DcTracker.java revision 092e6bd60f1a4a3a55fb73ad0efca1122b8e15e2
1c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville/*
2c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * Copyright (C) 2006 The Android Open Source Project
3c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville *
4c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * Licensed under the Apache License, Version 2.0 (the "License");
5c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * you may not use this file except in compliance with the License.
6c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * You may obtain a copy of the License at
7c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville *
8c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville *      http://www.apache.org/licenses/LICENSE-2.0
9c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville *
10c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * Unless required by applicable law or agreed to in writing, software
11c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * distributed under the License is distributed on an "AS IS" BASIS,
12c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * See the License for the specific language governing permissions and
14c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * limitations under the License.
15c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville */
16c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
174918296afe1c667e9523cdfc799f558f7ebc2bfbWink Savillepackage com.android.internal.telephony.dataconnection;
18c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
19cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kallaimport android.app.AlarmManager;
20c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.app.PendingIntent;
212b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensenimport android.app.ProgressDialog;
22c9b81a0c05128694c617fcdd67e73821895822feWink Savilleimport android.content.ActivityNotFoundException;
23b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensenimport android.content.BroadcastReceiver;
24c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.content.ContentResolver;
25cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.content.ContentValues;
26c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.content.Context;
27c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.content.Intent;
28c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.content.IntentFilter;
291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport android.content.SharedPreferences;
30cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.content.res.Resources;
31c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.database.ContentObserver;
32cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.database.Cursor;
33cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.net.ConnectivityManager;
34c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.net.LinkProperties;
3596cce86cf08e37e0f09ed5057b1196e26b302743Robert Greenwaltimport android.net.NetworkCapabilities;
36cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.net.NetworkConfig;
371a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport android.net.NetworkInfo;
38af5593594070f825032be46dced573cd195956e1Robert Greenwaltimport android.net.NetworkRequest;
39cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.net.NetworkUtils;
409c180aedfc9f0d20525c0128487d3500e6c0a715Jason Monkimport android.net.ProxyInfo;
411a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport android.net.TrafficStats;
42cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.net.Uri;
431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport android.net.wifi.WifiManager;
44c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.os.AsyncResult;
453fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwaltimport android.os.Build;
46b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensenimport android.os.Bundle;
47a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport android.os.Handler;
481a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport android.os.HandlerThread;
49af5593594070f825032be46dced573cd195956e1Robert Greenwaltimport android.os.Looper;
50c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.os.Message;
51a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport android.os.RegistrantList;
52b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensenimport android.os.ServiceManager;
53c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.os.SystemClock;
54c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.os.SystemProperties;
551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport android.preference.PreferenceManager;
56c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.provider.Settings;
571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport android.provider.Settings.SettingNotFoundException;
58cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.provider.Telephony;
59cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.telephony.CellLocation;
600e776303ca82b5bec5db19bb44e0f13b0c7c6400Etan Cohenimport android.telephony.ServiceState;
61c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.telephony.TelephonyManager;
62a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport android.telephony.SubscriptionManager;
631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport android.telephony.SubscriptionManager.OnSubscriptionsChangedListener;
64cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.telephony.cdma.CdmaCellLocation;
65cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.telephony.gsm.GsmCellLocation;
66c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.text.TextUtils;
67cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kallaimport android.util.EventLog;
682dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwaltimport android.util.LocalLog;
69ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwaltimport android.util.Pair;
70af5593594070f825032be46dced573cd195956e1Robert Greenwaltimport android.util.SparseArray;
712b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensenimport android.view.WindowManager;
7299c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Savilleimport android.telephony.Rlog;
73c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport com.android.internal.R;
75af5593594070f825032be46dced573cd195956e1Robert Greenwaltimport com.android.internal.annotations.VisibleForTesting;
761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport com.android.internal.telephony.GsmCdmaPhone;
774918296afe1c667e9523cdfc799f558f7ebc2bfbWink Savilleimport com.android.internal.telephony.Phone;
78cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport com.android.internal.telephony.DctConstants;
79cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport com.android.internal.telephony.EventLogTags;
80b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensenimport com.android.internal.telephony.ITelephony;
814918296afe1c667e9523cdfc799f558f7ebc2bfbWink Savilleimport com.android.internal.telephony.PhoneConstants;
82cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport com.android.internal.telephony.RILConstants;
83d720945f2be5ea5fe0faf67e67d9ea0e184eba67Alex Yakavenkaimport com.android.internal.telephony.uicc.IccRecords;
84bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenkaimport com.android.internal.telephony.uicc.UiccController;
85c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport com.android.internal.util.AsyncChannel;
8676f43316a5a6082d601bffd4b6898d0bd81e11fcramimport com.android.internal.util.ArrayUtils;
87c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
88c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport java.io.FileDescriptor;
89c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport java.io.PrintWriter;
90c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport java.util.ArrayList;
9129c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwaltimport java.util.Arrays;
921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport java.util.Comparator;
931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport java.util.HashMap;
941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport java.util.List;
951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport java.util.Map.Entry;
9629c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwaltimport java.util.Objects;
971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport java.util.PriorityQueue;
981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport java.util.Set;
991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport java.util.concurrent.ConcurrentHashMap;
1001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport java.util.concurrent.atomic.AtomicBoolean;
1011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport java.util.concurrent.atomic.AtomicInteger;
1021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport java.util.concurrent.atomic.AtomicReference;
103d86df358b8fe07160caa12147b6e4ad34d378ce6xinheimport java.lang.StringBuilder;
104c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
105a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport com.android.internal.telephony.ServiceStateTracker;
106c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville/**
107c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * {@hide}
108c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville */
1090c3ec24396bb8c21b4d89f743b626c13dd35ba7bAmit Mahajanpublic class DcTracker extends Handler {
1101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final String LOG_TAG = "DCT";
1111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final boolean DBG = true;
1121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final boolean VDBG = false; // STOPSHIP if true
1131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final boolean VDBG_STALL = false; // STOPSHIP if true
1141a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final boolean RADIO_TESTS = false;
1151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1160e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu    public AtomicBoolean isCleanupRequired = new AtomicBoolean(false);
1171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private final AlarmManager mAlarmManager;
1191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1201a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private Object mDataEnabledLock = new Object();
1211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // responds to the setInternalDataEnabled call - used internally to turn off data
1231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // for example during emergency calls
1241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean mInternalDataEnabled = true;
1251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // responds to public (user) API to enable/disable data use
1271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // independent of mInternalDataEnabled and requests for APN access
1281a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // persisted
1291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean mUserDataEnabled = true;
1301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1311a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // TODO: move away from static state once 5587429 is fixed.
1321a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static boolean sPolicyDataEnabled = true;
1331a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1341a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /* Currently requested APN type (TODO: This should probably be a parameter not a member) */
1351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private String mRequestedApnType = PhoneConstants.APN_TYPE_DEFAULT;
1361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1371a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /**
1381a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * After detecting a potential connection problem, this is the max number
1391a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * of subsequent polls before attempting recovery.
1401a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     */
1411a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // 1 sec. default polling interval when screen is on.
1421a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final int POLL_NETSTAT_MILLIS = 1000;
1431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // 10 min. default polling interval when screen is off.
1441a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final int POLL_NETSTAT_SCREEN_OFF_MILLIS = 1000*60*10;
1451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // Default sent packets without ack which triggers initial recovery steps
1461a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final int NUMBER_SENT_PACKETS_OF_HANG = 10;
1471a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1481a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // Default for the data stall alarm while non-aggressive stall detection
1491a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final int DATA_STALL_ALARM_NON_AGGRESSIVE_DELAY_IN_MS_DEFAULT = 1000 * 60 * 6;
1501a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // Default for the data stall alarm for aggressive stall detection
1511a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final int DATA_STALL_ALARM_AGGRESSIVE_DELAY_IN_MS_DEFAULT = 1000 * 60;
1521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // Tag for tracking stale alarms
1531a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final String DATA_STALL_ALARM_TAG_EXTRA = "data.stall.alram.tag";
1541a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final boolean DATA_STALL_SUSPECTED = true;
1561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final boolean DATA_STALL_NOT_SUSPECTED = false;
1571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private String RADIO_RESET_PROPERTY = "gsm.radioreset";
1591a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final String INTENT_RECONNECT_ALARM =
1611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            "com.android.internal.telephony.data-reconnect";
1621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final String INTENT_RECONNECT_ALARM_EXTRA_TYPE = "reconnect_alarm_extra_type";
1631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final String INTENT_RECONNECT_ALARM_EXTRA_REASON =
1641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            "reconnect_alarm_extra_reason";
1651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1661a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final String INTENT_DATA_STALL_ALARM =
1671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            "com.android.internal.telephony.data-stall";
1681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1691a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private DcTesterFailBringUpAll mDcTesterFailBringUpAll;
1701a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private DcController mDcc;
1711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /** kept in sync with mApnContexts
1731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * Higher numbers are higher priority and sorted so highest priority is first */
1741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private final PriorityQueue<ApnContext>mPrioritySortedApnContexts =
1751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            new PriorityQueue<ApnContext>(5,
1761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            new Comparator<ApnContext>() {
1771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                public int compare(ApnContext c1, ApnContext c2) {
1781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    return c2.priority - c1.priority;
1791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
1801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } );
1811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /** allApns holds all apns */
1831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private ArrayList<ApnSetting> mAllApnSettings = null;
1841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /** preferred apn */
1861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private ApnSetting mPreferredApn = null;
1871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /** Is packet service restricted by network */
1891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean mIsPsRestricted = false;
1901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /** emergency apn Setting*/
1921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private ApnSetting mEmergencyApn = null;
1931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /* Once disposed dont handle any messages */
1951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean mIsDisposed = false;
1961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private ContentResolver mResolver;
1981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /* Set to true with CMD_ENABLE_MOBILE_PROVISIONING */
2001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean mIsProvisioning = false;
2011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /* The Url passed as object parameter in CMD_ENABLE_MOBILE_PROVISIONING */
2031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private String mProvisioningUrl = null;
2041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /* Intent for the provisioning apn alarm */
2061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final String INTENT_PROVISIONING_APN_ALARM =
2071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            "com.android.internal.telephony.provisioning_apn_alarm";
2081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /* Tag for tracking stale alarms */
2101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final String PROVISIONING_APN_ALARM_TAG_EXTRA = "provisioning.apn.alarm.tag";
2111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /* Debug property for overriding the PROVISIONING_APN_ALARM_DELAY_IN_MS */
2131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final String DEBUG_PROV_APN_ALARM = "persist.debug.prov_apn_alarm";
2141a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /* Default for the provisioning apn alarm timeout */
2161a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final int PROVISIONING_APN_ALARM_DELAY_IN_MS_DEFAULT = 1000 * 60 * 15;
2171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /* The provision apn alarm intent used to disable the provisioning apn */
2191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private PendingIntent mProvisioningApnAlarmIntent = null;
2201a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /* Used to track stale provisioning apn alarms */
2221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private int mProvisioningApnAlarmTag = (int) SystemClock.elapsedRealtime();
2231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private AsyncChannel mReplyAc = new AsyncChannel();
2251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver () {
2271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        @Override
2281a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public void onReceive(Context context, Intent intent) {
2291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            String action = intent.getAction();
230c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu
2311a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (action.equals(Intent.ACTION_SCREEN_ON)) {
232c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu                if (DBG) log("screen on");
2331a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mIsScreenOn = true;
2341a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                stopNetStatPoll();
2351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                startNetStatPoll();
2361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                restartDataStallAlarm();
2371a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else if (action.equals(Intent.ACTION_SCREEN_OFF)) {
238c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu                if (DBG) log("screen off");
2391a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mIsScreenOn = false;
2401a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                stopNetStatPoll();
2411a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                startNetStatPoll();
2421a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                restartDataStallAlarm();
2431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else if (action.startsWith(INTENT_RECONNECT_ALARM)) {
2441a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) log("Reconnect alarm. Previous state was " + mState);
2451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onActionIntentReconnectAlarm(intent);
2461a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else if (action.equals(INTENT_DATA_STALL_ALARM)) {
247c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu                if (DBG) log("Data stall alarm");
2481a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onActionIntentDataStallAlarm(intent);
2491a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else if (action.equals(INTENT_PROVISIONING_APN_ALARM)) {
250c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu                if (DBG) log("Provisioning apn alarm");
2511a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onActionIntentProvisioningApnAlarm(intent);
2521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
2531a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                final android.net.NetworkInfo networkInfo = (NetworkInfo)
2541a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
2551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mIsWifiConnected = (networkInfo != null && networkInfo.isConnected());
2561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) log("NETWORK_STATE_CHANGED_ACTION: mIsWifiConnected=" + mIsWifiConnected);
2571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) {
258c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu                if (DBG) log("Wifi state changed");
2591a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                final boolean enabled = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,
2601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        WifiManager.WIFI_STATE_UNKNOWN) == WifiManager.WIFI_STATE_ENABLED;
2611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (!enabled) {
2621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    // when WiFi got disabled, the NETWORK_STATE_CHANGED_ACTION
2631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    // quit and won't report disconnected until next enabling.
2641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    mIsWifiConnected = false;
2651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
2661a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) {
2671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    log("WIFI_STATE_CHANGED_ACTION: enabled=" + enabled
2681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            + " mIsWifiConnected=" + mIsWifiConnected);
2691a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
270c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu            } else {
271c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu                if (DBG) log("onReceive: Unknown action=" + action);
2721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
2731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
2741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    };
2751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private final Runnable mPollNetStat = new Runnable() {
2771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        @Override
2781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public void run() {
2791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            updateDataActivity();
2801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (mIsScreenOn) {
2821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mNetStatPollPeriod = Settings.Global.getInt(mResolver,
2831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        Settings.Global.PDP_WATCHDOG_POLL_INTERVAL_MS, POLL_NETSTAT_MILLIS);
2841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else {
2851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mNetStatPollPeriod = Settings.Global.getInt(mResolver,
2861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        Settings.Global.PDP_WATCHDOG_LONG_POLL_INTERVAL_MS,
2871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        POLL_NETSTAT_SCREEN_OFF_MILLIS);
2881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
2891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (mNetStatPollEnabled) {
2911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mDataConnectionTracker.postDelayed(this, mNetStatPollPeriod);
2921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
2931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
2941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    };
2951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private SubscriptionManager mSubscriptionManager;
2971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private final OnSubscriptionsChangedListener mOnSubscriptionsChangedListener =
2981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            new OnSubscriptionsChangedListener() {
2991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                public final AtomicInteger mPreviousSubId =
3001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        new AtomicInteger(SubscriptionManager.INVALID_SUBSCRIPTION_ID);
3011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                /**
3031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                 * Callback invoked when there is any change to any SubscriptionInfo. Typically
3041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                 * this method invokes {@link SubscriptionManager#getActiveSubscriptionInfoList}
3051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                 */
3061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                @Override
3071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                public void onSubscriptionsChanged() {
3081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (DBG) log("SubscriptionListener.onSubscriptionInfoChanged");
3091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    // Set the network type, in case the radio does not restore it.
3101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    int subId = mPhone.getSubId();
3111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (SubscriptionManager.isValidSubscriptionId(subId)) {
3121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        if (mDataRoamingSettingObserver != null) {
3131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            mDataRoamingSettingObserver.unregister();
3141a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        }
3151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        // Watch for changes to Settings.Global.DATA_ROAMING
3161a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        mDataRoamingSettingObserver = new DataRoamingSettingObserver(mPhone,
3171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                                mPhone.getContext());
3181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        mDataRoamingSettingObserver.register();
3191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3201a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
3211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (mPreviousSubId.getAndSet(subId) != subId &&
3221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            SubscriptionManager.isValidSubscriptionId(subId)) {
3231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        onRecordsLoadedOrSubIdChanged();
3241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
3251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
3261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            };
3271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3281a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private class DataRoamingSettingObserver extends ContentObserver {
3291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public DataRoamingSettingObserver(Handler handler, Context context) {
3311a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            super(handler);
3321a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
3331a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3341a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public void register() {
3351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            String contentUri;
3361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (TelephonyManager.getDefault().getSimCount() == 1) {
3371a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                contentUri = Settings.Global.DATA_ROAMING;
3381a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else {
3391a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                contentUri = Settings.Global.DATA_ROAMING + mPhone.getSubId();
3401a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
3411a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3421a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mResolver.registerContentObserver(Settings.Global.getUriFor(contentUri), false, this);
3431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
3441a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public void unregister() {
3461a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mResolver.unregisterContentObserver(this);
3471a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
3481a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3491a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        @Override
3501a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public void onChange(boolean selfChange) {
3511a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            // already running on mPhone handler thread
3521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (mPhone.getServiceState().getDataRoaming()) {
3531a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                sendMessage(obtainMessage(DctConstants.EVENT_ROAMING_ON));
3541a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
3551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
3561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
3571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private DataRoamingSettingObserver mDataRoamingSettingObserver;
3581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3591a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /**
3601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * Maintain the sum of transmit and receive packets.
3611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     *
3621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * The packet counts are initialized and reset to -1 and
3631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * remain -1 until they can be updated.
3641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     */
3651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    public static class TxRxSum {
3661a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public long txPkts;
3671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public long rxPkts;
3681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3691a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public TxRxSum() {
3701a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            reset();
3711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
3721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public TxRxSum(long txPkts, long rxPkts) {
3741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            this.txPkts = txPkts;
3751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            this.rxPkts = rxPkts;
3761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
3771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public TxRxSum(TxRxSum sum) {
3791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            txPkts = sum.txPkts;
3801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            rxPkts = sum.rxPkts;
3811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
3821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public void reset() {
3841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            txPkts = -1;
3851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            rxPkts = -1;
3861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
3871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        @Override
3891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public String toString() {
3901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            return "{txSum=" + txPkts + " rxSum=" + rxPkts + "}";
3911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
3921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public void updateTxRxSum() {
3941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            this.txPkts = TrafficStats.getMobileTcpTxPackets();
3951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            this.rxPkts = TrafficStats.getMobileTcpRxPackets();
3961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
3971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
3981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onActionIntentReconnectAlarm(Intent intent) {
4001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        String reason = intent.getStringExtra(INTENT_RECONNECT_ALARM_EXTRA_REASON);
4011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        String apnType = intent.getStringExtra(INTENT_RECONNECT_ALARM_EXTRA_TYPE);
4021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        int phoneSubId = mPhone.getSubId();
4041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        int currSubId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY,
4051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                SubscriptionManager.INVALID_SUBSCRIPTION_ID);
4061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        log("onActionIntentReconnectAlarm: currSubId = " + currSubId + " phoneSubId=" + phoneSubId);
4071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        // Stop reconnect if not current subId is not correct.
4091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        // FIXME STOPSHIP - phoneSubId is coming up as -1 way after boot and failing this?
4101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (!SubscriptionManager.isValidSubscriptionId(currSubId) || (currSubId != phoneSubId)) {
4111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            log("receive ReconnectAlarm but subId incorrect, ignore");
4121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            return;
4131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
4141a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        ApnContext apnContext = mApnContexts.get(apnType);
4161a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (DBG) {
4181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            log("onActionIntentReconnectAlarm: mState=" + mState + " reason=" + reason +
4191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    " apnType=" + apnType + " apnContext=" + apnContext +
4201a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    " mDataConnectionAsyncChannels=" + mDataConnectionAcHashMap);
4211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
4221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if ((apnContext != null) && (apnContext.isEnabled())) {
4241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            apnContext.setReason(reason);
4251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            DctConstants.State apnContextState = apnContext.getState();
4261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) {
4271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                log("onActionIntentReconnectAlarm: apnContext state=" + apnContextState);
4281a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
4291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if ((apnContextState == DctConstants.State.FAILED)
4301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    || (apnContextState == DctConstants.State.IDLE)) {
4311a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) {
4321a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    log("onActionIntentReconnectAlarm: state is FAILED|IDLE, disassociate");
4331a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
4341a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                DcAsyncChannel dcac = apnContext.getDcAc();
4351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (dcac != null) {
4361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (DBG) {
4371a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        log("onActionIntentReconnectAlarm: tearDown apnContext=" + apnContext);
4381a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
4391a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    dcac.tearDown(apnContext, "", null);
4401a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
4411a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                apnContext.setDataConnectionAc(null);
4421a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                apnContext.setState(DctConstants.State.IDLE);
4431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else {
4441a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) log("onActionIntentReconnectAlarm: keep associated");
4451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
4461a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            // TODO: IF already associated should we send the EVENT_TRY_SETUP_DATA???
4471a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            sendMessage(obtainMessage(DctConstants.EVENT_TRY_SETUP_DATA, apnContext));
4481a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4491a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            apnContext.setReconnectIntent(null);
4501a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
4511a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
4521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4531a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onActionIntentDataStallAlarm(Intent intent) {
4541a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (VDBG_STALL) log("onActionIntentDataStallAlarm: action=" + intent.getAction());
4551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        Message msg = obtainMessage(DctConstants.EVENT_DATA_STALL_ALARM,
4561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                intent.getAction());
4571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        msg.arg1 = intent.getIntExtra(DATA_STALL_ALARM_TAG_EXTRA, 0);
4581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        sendMessage(msg);
4591a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
4601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private final ConnectivityManager mCm;
462c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
463b3a03455be44a2a0ffbeb757b193d860c1878599Naveen Kalla    /**
464a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville     * List of messages that are waiting to be posted, when data call disconnect
465a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville     * is complete
466a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville     */
467a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private ArrayList<Message> mDisconnectAllCompleteMsgList = new ArrayList<Message>();
468a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
469a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private RegistrantList mAllDataDisconnectedRegistrants = new RegistrantList();
470a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // member variables
4721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private final Phone mPhone;
4731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private final UiccController mUiccController;
4741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private final AtomicReference<IccRecords> mIccRecords = new AtomicReference<IccRecords>();
4751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private DctConstants.Activity mActivity = DctConstants.Activity.NONE;
4761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private DctConstants.State mState = DctConstants.State.IDLE;
4771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private final Handler mDataConnectionTracker;
4781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private long mTxPkts;
4801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private long mRxPkts;
4811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private int mNetStatPollPeriod;
4821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean mNetStatPollEnabled = false;
4831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private TxRxSum mDataStallTxRxSum = new TxRxSum(0, 0);
4851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // Used to track stale data stall alarms.
4861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private int mDataStallAlarmTag = (int) SystemClock.elapsedRealtime();
4871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // The current data stall alarm intent
4881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private PendingIntent mDataStallAlarmIntent = null;
4891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // Number of packets sent since the last received packet
4901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private long mSentSinceLastRecv;
4911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // Controls when a simple recovery attempt it to be tried
4921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private int mNoRecvPollCount = 0;
4930e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu    // Reference counter for enabling fail fast
4941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static int sEnableFailFastRefCounter = 0;
4951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // True if data stall detection is enabled
4961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private volatile boolean mDataStallDetectionEnabled = true;
4971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private volatile boolean mFailFast = false;
4991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
5001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // True when in voice call
5011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean mInVoiceCall = false;
5021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
5031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // wifi connection status will be updated by sticky intent
5041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean mIsWifiConnected = false;
5051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
5061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /** Intent sent when the reconnect alarm fires. */
5071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private PendingIntent mReconnectIntent = null;
5081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
5091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // When false we will not auto attach and manually attaching is required.
5101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean mAutoAttachOnCreationConfig = false;
5111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private AtomicBoolean mAutoAttachOnCreation = new AtomicBoolean(false);
5121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
5131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // State of screen
5141a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // (TODO: Reconsider tying directly to screen, maybe this is
5151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    //        really a lower power mode")
5161a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean mIsScreenOn = true;
5171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
5181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // Indicates if we found mvno-specific APNs in the full APN list.
5191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // used to determine if we can accept mno-specific APN for tethering.
5201a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean mMvnoMatched = false;
5211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
5221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /** Allows the generation of unique Id's for DataConnection objects */
5231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private AtomicInteger mUniqueIdGenerator = new AtomicInteger(0);
5241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
5251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /** The data connections. */
5261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private HashMap<Integer, DataConnection> mDataConnections =
5271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            new HashMap<Integer, DataConnection>();
5281a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
5291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /** The data connection async channels */
5301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private HashMap<Integer, DcAsyncChannel> mDataConnectionAcHashMap =
5311a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            new HashMap<Integer, DcAsyncChannel>();
5321a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
5331a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /** Convert an ApnType string to Id (TODO: Use "enumeration" instead of String for ApnType) */
5341a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private HashMap<String, Integer> mApnToDataConnectionId = new HashMap<String, Integer>();
5351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
5361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /** Phone.APN_TYPE_* ===> ApnContext */
5371a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private final ConcurrentHashMap<String, ApnContext> mApnContexts =
5381a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            new ConcurrentHashMap<String, ApnContext>();
5391a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
540af5593594070f825032be46dced573cd195956e1Robert Greenwalt    private final SparseArray<ApnContext> mApnContextsById = new SparseArray<ApnContext>();
541af5593594070f825032be46dced573cd195956e1Robert Greenwalt
5421a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private int mDisconnectPendingCount = 0;
543a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
544a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    /**
545cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Handles changes to the APN db.
546b3a03455be44a2a0ffbeb757b193d860c1878599Naveen Kalla     */
547cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private class ApnChangeObserver extends ContentObserver {
548cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        public ApnChangeObserver () {
549cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            super(mDataConnectionTracker);
550cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
551c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
552cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        @Override
553cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        public void onChange(boolean selfChange) {
554cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            sendMessage(obtainMessage(DctConstants.EVENT_APN_CHANGED));
555cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
556cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
557c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
558cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    //***** Instance Variables
559c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
560cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private boolean mReregisterOnReconnectFailure = false;
561c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
562c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
563cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    //***** Constants
564c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
565ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    // Used by puppetmaster/*/radio_stress.py
566ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    private static final String PUPPET_MASTER_RADIO_STRESS_TEST = "gsm.defaultpdpcontext.active";
567c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
568ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    private static final int POLL_PDP_MILLIS = 5 * 1000;
569c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
5702b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen    private static final int PROVISIONING_SPINNER_TIMEOUT_MILLIS = 120 * 1000;
5712b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen
5726bc4098827f3070a44b5e51508b455d7c7be9c07Wink Saville    static final Uri PREFERAPN_NO_UPDATE_URI_USING_SUBID =
5736bc4098827f3070a44b5e51508b455d7c7be9c07Wink Saville                        Uri.parse("content://telephony/carriers/preferapn_no_update/subId/");
574cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    static final String APN_ID = "apn_id";
575cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
576ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    private boolean mCanSetPreferApn = false;
577c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
578187a39f896f88eb6c5e4306d9595546654825976Wink Saville    private AtomicBoolean mAttached = new AtomicBoolean(false);
579187a39f896f88eb6c5e4306d9595546654825976Wink Saville
580cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /** Watches for changes to the APN db. */
581cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private ApnChangeObserver mApnObserver;
582cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
583b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen    private final String mProvisionActionName;
584b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen    private BroadcastReceiver mProvisionBroadcastReceiver;
5852b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen    private ProgressDialog mProvisioningSpinner;
586b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen
587a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public boolean mImsRegistrationState = false;
588a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
589cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    //***** Constructor
5901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    public DcTracker(Phone phone) {
5911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        super();
5921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone = phone;
5931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
5941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (DBG) log("DCT.constructor");
5951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
5961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mResolver = mPhone.getContext().getContentResolver();
5971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mUiccController = UiccController.getInstance();
5981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mUiccController.registerForIccChanged(this, DctConstants.EVENT_ICC_CHANGED, null);
5991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mAlarmManager =
6001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                (AlarmManager) mPhone.getContext().getSystemService(Context.ALARM_SERVICE);
6011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mCm = (ConnectivityManager) mPhone.getContext().getSystemService(
6021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                Context.CONNECTIVITY_SERVICE);
6031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
6041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
6051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        IntentFilter filter = new IntentFilter();
6061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        filter.addAction(Intent.ACTION_SCREEN_ON);
6071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        filter.addAction(Intent.ACTION_SCREEN_OFF);
6081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
6091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
6101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        filter.addAction(INTENT_DATA_STALL_ALARM);
6111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        filter.addAction(INTENT_PROVISIONING_APN_ALARM);
6121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
6131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        // TODO - redundent with update call below?
6141a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mUserDataEnabled = getDataEnabled();
6151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
6161a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getContext().registerReceiver(mIntentReceiver, filter, null, mPhone);
6171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
6181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mPhone.getContext());
6191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mAutoAttachOnCreation.set(sp.getBoolean(Phone.DATA_DISABLED_ON_BOOT_KEY, false));
6201a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
6211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mSubscriptionManager = SubscriptionManager.from(mPhone.getContext());
6221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mSubscriptionManager.addOnSubscriptionsChangedListener(mOnSubscriptionsChangedListener);
6231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
6241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        HandlerThread dcHandlerThread = new HandlerThread("DcHandlerThread");
6251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        dcHandlerThread.start();
6261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        Handler dcHandler = new Handler(dcHandlerThread.getLooper());
6271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mDcc = DcController.makeDcc(mPhone, this, dcHandler);
6281a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mDcTesterFailBringUpAll = new DcTesterFailBringUpAll(mPhone, dcHandler);
629cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
630cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mDataConnectionTracker = this;
631a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        update();
632cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mApnObserver = new ApnChangeObserver();
6331a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        phone.getContext().getContentResolver().registerContentObserver(
634cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                Telephony.Carriers.CONTENT_URI, true, mApnObserver);
635cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
636d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt        initApnContexts();
637d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt
638d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt        for (ApnContext apnContext : mApnContexts.values()) {
639d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            // Register the reconnect and restart actions.
6401a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            filter = new IntentFilter();
641d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            filter.addAction(INTENT_RECONNECT_ALARM + '.' + apnContext.getApnType());
642d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            mPhone.getContext().registerReceiver(mIntentReceiver, filter, null, mPhone);
643d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt        }
644d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt
64576f43316a5a6082d601bffd4b6898d0bd81e11fcram        // Add Emergency APN to APN setting list by default to support EPDN in sim absent cases
64676f43316a5a6082d601bffd4b6898d0bd81e11fcram        initEmergencyApnSetting();
64776f43316a5a6082d601bffd4b6898d0bd81e11fcram        addEmergencyApnSetting();
648b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen
6491a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mProvisionActionName = "com.android.internal.telephony.PROVISION" + phone.getPhoneId();
6501a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
6511a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
652af5593594070f825032be46dced573cd195956e1Robert Greenwalt    @VisibleForTesting
653af5593594070f825032be46dced573cd195956e1Robert Greenwalt    public DcTracker() {
654af5593594070f825032be46dced573cd195956e1Robert Greenwalt        mAlarmManager = null;
655af5593594070f825032be46dced573cd195956e1Robert Greenwalt        mCm = null;
656af5593594070f825032be46dced573cd195956e1Robert Greenwalt        mPhone = null;
657af5593594070f825032be46dced573cd195956e1Robert Greenwalt        mUiccController = null;
658af5593594070f825032be46dced573cd195956e1Robert Greenwalt        mDataConnectionTracker = null;
659af5593594070f825032be46dced573cd195956e1Robert Greenwalt        mProvisionActionName = null;
660af5593594070f825032be46dced573cd195956e1Robert Greenwalt    }
661af5593594070f825032be46dced573cd195956e1Robert Greenwalt
6621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    public void registerServiceStateTrackerEvents() {
6631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getServiceStateTracker().registerForDataConnectionAttached(this,
6641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                DctConstants.EVENT_DATA_CONNECTION_ATTACHED, null);
6651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getServiceStateTracker().registerForDataConnectionDetached(this,
6661a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                DctConstants.EVENT_DATA_CONNECTION_DETACHED, null);
6671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getServiceStateTracker().registerForDataRoamingOn(this,
6681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                DctConstants.EVENT_ROAMING_ON, null);
6691a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getServiceStateTracker().registerForDataRoamingOff(this,
6701a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                DctConstants.EVENT_ROAMING_OFF, null);
6711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getServiceStateTracker().registerForPsRestrictedEnabled(this,
6721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                DctConstants.EVENT_PS_RESTRICT_ENABLED, null);
6731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getServiceStateTracker().registerForPsRestrictedDisabled(this,
6741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                DctConstants.EVENT_PS_RESTRICT_DISABLED, null);
6751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getServiceStateTracker().registerForDataRegStateOrRatChanged(this,
6761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                DctConstants.EVENT_DATA_RAT_CHANGED, null);
677cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
678c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
6791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    public void unregisterServiceStateTrackerEvents() {
6801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getServiceStateTracker().unregisterForDataConnectionAttached(this);
6811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getServiceStateTracker().unregisterForDataConnectionDetached(this);
6821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getServiceStateTracker().unregisterForDataRoamingOn(this);
6831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getServiceStateTracker().unregisterForDataRoamingOff(this);
6841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getServiceStateTracker().unregisterForPsRestrictedEnabled(this);
6851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getServiceStateTracker().unregisterForPsRestrictedDisabled(this);
6861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getServiceStateTracker().unregisterForDataRegStateOrRatChanged(this);
6871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
6881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
6891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void registerForAllEvents() {
690a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mPhone.mCi.registerForAvailable(this, DctConstants.EVENT_RADIO_AVAILABLE, null);
691a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mPhone.mCi.registerForOffOrNotAvailable(this,
6929c32a1e9495f06905377c9e2b91c0ef9cdb0528fJack Yu                DctConstants.EVENT_RADIO_OFF_OR_NOT_AVAILABLE, null);
693a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mPhone.mCi.registerForDataNetworkStateChanged(this,
6949c32a1e9495f06905377c9e2b91c0ef9cdb0528fJack Yu                DctConstants.EVENT_DATA_STATE_CHANGED, null);
6950710ff7ae80f217782f08528c5406f6d26a29f75Robert Greenwalt        // Note, this is fragile - the Phone is now presenting a merged picture
6960710ff7ae80f217782f08528c5406f6d26a29f75Robert Greenwalt        // of PS (volte) & CS and by diving into its internals you're just seeing
6970710ff7ae80f217782f08528c5406f6d26a29f75Robert Greenwalt        // the CS data.  This works well for the purposes this is currently used for
6980710ff7ae80f217782f08528c5406f6d26a29f75Robert Greenwalt        // but that may not always be the case.  Should probably be redesigned to
6990710ff7ae80f217782f08528c5406f6d26a29f75Robert Greenwalt        // accurately reflect what we're really interested in (registerForCSVoiceCallEnded).
7001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getCallTracker().registerForVoiceCallEnded(this,
7011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                DctConstants.EVENT_VOICE_CALL_ENDED, null);
7021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getCallTracker().registerForVoiceCallStarted(this,
7031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                DctConstants.EVENT_VOICE_CALL_STARTED, null);
7041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        registerServiceStateTrackerEvents();
705a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville     //   SubscriptionManager.registerForDdsSwitch(this,
706a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville     //          DctConstants.EVENT_CLEAN_UP_ALL_CONNECTIONS, null);
707a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
7081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
709cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public void dispose() {
7101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (DBG) log("DCT.dispose");
7114dfda5470a2582c0fb543ead6c79ccf598c580e0Robert Greenwalt
712b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        if (mProvisionBroadcastReceiver != null) {
713b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            mPhone.getContext().unregisterReceiver(mProvisionBroadcastReceiver);
714b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            mProvisionBroadcastReceiver = null;
715b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        }
7162b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen        if (mProvisioningSpinner != null) {
7172b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            mProvisioningSpinner.dismiss();
7182b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            mProvisioningSpinner = null;
7192b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen        }
720b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen
721cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        cleanUpAllConnections(true, null);
722cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
7231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        for (DcAsyncChannel dcac : mDataConnectionAcHashMap.values()) {
7241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            dcac.disconnect();
7251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
7261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mDataConnectionAcHashMap.clear();
7271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mIsDisposed = true;
7281a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.getContext().unregisterReceiver(mIntentReceiver);
7291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mUiccController.unregisterForIccChanged(this);
7301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (mDataRoamingSettingObserver != null) {
7311a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mDataRoamingSettingObserver.unregister();
7321a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
7331a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mSubscriptionManager
7341a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                .removeOnSubscriptionsChangedListener(mOnSubscriptionsChangedListener);
7351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mDcc.dispose();
7361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mDcTesterFailBringUpAll.dispose();
737cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
738a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mPhone.getContext().getContentResolver().unregisterContentObserver(mApnObserver);
739a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mApnContexts.clear();
740af5593594070f825032be46dced573cd195956e1Robert Greenwalt        mApnContextsById.clear();
741a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mPrioritySortedApnContexts.clear();
742a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
743a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        destroyDataConnections();
744a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
7451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
7461a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void unregisterForAllEvents() {
747a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville         //Unregister for all events
74822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mPhone.mCi.unregisterForAvailable(this);
74922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mPhone.mCi.unregisterForOffOrNotAvailable(this);
750cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        IccRecords r = mIccRecords.get();
751a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (r != null) {
752a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            r.unregisterForRecordsLoaded(this);
753a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mIccRecords.set(null);
754a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
75522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mPhone.mCi.unregisterForDataNetworkStateChanged(this);
756cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mPhone.getCallTracker().unregisterForVoiceCallEnded(this);
757cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mPhone.getCallTracker().unregisterForVoiceCallStarted(this);
7581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        unregisterServiceStateTrackerEvents();
759a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        //SubscriptionManager.unregisterForDdsSwitch(this);
760cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
761cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
7621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /**
7631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * Called when EVENT_RESET_DONE is received so goto
7641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * IDLE state and send notifications to those interested.
7651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     *
7661a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * TODO - currently unused.  Needs to be hooked into DataConnection cleanup
7671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * TODO - needs to pass some notion of which connection is reset..
7681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     */
7691a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onResetDone(AsyncResult ar) {
7701a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (DBG) log("EVENT_RESET_DONE");
7711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        String reason = null;
7721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (ar.userObj instanceof String) {
7731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            reason = (String) ar.userObj;
7741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
7751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        gotoIdleAndNotifyDataConnection(reason);
7761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
7771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
7781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /**
7791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * Modify {@link android.provider.Settings.Global#MOBILE_DATA} value.
7801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     */
7811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    public void setDataEnabled(boolean enable) {
7821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        Message msg = obtainMessage(DctConstants.CMD_SET_USER_DATA_ENABLE);
7831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        msg.arg1 = enable ? 1 : 0;
7841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (DBG) log("setDataEnabled: sendMessage: enable=" + enable);
7851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        sendMessage(msg);
7861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
7871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
7881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onSetUserDataEnabled(boolean enabled) {
7891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        synchronized (mDataEnabledLock) {
7901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (mUserDataEnabled != enabled) {
7911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mUserDataEnabled = enabled;
7921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
7931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                // For single SIM phones, this is a per phone property.
7941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (TelephonyManager.getDefault().getSimCount() == 1) {
7951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    Settings.Global.putInt(mResolver, Settings.Global.MOBILE_DATA, enabled ? 1 : 0);
7961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                } else {
7971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    int phoneSubId = mPhone.getSubId();
7981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    Settings.Global.putInt(mResolver, Settings.Global.MOBILE_DATA + phoneSubId,
7991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            enabled ? 1 : 0);
8001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
8011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (getDataOnRoamingEnabled() == false &&
8021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        mPhone.getServiceState().getDataRoaming() == true) {
8031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (enabled) {
8041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        notifyOffApnsOfAvailability(Phone.REASON_ROAMING_ON);
8051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    } else {
8061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        notifyOffApnsOfAvailability(Phone.REASON_DATA_DISABLED);
8071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
8081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
8091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
8101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (enabled) {
8111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    onTrySetupData(Phone.REASON_DATA_ENABLED);
8121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                } else {
8131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    onCleanUpAllConnections(Phone.REASON_DATA_SPECIFIC_DISABLED);
8141a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
8151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
8161a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
8171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
8181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
8191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
8201a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
8211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    public long getSubId() {
8221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        return mPhone.getSubId();
8231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
8241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
8251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    public DctConstants.Activity getActivity() {
8261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        return mActivity;
8271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
8281a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
8291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void setActivity(DctConstants.Activity activity) {
8301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        log("setActivity = " + activity);
8311a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mActivity = activity;
8321a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.notifyDataActivity();
8331a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
8341a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
835af5593594070f825032be46dced573cd195956e1Robert Greenwalt    public void requestNetwork(NetworkRequest networkRequest, LocalLog log) {
836af5593594070f825032be46dced573cd195956e1Robert Greenwalt        final int apnId = ApnContext.apnIdForNetworkRequest(networkRequest);
837af5593594070f825032be46dced573cd195956e1Robert Greenwalt        final ApnContext apnContext = mApnContextsById.get(apnId);
838af5593594070f825032be46dced573cd195956e1Robert Greenwalt        log.log("DcTracker.requestNetwork for " + networkRequest + " found " + apnContext);
839af5593594070f825032be46dced573cd195956e1Robert Greenwalt        if (apnContext != null) apnContext.incRefCount(log);
840af5593594070f825032be46dced573cd195956e1Robert Greenwalt    }
841af5593594070f825032be46dced573cd195956e1Robert Greenwalt
842af5593594070f825032be46dced573cd195956e1Robert Greenwalt    public void releaseNetwork(NetworkRequest networkRequest, LocalLog log) {
843af5593594070f825032be46dced573cd195956e1Robert Greenwalt        final int apnId = ApnContext.apnIdForNetworkRequest(networkRequest);
844af5593594070f825032be46dced573cd195956e1Robert Greenwalt        final ApnContext apnContext = mApnContextsById.get(apnId);
845af5593594070f825032be46dced573cd195956e1Robert Greenwalt        log.log("DcTracker.releaseNetwork for " + networkRequest + " found " + apnContext);
846af5593594070f825032be46dced573cd195956e1Robert Greenwalt        if (apnContext != null) apnContext.decRefCount(log);
847af5593594070f825032be46dced573cd195956e1Robert Greenwalt    }
848af5593594070f825032be46dced573cd195956e1Robert Greenwalt
849bda761320929f714951c328bfec6a51a1978db97Wink Saville    public boolean isApnSupported(String name) {
85091bce2abae052df918cb546b9c5d205706ede026Shishir Agrawal        if (name == null) {
85191bce2abae052df918cb546b9c5d205706ede026Shishir Agrawal            loge("isApnSupported: name=null");
85291bce2abae052df918cb546b9c5d205706ede026Shishir Agrawal            return false;
85391bce2abae052df918cb546b9c5d205706ede026Shishir Agrawal        }
854bda761320929f714951c328bfec6a51a1978db97Wink Saville        ApnContext apnContext = mApnContexts.get(name);
855bda761320929f714951c328bfec6a51a1978db97Wink Saville        if (apnContext == null) {
856bda761320929f714951c328bfec6a51a1978db97Wink Saville            loge("Request for unsupported mobile name: " + name);
857bda761320929f714951c328bfec6a51a1978db97Wink Saville            return false;
858071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        }
859bda761320929f714951c328bfec6a51a1978db97Wink Saville        return true;
860bda761320929f714951c328bfec6a51a1978db97Wink Saville    }
861071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt
862bda761320929f714951c328bfec6a51a1978db97Wink Saville    public int getApnPriority(String name) {
863071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        ApnContext apnContext = mApnContexts.get(name);
864071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        if (apnContext == null) {
865bda761320929f714951c328bfec6a51a1978db97Wink Saville            loge("Request for unsupported mobile name: " + name);
866071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt        }
867bda761320929f714951c328bfec6a51a1978db97Wink Saville        return apnContext.priority;
868071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt    }
869071b9f85ac559a35430ed37c03a66271977b9d17Robert Greenwalt
870b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen    // Turn telephony radio on or off.
871b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen    private void setRadio(boolean on) {
872b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        final ITelephony phone = ITelephony.Stub.asInterface(ServiceManager.checkService("phone"));
873b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        try {
874b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            phone.setRadio(on);
875b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        } catch (Exception e) {
876b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            // Ignore.
877b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        }
878b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen    }
879b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen
880b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen    // Class to handle Intent dispatched with user selects the "Sign-in to network"
881b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen    // notification.
882b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen    private class ProvisionNotificationBroadcastReceiver extends BroadcastReceiver {
8832b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen        private final String mNetworkOperator;
884b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        // Mobile provisioning URL.  Valid while provisioning notification is up.
885b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        // Set prior to notification being posted as URL contains ICCID which
886b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        // disappears when radio is off (which is the case when notification is up).
887b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        private final String mProvisionUrl;
888b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen
8892b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen        public ProvisionNotificationBroadcastReceiver(String provisionUrl, String networkOperator) {
8902b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            mNetworkOperator = networkOperator;
891b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            mProvisionUrl = provisionUrl;
892b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        }
893b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen
894b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        private void setEnableFailFastMobileData(int enabled) {
8956395443719ec3ee0257085945e753d02f603886bRobert Greenwalt            sendMessage(obtainMessage(DctConstants.CMD_SET_ENABLE_FAIL_FAST_MOBILE_DATA, enabled, 0));
896b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        }
897b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen
898b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        private void enableMobileProvisioning() {
899b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            final Message msg = obtainMessage(DctConstants.CMD_ENABLE_MOBILE_PROVISIONING);
900b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            msg.setData(Bundle.forPair(DctConstants.PROVISIONING_URL_KEY, mProvisionUrl));
901b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            sendMessage(msg);
902b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        }
903b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen
904b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        @Override
905b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        public void onReceive(Context context, Intent intent) {
9062b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            // Turning back on the radio can take time on the order of a minute, so show user a
9072b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            // spinner so they know something is going on.
9082b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            mProvisioningSpinner = new ProgressDialog(context);
9092b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            mProvisioningSpinner.setTitle(mNetworkOperator);
9102b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            mProvisioningSpinner.setMessage(
9112b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                    // TODO: Don't borrow "Connecting..." i18n string; give Telephony a version.
9122b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                    context.getText(com.android.internal.R.string.media_route_status_connecting));
9132b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            mProvisioningSpinner.setIndeterminate(true);
9142b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            mProvisioningSpinner.setCancelable(true);
9152b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            // Allow non-Activity Service Context to create a View.
9162b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            mProvisioningSpinner.getWindow().setType(
9172b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                    WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
9182b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            mProvisioningSpinner.show();
9192b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            // After timeout, hide spinner so user can at least use their device.
9202b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            // TODO: Indicate to user that it is taking an unusually long time to connect?
9212b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            sendMessageDelayed(obtainMessage(DctConstants.CMD_CLEAR_PROVISIONING_SPINNER,
9222b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                    mProvisioningSpinner), PROVISIONING_SPINNER_TIMEOUT_MILLIS);
923b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            // This code is almost identical to the old
924b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            // ConnectivityService.handleMobileProvisioningAction code.
925b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            setRadio(true);
926b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            setEnableFailFastMobileData(DctConstants.ENABLED);
927b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen            enableMobileProvisioning();
928b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen        }
929b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen    }
930b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen
931cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public boolean isApnTypeActive(String type) {
932cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ApnContext apnContext = mApnContexts.get(type);
933cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext == null) return false;
934cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
935ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        return (apnContext.getDcAc() != null);
936cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
937cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
938cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public boolean isDataPossible(String apnType) {
939cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ApnContext apnContext = mApnContexts.get(apnType);
940cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext == null) {
941cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return false;
942cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
943cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean apnContextIsEnabled = apnContext.isEnabled();
944cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        DctConstants.State apnContextState = apnContext.getState();
945cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean apnTypePossible = !(apnContextIsEnabled &&
946cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                (apnContextState == DctConstants.State.FAILED));
947cf5205f70eb1eac497164124187a088ecb03fff5Ram        boolean isEmergencyApn = apnContext.getApnType().equals(PhoneConstants.APN_TYPE_EMERGENCY);
948cf5205f70eb1eac497164124187a088ecb03fff5Ram        // Set the emergency APN availability status as TRUE irrespective of conditions checked in
949cf5205f70eb1eac497164124187a088ecb03fff5Ram        // isDataAllowed() like IN_SERVICE, MOBILE DATA status etc.
9509c32a1e9495f06905377c9e2b91c0ef9cdb0528fJack Yu        boolean dataAllowed = isEmergencyApn || isDataAllowed(null);
951cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean possible = dataAllowed && apnTypePossible;
952cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
9530e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh        if ((apnContext.getApnType().equals(PhoneConstants.APN_TYPE_DEFAULT)
9540e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh                    || apnContext.getApnType().equals(PhoneConstants.APN_TYPE_IA))
9550e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh                && (mPhone.getServiceState().getRilDataRadioTechnology()
9560e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh                == ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN)) {
9570e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh            log("Default data call activation not possible in iwlan.");
9580e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh            possible = false;
9590e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh        }
9600e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh
961ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (VDBG) {
962cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log(String.format("isDataPossible(%s): possible=%b isDataAllowed=%b " +
963cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    "apnTypePossible=%b apnContextisEnabled=%b apnContextState()=%s",
964cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnType, possible, dataAllowed, apnTypePossible,
965cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnContextIsEnabled, apnContextState));
966cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
967cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return possible;
968cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
969cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
970cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
971cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void finalize() {
972cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if(DBG) log("finalize");
973cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
974cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
9754a9b3afeb2ec4d573eca335a3706392ecf9f281eWink Saville    private ApnContext addApnContext(String type, NetworkConfig networkConfig) {
9760e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu        ApnContext apnContext = new ApnContext(mPhone, type, LOG_TAG, networkConfig, this);
977cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mApnContexts.put(type, apnContext);
978af5593594070f825032be46dced573cd195956e1Robert Greenwalt        mApnContextsById.put(ApnContext.apnIdForApnName(type), apnContext);
9793fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        mPrioritySortedApnContexts.add(apnContext);
980bce3d2575122929bb27ec8a37d56e96da39a3ca2Robert Greenwalt        return apnContext;
981cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
982c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
9831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void initApnContexts() {
984d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt        log("initApnContexts: E");
985d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt        // Load device network attributes from resources
986d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt        String[] networkConfigStrings = mPhone.getContext().getResources().getStringArray(
987d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                com.android.internal.R.array.networkAttributes);
988d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt        for (String networkConfigString : networkConfigStrings) {
989d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            NetworkConfig networkConfig = new NetworkConfig(networkConfigString);
990d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            ApnContext apnContext = null;
991d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt
992d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            switch (networkConfig.type) {
993d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            case ConnectivityManager.TYPE_MOBILE:
994d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                apnContext = addApnContext(PhoneConstants.APN_TYPE_DEFAULT, networkConfig);
995d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                break;
996d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            case ConnectivityManager.TYPE_MOBILE_MMS:
997d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                apnContext = addApnContext(PhoneConstants.APN_TYPE_MMS, networkConfig);
998d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                break;
999d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            case ConnectivityManager.TYPE_MOBILE_SUPL:
1000d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                apnContext = addApnContext(PhoneConstants.APN_TYPE_SUPL, networkConfig);
1001d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                break;
1002d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            case ConnectivityManager.TYPE_MOBILE_DUN:
1003d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                apnContext = addApnContext(PhoneConstants.APN_TYPE_DUN, networkConfig);
1004d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                break;
1005d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            case ConnectivityManager.TYPE_MOBILE_HIPRI:
1006d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                apnContext = addApnContext(PhoneConstants.APN_TYPE_HIPRI, networkConfig);
1007d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                break;
1008d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            case ConnectivityManager.TYPE_MOBILE_FOTA:
1009d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                apnContext = addApnContext(PhoneConstants.APN_TYPE_FOTA, networkConfig);
1010d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                break;
1011d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            case ConnectivityManager.TYPE_MOBILE_IMS:
1012d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                apnContext = addApnContext(PhoneConstants.APN_TYPE_IMS, networkConfig);
1013d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                break;
1014d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            case ConnectivityManager.TYPE_MOBILE_CBS:
1015d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                apnContext = addApnContext(PhoneConstants.APN_TYPE_CBS, networkConfig);
1016d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                break;
1017d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            case ConnectivityManager.TYPE_MOBILE_IA:
1018d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                apnContext = addApnContext(PhoneConstants.APN_TYPE_IA, networkConfig);
1019d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                break;
1020cf5205f70eb1eac497164124187a088ecb03fff5Ram            case ConnectivityManager.TYPE_MOBILE_EMERGENCY:
1021cf5205f70eb1eac497164124187a088ecb03fff5Ram                apnContext = addApnContext(PhoneConstants.APN_TYPE_EMERGENCY, networkConfig);
1022cf5205f70eb1eac497164124187a088ecb03fff5Ram                break;
1023d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            default:
1024d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                log("initApnContexts: skipping unknown type=" + networkConfig.type);
1025d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt                continue;
1026d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            }
1027d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt            log("initApnContexts: apnContext=" + apnContext);
1028d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt        }
1029092e6bd60f1a4a3a55fb73ad0efca1122b8e15e2Jack Yu
1030092e6bd60f1a4a3a55fb73ad0efca1122b8e15e2Jack Yu        if (VDBG) log("initApnContexts: X mApnContexts=" + mApnContexts);
1031d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt    }
1032d32b58c8e7cea693c98f49b2291455e917cd9301Robert Greenwalt
1033cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public LinkProperties getLinkProperties(String apnType) {
1034cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ApnContext apnContext = mApnContexts.get(apnType);
1035cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext != null) {
1036454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville            DcAsyncChannel dcac = apnContext.getDcAc();
1037cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (dcac != null) {
1038cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) log("return link properites for " + apnType);
1039cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return dcac.getLinkPropertiesSync();
1040cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1041cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1042cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("return new LinkProperties");
1043cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return new LinkProperties();
1044cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1045cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
1046608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt    public NetworkCapabilities getNetworkCapabilities(String apnType) {
1047608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt        ApnContext apnContext = mApnContexts.get(apnType);
1048608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt        if (apnContext!=null) {
1049608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt            DcAsyncChannel dataConnectionAc = apnContext.getDcAc();
1050608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt            if (dataConnectionAc != null) {
1051608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt                if (DBG) {
1052608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt                    log("get active pdp is not null, return NetworkCapabilities for " + apnType);
1053608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt                }
1054608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt                return dataConnectionAc.getNetworkCapabilitiesSync();
1055608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt            }
1056608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt        }
1057608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt        if (DBG) log("return new NetworkCapabilities");
1058608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt        return new NetworkCapabilities();
1059608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt    }
1060cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1061cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // Return all active apn types
1062cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public String[] getActiveApnTypes() {
1063cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("get all active apn types");
1064cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ArrayList<String> result = new ArrayList<String>();
1065cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
1066cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (ApnContext apnContext : mApnContexts.values()) {
1067187a39f896f88eb6c5e4306d9595546654825976Wink Saville            if (mAttached.get() && apnContext.isReady()) {
1068cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                result.add(apnContext.getApnType());
1069cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            }
1070cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
1071c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1072cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return result.toArray(new String[0]);
1073cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1074cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1075cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // Return active apn of specific apn type
1076cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public String getActiveApnString(String apnType) {
1077ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (VDBG) log( "get active apn string for type:" + apnType);
1078cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ApnContext apnContext = mApnContexts.get(apnType);
1079cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext != null) {
1080cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            ApnSetting apnSetting = apnContext.getApnSetting();
1081cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (apnSetting != null) {
1082cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return apnSetting.apn;
1083cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1084cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1085cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return null;
1086cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1087cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1088cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public boolean isApnTypeEnabled(String apnType) {
1089cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ApnContext apnContext = mApnContexts.get(apnType);
1090cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext == null) {
1091cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return false;
1092cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1093cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return apnContext.isEnabled();
1094cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1095cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
10961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void setState(DctConstants.State s) {
1097cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("setState should not be used in GSM" + s);
1098cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1099cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1100cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // Return state of specific apn type
1101cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public DctConstants.State getState(String apnType) {
1102cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ApnContext apnContext = mApnContexts.get(apnType);
1103cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext != null) {
1104cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return apnContext.getState();
1105c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1106cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return DctConstants.State.FAILED;
1107cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1108c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1109c9b81a0c05128694c617fcdd67e73821895822feWink Saville    // Return if apn type is a provisioning apn.
11101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean isProvisioningApn(String apnType) {
1111c9b81a0c05128694c617fcdd67e73821895822feWink Saville        ApnContext apnContext = mApnContexts.get(apnType);
1112c9b81a0c05128694c617fcdd67e73821895822feWink Saville        if (apnContext != null) {
1113c9b81a0c05128694c617fcdd67e73821895822feWink Saville            return apnContext.isProvisioningApn();
1114c9b81a0c05128694c617fcdd67e73821895822feWink Saville        }
1115c9b81a0c05128694c617fcdd67e73821895822feWink Saville        return false;
1116c9b81a0c05128694c617fcdd67e73821895822feWink Saville    }
1117c9b81a0c05128694c617fcdd67e73821895822feWink Saville
1118cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // Return state of overall
1119cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public DctConstants.State getOverallState() {
1120cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean isConnecting = false;
1121cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean isFailed = true; // All enabled Apns should be FAILED.
1122cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean isAnyEnabled = false;
1123cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1124cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (ApnContext apnContext : mApnContexts.values()) {
1125cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (apnContext.isEnabled()) {
1126cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                isAnyEnabled = true;
1127cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                switch (apnContext.getState()) {
1128cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                case CONNECTED:
1129cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                case DISCONNECTING:
11301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (VDBG) log("overall state is CONNECTED");
1131cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    return DctConstants.State.CONNECTED;
1132ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                case RETRYING:
1133cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                case CONNECTING:
1134cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    isConnecting = true;
1135cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    isFailed = false;
1136cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    break;
1137cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                case IDLE:
1138cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                case SCANNING:
1139cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    isFailed = false;
1140cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    break;
1141cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                default:
1142cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    isAnyEnabled = true;
1143cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    break;
1144cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
1145cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1146c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1147c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1148cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (!isAnyEnabled) { // Nothing enabled. return IDLE.
11491a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (VDBG) log( "overall state is IDLE");
1150cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return DctConstants.State.IDLE;
1151c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1152c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1153cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (isConnecting) {
11541a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (VDBG) log( "overall state is CONNECTING");
1155cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return DctConstants.State.CONNECTING;
1156cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else if (!isFailed) {
11571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (VDBG) log( "overall state is IDLE");
1158cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return DctConstants.State.IDLE;
1159cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
11601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (VDBG) log( "overall state is FAILED");
1161cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return DctConstants.State.FAILED;
1162c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1163c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1164c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1165cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /**
1166cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Report on whether data connectivity is enabled for any APN.
1167cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @return {@code false} if data connectivity has been explicitly disabled,
1168cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * {@code true} otherwise.
1169cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     */
1170cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public boolean getAnyDataEnabled() {
1171cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        synchronized (mDataEnabledLock) {
1172cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (!(mInternalDataEnabled && mUserDataEnabled && sPolicyDataEnabled)) return false;
11739c32a1e9495f06905377c9e2b91c0ef9cdb0528fJack Yu            StringBuilder failureReason = new StringBuilder();
11749c32a1e9495f06905377c9e2b91c0ef9cdb0528fJack Yu            if (!isDataAllowed(failureReason)) {
11759c32a1e9495f06905377c9e2b91c0ef9cdb0528fJack Yu                if (DBG) log(failureReason.toString());
11769c32a1e9495f06905377c9e2b91c0ef9cdb0528fJack Yu                return false;
11779c32a1e9495f06905377c9e2b91c0ef9cdb0528fJack Yu            }
1178cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            for (ApnContext apnContext : mApnContexts.values()) {
1179cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // Make sure we don't have a context that is going down
1180cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // and is explicitly disabled.
11819c32a1e9495f06905377c9e2b91c0ef9cdb0528fJack Yu                if (isDataAllowedForApn(apnContext)) {
1182cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    return true;
1183cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
1184cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1185cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return false;
1186c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1187c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1188c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1189a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public boolean getAnyDataEnabled(boolean checkUserDataEnabled) {
1190a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        synchronized (mDataEnabledLock) {
1191a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (!(mInternalDataEnabled && (!checkUserDataEnabled || mUserDataEnabled)
1192a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                        && (!checkUserDataEnabled || sPolicyDataEnabled)))
1193a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                return false;
1194a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
11959c32a1e9495f06905377c9e2b91c0ef9cdb0528fJack Yu            StringBuilder failureReason = new StringBuilder();
11969c32a1e9495f06905377c9e2b91c0ef9cdb0528fJack Yu            if (!isDataAllowed(failureReason)) {
11979c32a1e9495f06905377c9e2b91c0ef9cdb0528fJack Yu                if (DBG) log(failureReason.toString());
11989c32a1e9495f06905377c9e2b91c0ef9cdb0528fJack Yu                return false;
11999c32a1e9495f06905377c9e2b91c0ef9cdb0528fJack Yu            }
1200a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            for (ApnContext apnContext : mApnContexts.values()) {
1201a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                // Make sure we dont have a context that going down
1202a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                // and is explicitly disabled.
12039c32a1e9495f06905377c9e2b91c0ef9cdb0528fJack Yu                if (isDataAllowedForApn(apnContext)) {
1204a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    return true;
1205a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                }
1206a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
1207a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            return false;
1208a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
1209a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
1210a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
12119c32a1e9495f06905377c9e2b91c0ef9cdb0528fJack Yu    private boolean isDataAllowedForApn(ApnContext apnContext) {
12120e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh        //If RAT is iwlan then dont allow default/IA PDP at all.
12130e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh        //Rest of APN types can be evaluated for remaining conditions.
12140e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh        if ((apnContext.getApnType().equals(PhoneConstants.APN_TYPE_DEFAULT)
12150e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh                    || apnContext.getApnType().equals(PhoneConstants.APN_TYPE_IA))
12160e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh                && (mPhone.getServiceState().getRilDataRadioTechnology()
12170e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh                == ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN)) {
12180e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh            log("Default data call activation not allowed in iwlan.");
12190e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh            return false;
12200e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh        }
12219c32a1e9495f06905377c9e2b91c0ef9cdb0528fJack Yu
12229c32a1e9495f06905377c9e2b91c0ef9cdb0528fJack Yu        return apnContext.isReady();
1223c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1224c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1225cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    //****** Called from ServiceStateTracker
1226c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
1227cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Invoked when ServiceStateTracker observes a transition from GPRS
1228cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * attach to detach.
1229c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
12301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onDataConnectionDetached() {
1231cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        /*
1232cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville         * We presently believe it is unnecessary to tear down the PDP context
1233cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville         * when GPRS detaches, but we should stop the network polling.
1234cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville         */
1235cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log ("onDataConnectionDetached: stop polling and notify detached");
1236cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        stopNetStatPoll();
1237cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        stopDataStallAlarm();
1238cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        notifyDataConnection(Phone.REASON_DATA_DETACHED);
1239187a39f896f88eb6c5e4306d9595546654825976Wink Saville        mAttached.set(false);
1240cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1241c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1242cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private void onDataConnectionAttached() {
1243cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onDataConnectionAttached");
12447ab10e4710bdb54c6d9a5ee01cd443a42a2689f5Sungmin Choi        mAttached.set(true);
1245cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (getOverallState() == DctConstants.State.CONNECTED) {
1246cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("onDataConnectionAttached: start polling notify attached");
1247cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            startNetStatPoll();
1248cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
1249cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyDataConnection(Phone.REASON_DATA_ATTACHED);
1250cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
1251cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // update APN availability so that APN can be enabled.
1252cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyOffApnsOfAvailability(Phone.REASON_DATA_ATTACHED);
1253cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
125412fffcf0d8df6b8268806d9aa7cc7a662e73743bJing Zhao        if (mAutoAttachOnCreationConfig) {
1255aacc11b299ac047e73e1e712aa396ea0a6a80158Robert Greenwalt            mAutoAttachOnCreation.set(true);
125612fffcf0d8df6b8268806d9aa7cc7a662e73743bJing Zhao        }
1257ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        setupDataOnConnectableApns(Phone.REASON_DATA_ATTACHED);
1258cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1259c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
12609c32a1e9495f06905377c9e2b91c0ef9cdb0528fJack Yu    private boolean isDataAllowed(StringBuilder failureReason) {
1261cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        final boolean internalDataEnabled;
1262cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        synchronized (mDataEnabledLock) {
1263cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            internalDataEnabled = mInternalDataEnabled;
1264cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1265cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
12669894b3fb2f35e21d9cfd45f233ed093589e14c26sy.yun        boolean attachedState = mAttached.get();
1267cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean desiredPowerState = mPhone.getServiceStateTracker().getDesiredPowerState();
12680e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh        int radioTech = mPhone.getServiceState().getRilDataRadioTechnology();
12690e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh        if (radioTech == ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN) {
12700e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh            desiredPowerState = true;
12710e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh        }
12720e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh
1273cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        IccRecords r = mIccRecords.get();
12742b0f0da4f9fe8449c578632b491e2f158c201bd5Stuart Scott        boolean recordsLoaded = false;
12752b0f0da4f9fe8449c578632b491e2f158c201bd5Stuart Scott        if (r != null) {
12762b0f0da4f9fe8449c578632b491e2f158c201bd5Stuart Scott            recordsLoaded = r.getRecordsLoaded();
12779232dafa7ea833fc0b3a6024d6c7e23fc8e961eaRobert Greenwalt            if (DBG && !recordsLoaded) log("isDataAllowed getRecordsLoaded=" + recordsLoaded);
12782b0f0da4f9fe8449c578632b491e2f158c201bd5Stuart Scott        }
1279cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
128038ca51d0f643405df51e78fce6c546424e9f410dShishir Agrawal        int dataSub = SubscriptionManager.getDefaultDataSubscriptionId();
1281434fa420329b093f68d83862a637c7ded93a4dafCraig Lafayette        boolean defaultDataSelected = SubscriptionManager.isValidSubscriptionId(dataSub);
1282b79f845a0451895b0f0b8a926a8571511d476ce8Libin.Tang@motorola.com        PhoneConstants.State state = PhoneConstants.State.IDLE;
12830710ff7ae80f217782f08528c5406f6d26a29f75Robert Greenwalt        // Note this is explicitly not using mPhone.getState.  See b/19090488.
12840710ff7ae80f217782f08528c5406f6d26a29f75Robert Greenwalt        // mPhone.getState reports the merge of CS and PS (volte) voice call state
12850710ff7ae80f217782f08528c5406f6d26a29f75Robert Greenwalt        // but we only care about CS calls here for data/voice concurrency issues.
12860710ff7ae80f217782f08528c5406f6d26a29f75Robert Greenwalt        // Calling getCallTracker currently gives you just the CS side where the
12870710ff7ae80f217782f08528c5406f6d26a29f75Robert Greenwalt        // ImsCallTracker is held internally where applicable.
12880710ff7ae80f217782f08528c5406f6d26a29f75Robert Greenwalt        // This should be redesigned to ask explicitly what we want:
12890710ff7ae80f217782f08528c5406f6d26a29f75Robert Greenwalt        // voiceCallStateAllowDataCall, or dataCallAllowed or something similar.
1290b79f845a0451895b0f0b8a926a8571511d476ce8Libin.Tang@motorola.com        if (mPhone.getCallTracker() != null) {
1291b79f845a0451895b0f0b8a926a8571511d476ce8Libin.Tang@motorola.com            state = mPhone.getCallTracker().getState();
1292b79f845a0451895b0f0b8a926a8571511d476ce8Libin.Tang@motorola.com        }
12931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1294cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean allowed =
1295aacc11b299ac047e73e1e712aa396ea0a6a80158Robert Greenwalt                    (attachedState || mAutoAttachOnCreation.get()) &&
1296cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    recordsLoaded &&
1297b79f845a0451895b0f0b8a926a8571511d476ce8Libin.Tang@motorola.com                    (state == PhoneConstants.State.IDLE ||
1298cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                     mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) &&
1299cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    internalDataEnabled &&
13002b0f0da4f9fe8449c578632b491e2f158c201bd5Stuart Scott                    defaultDataSelected &&
1301ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao                    (!mPhone.getServiceState().getDataRoaming() || getDataOnRoamingEnabled()) &&
13021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    !mIsPsRestricted &&
1303cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    desiredPowerState;
13049c32a1e9495f06905377c9e2b91c0ef9cdb0528fJack Yu        if (!allowed && failureReason != null) {
13059c32a1e9495f06905377c9e2b91c0ef9cdb0528fJack Yu            failureReason.setLength(0);
13069c32a1e9495f06905377c9e2b91c0ef9cdb0528fJack Yu            failureReason.append("isDataAllowed: No");
1307aacc11b299ac047e73e1e712aa396ea0a6a80158Robert Greenwalt            if (!(attachedState || mAutoAttachOnCreation.get())) {
13089c32a1e9495f06905377c9e2b91c0ef9cdb0528fJack Yu                failureReason.append(" - Attached= " + attachedState);
1309cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
13109c32a1e9495f06905377c9e2b91c0ef9cdb0528fJack Yu            if (!recordsLoaded) failureReason.append(" - SIM not loaded");
1311b79f845a0451895b0f0b8a926a8571511d476ce8Libin.Tang@motorola.com            if (state != PhoneConstants.State.IDLE &&
1312cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    !mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) {
13139c32a1e9495f06905377c9e2b91c0ef9cdb0528fJack Yu                failureReason.append(" - PhoneState= " + state);
13149c32a1e9495f06905377c9e2b91c0ef9cdb0528fJack Yu                failureReason.append(" - Concurrent voice and data not allowed");
1315cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
13169c32a1e9495f06905377c9e2b91c0ef9cdb0528fJack Yu            if (!internalDataEnabled) failureReason.append(" - mInternalDataEnabled= false");
13179c32a1e9495f06905377c9e2b91c0ef9cdb0528fJack Yu            if (!defaultDataSelected) failureReason.append(" - defaultDataSelected= false");
1318ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao            if (mPhone.getServiceState().getDataRoaming() && !getDataOnRoamingEnabled()) {
13199c32a1e9495f06905377c9e2b91c0ef9cdb0528fJack Yu                failureReason.append(" - Roaming and data roaming not enabled");
1320cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
13219c32a1e9495f06905377c9e2b91c0ef9cdb0528fJack Yu            if (mIsPsRestricted) failureReason.append(" - mIsPsRestricted= true");
13229c32a1e9495f06905377c9e2b91c0ef9cdb0528fJack Yu            if (!desiredPowerState) failureReason.append(" - desiredPowerState= false");
1323c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1324cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return allowed;
1325cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1326c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1327c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt    // arg for setupDataOnConnectableApns
1328c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt    private enum RetryFailures {
1329c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt        // retry failed networks always (the old default)
1330c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt        ALWAYS,
13310e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu        // retry only when a substantial change has occurred.  Either:
1332c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt        // 1) we were restricted by voice/data concurrency and aren't anymore
1333c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt        // 2) our apn list has change
1334c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt        ONLY_ON_CHANGE
1335c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt    };
1336c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt
1337ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    private void setupDataOnConnectableApns(String reason) {
1338c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt        setupDataOnConnectableApns(reason, RetryFailures.ALWAYS);
1339c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt    }
1340c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt
1341c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt    private void setupDataOnConnectableApns(String reason, RetryFailures retryFailures) {
13429c32a1e9495f06905377c9e2b91c0ef9cdb0528fJack Yu        if (VDBG) log("setupDataOnConnectableApns: " + reason);
13433fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt
1344c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu        if (DBG && !VDBG) {
1345c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu            StringBuilder sb = new StringBuilder(120);
1346c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu            for (ApnContext apnContext : mPrioritySortedApnContexts) {
1347c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu                sb.append(apnContext.getApnType());
1348c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu                sb.append(":[state=");
1349c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu                sb.append(apnContext.getState());
1350c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu                sb.append(",enabled=");
1351c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu                sb.append(apnContext.isEnabled());
1352c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu                sb.append("] ");
1353c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu            }
13549c32a1e9495f06905377c9e2b91c0ef9cdb0528fJack Yu            log("setupDataOnConnectableApns: " + reason + " " + sb);
1355c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu        }
1356c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu
13573fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        for (ApnContext apnContext : mPrioritySortedApnContexts) {
1358735bc2f4524d68155765351912ffae11306c3bd5Chris Manton            ArrayList<ApnSetting> waitingApns = null;
1359735bc2f4524d68155765351912ffae11306c3bd5Chris Manton
1360c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu            if (VDBG) log("setupDataOnConnectableApns: apnContext " + apnContext);
1361c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu
1362735bc2f4524d68155765351912ffae11306c3bd5Chris Manton            if (apnContext.getState() == DctConstants.State.FAILED
13630e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                    || apnContext.getState() == DctConstants.State.SCANNING) {
1364c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt                if (retryFailures == RetryFailures.ALWAYS) {
1365ee665b78ad648abd98b019a9c9047f206ed22994Robert Greenwalt                    apnContext.releaseDataConnection(reason);
1366c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt                } else if (apnContext.isConcurrentVoiceAndDataAllowed() == false &&
13670e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                        mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) {
1368c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt                    // RetryFailures.ONLY_ON_CHANGE - check if voice concurrency has changed
1369ee665b78ad648abd98b019a9c9047f206ed22994Robert Greenwalt                    apnContext.releaseDataConnection(reason);
1370c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt                } else {
1371c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt                    // RetryFailures.ONLY_ON_CHANGE - check if the apns have changed
1372c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt                    int radioTech = mPhone.getServiceState().getRilDataRadioTechnology();
13730e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                    ArrayList<ApnSetting> originalApns = apnContext.getWaitingApns();
1374c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt                    if (originalApns != null && originalApns.isEmpty() == false) {
1375c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt                        waitingApns = buildWaitingApns(apnContext.getApnType(), radioTech);
1376c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt                        if (originalApns.size() != waitingApns.size() ||
1377c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt                                originalApns.containsAll(waitingApns) == false) {
1378ee665b78ad648abd98b019a9c9047f206ed22994Robert Greenwalt                            apnContext.releaseDataConnection(reason);
1379b290ce3d172215e5ab7cd43c8e7bbee9551ab29eRobert Greenwalt                        } else {
1380b290ce3d172215e5ab7cd43c8e7bbee9551ab29eRobert Greenwalt                            continue;
1381c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt                        }
1382b290ce3d172215e5ab7cd43c8e7bbee9551ab29eRobert Greenwalt                    } else {
1383b290ce3d172215e5ab7cd43c8e7bbee9551ab29eRobert Greenwalt                        continue;
1384c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt                    }
1385c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt                }
1386cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1387ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (apnContext.isConnectable()) {
13889c32a1e9495f06905377c9e2b91c0ef9cdb0528fJack Yu                log("isConnectable() call trySetupData");
1389ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                apnContext.setReason(reason);
1390c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt                trySetupData(apnContext, waitingApns);
1391cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1392cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1393c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1394c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
13951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    boolean isEmergency() {
13961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        final boolean result;
13971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        synchronized (mDataEnabledLock) {
13981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            result = mPhone.isInEcm() || mPhone.isInEmergencyCall();
13991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
14001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        log("isEmergency: result=" + result);
14011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        return result;
14021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
14031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1404cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private boolean trySetupData(ApnContext apnContext) {
1405c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt        return trySetupData(apnContext, null);
1406c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt    }
1407c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt
1408c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt    private boolean trySetupData(ApnContext apnContext, ArrayList<ApnSetting> waitingApns) {
1409cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) {
1410cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("trySetupData for type:" + apnContext.getApnType() +
14119c32a1e9495f06905377c9e2b91c0ef9cdb0528fJack Yu                    " due to " + apnContext.getReason() + ", mIsPsRestricted=" + mIsPsRestricted);
1412cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
14132dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt        apnContext.requestLog("trySetupData due to " + apnContext.getReason());
1414cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1415cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (mPhone.getSimulatedRadioControl() != null) {
1416cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // Assume data is connected on the simulator
1417cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // FIXME  this can be improved
1418cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            apnContext.setState(DctConstants.State.CONNECTED);
1419cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
1420cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1421cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("trySetupData: X We're on the simulator; assuming connected retValue=true");
1422cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return true;
1423cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1424cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1425cf5205f70eb1eac497164124187a088ecb03fff5Ram        // Allow SETUP_DATA request for E-APN to be completed during emergency call
1426cf5205f70eb1eac497164124187a088ecb03fff5Ram        // and MOBILE DATA On/Off cases as well.
1427cf5205f70eb1eac497164124187a088ecb03fff5Ram        boolean isEmergencyApn = apnContext.getApnType().equals(PhoneConstants.APN_TYPE_EMERGENCY);
1428c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt        final ServiceStateTracker sst = mPhone.getServiceStateTracker();
14290e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu
1430a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        boolean checkUserDataEnabled =
1431a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    !(apnContext.getApnType().equals(PhoneConstants.APN_TYPE_IMS));
1432cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
14339c32a1e9495f06905377c9e2b91c0ef9cdb0528fJack Yu        StringBuilder failureReason = new StringBuilder();
1434cf5205f70eb1eac497164124187a088ecb03fff5Ram        if (apnContext.isConnectable() && (isEmergencyApn ||
14359c32a1e9495f06905377c9e2b91c0ef9cdb0528fJack Yu                (isDataAllowed(failureReason) && isDataAllowedForApn(apnContext) &&
1436cf5205f70eb1eac497164124187a088ecb03fff5Ram                getAnyDataEnabled(checkUserDataEnabled) && !isEmergency()))) {
14379c32a1e9495f06905377c9e2b91c0ef9cdb0528fJack Yu            if (!failureReason.toString().isEmpty()) {
14389c32a1e9495f06905377c9e2b91c0ef9cdb0528fJack Yu                if (DBG) log(failureReason.toString());
14399c32a1e9495f06905377c9e2b91c0ef9cdb0528fJack Yu                apnContext.requestLog(failureReason.toString());
14409c32a1e9495f06905377c9e2b91c0ef9cdb0528fJack Yu            }
1441ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (apnContext.getState() == DctConstants.State.FAILED) {
14422dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                String str ="trySetupData: make a FAILED ApnContext IDLE so its reusable";
14432dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                if (DBG) log(str);
14442dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                apnContext.requestLog(str);
1445ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                apnContext.setState(DctConstants.State.IDLE);
1446ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            }
1447203e588e3c42a81aa8a56f595119c181a63b12caWink Saville            int radioTech = mPhone.getServiceState().getRilDataRadioTechnology();
1448c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt            apnContext.setConcurrentVoiceAndDataAllowed(sst.isConcurrentVoiceAndDataAllowed());
1449cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (apnContext.getState() == DctConstants.State.IDLE) {
1450c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt                if (waitingApns == null) {
1451c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt                    waitingApns = buildWaitingApns(apnContext.getApnType(), radioTech);
1452c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt                }
1453cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (waitingApns.isEmpty()) {
1454ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                    notifyNoData(DcFailCause.MISSING_UNKNOWN_APN, apnContext);
1455cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    notifyOffApnsOfAvailability(apnContext.getReason());
14562dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                    String str = "trySetupData: X No APN found retValue=false";
14572dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                    if (DBG) log(str);
14582dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                    apnContext.requestLog(str);
1459cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    return false;
1460cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else {
1461cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnContext.setWaitingApns(waitingApns);
1462cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    if (DBG) {
1463ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                        log ("trySetupData: Create from mAllApnSettings : "
1464ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                    + apnListToString(mAllApnSettings));
1465cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    }
1466cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
1467cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1468cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1469203e588e3c42a81aa8a56f595119c181a63b12caWink Saville            boolean retValue = setupData(apnContext, radioTech);
1470cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyOffApnsOfAvailability(apnContext.getReason());
1471cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1472cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("trySetupData: X retValue=" + retValue);
1473cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return retValue;
1474cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
1475cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (!apnContext.getApnType().equals(PhoneConstants.APN_TYPE_DEFAULT)
1476ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                    && apnContext.isConnectable()) {
1477cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mPhone.notifyDataConnectionFailed(apnContext.getReason(), apnContext.getApnType());
1478ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            }
1479cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyOffApnsOfAvailability(apnContext.getReason());
14802dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt            String str = "trySetupData: X apnContext not 'ready' retValue=false";
14812dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt            apnContext.requestLog(str);
14822dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt            if (DBG) {
14832dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                log(str);
14842dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                if (!apnContext.isConnectable()) log("apnContext.isConnectable = false");
14859c32a1e9495f06905377c9e2b91c0ef9cdb0528fJack Yu                if (!isDataAllowed(failureReason)) log(failureReason.toString());
14869c32a1e9495f06905377c9e2b91c0ef9cdb0528fJack Yu                if (!isDataAllowedForApn(apnContext)) log("isDataAllowedForApn = false");
14872dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                if (!getAnyDataEnabled(checkUserDataEnabled)) {
14882dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                    log("getAnyDataEnabled(" + checkUserDataEnabled + ") = false");
14892dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                }
14902dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt            }
1491cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return false;
1492cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1493c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1494c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
14950e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu    // Disabled apn's still need avail/unavail notifications - send them out
14961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void notifyOffApnsOfAvailability(String reason) {
14979c32a1e9495f06905377c9e2b91c0ef9cdb0528fJack Yu        if (DBG) {
14989c32a1e9495f06905377c9e2b91c0ef9cdb0528fJack Yu            StringBuilder failureReason = new StringBuilder();
14999c32a1e9495f06905377c9e2b91c0ef9cdb0528fJack Yu            isDataAllowed(failureReason);
15009c32a1e9495f06905377c9e2b91c0ef9cdb0528fJack Yu            if (!failureReason.toString().isEmpty()) {
15019c32a1e9495f06905377c9e2b91c0ef9cdb0528fJack Yu                log(failureReason.toString());
15029c32a1e9495f06905377c9e2b91c0ef9cdb0528fJack Yu            }
15039c32a1e9495f06905377c9e2b91c0ef9cdb0528fJack Yu        }
1504cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (ApnContext apnContext : mApnContexts.values()) {
1505187a39f896f88eb6c5e4306d9595546654825976Wink Saville            if (!mAttached.get() || !apnContext.isReady()) {
1506ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                if (VDBG) log("notifyOffApnOfAvailability type:" + apnContext.getApnType());
1507cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mPhone.notifyDataConnection(reason != null ? reason : apnContext.getReason(),
1508cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                            apnContext.getApnType(),
1509cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                            PhoneConstants.DataState.DISCONNECTED);
1510cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } else {
1511ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                if (VDBG) {
1512187a39f896f88eb6c5e4306d9595546654825976Wink Saville                    log("notifyOffApnsOfAvailability skipped apn due to attached && isReady " +
1513cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            apnContext.toString());
1514cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
1515c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
1516c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1517c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1518c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1519cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /**
1520cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * If tearDown is true, this only tears down a CONNECTED session. Presently,
1521cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * there is no mechanism for abandoning an CONNECTING session,
1522cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * but would likely involve cancelling pending async requests or
1523cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * setting a flag or new state to ignore them when they came in
1524cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @param tearDown true if the underlying DataConnection should be
1525cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * disconnected.
1526cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @param reason reason for the clean up.
15273fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     * @return boolean - true if we did cleanup any connections, false if they
15283fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     *                   were already all disconnected.
1529cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     */
15301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean cleanUpAllConnections(boolean tearDown, String reason) {
1531cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("cleanUpAllConnections: tearDown=" + tearDown + " reason=" + reason);
15323fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        boolean didDisconnect = false;
1533a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        boolean specificdisable = false;
1534a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1535a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (!TextUtils.isEmpty(reason)) {
1536a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            specificdisable = reason.equals(Phone.REASON_DATA_SPECIFIC_DISABLED);
1537a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
1538cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1539cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (ApnContext apnContext : mApnContexts.values()) {
15403fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            if (apnContext.isDisconnected() == false) didDisconnect = true;
1541a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (specificdisable) {
1542a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                if (!apnContext.getApnType().equals(PhoneConstants.APN_TYPE_IMS)) {
1543a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    if (DBG) log("ApnConextType: " + apnContext.getApnType());
1544a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    apnContext.setReason(reason);
1545a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    cleanUpConnection(tearDown, apnContext);
1546a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                }
1547a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            } else {
1548a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                // TODO - only do cleanup if not disconnected
1549a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                apnContext.setReason(reason);
1550a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                cleanUpConnection(tearDown, apnContext);
1551a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
1552c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1553cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1554cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        stopNetStatPoll();
1555cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        stopDataStallAlarm();
1556cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1557cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // TODO: Do we need mRequestedApnType?
1558cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mRequestedApnType = PhoneConstants.APN_TYPE_DEFAULT;
1559a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1560a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        log("cleanUpConnection: mDisconnectPendingCount = " + mDisconnectPendingCount);
1561a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (tearDown && mDisconnectPendingCount == 0) {
1562a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            notifyDataDisconnectComplete();
1563a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            notifyAllDataDisconnected();
1564a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
1565a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
15663fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        return didDisconnect;
1567cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1568cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1569cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /**
1570cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Cleanup all connections.
1571cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *
1572cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * TODO: Cleanup only a specified connection passed as a parameter.
1573cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *       Also, make sure when you clean up a conn, if it is last apply
1574cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *       logic as though it is cleanupAllConnections
1575cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *
1576cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @param cause for the clean up.
1577cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     */
15781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onCleanUpAllConnections(String cause) {
1579cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        cleanUpAllConnections(true, cause);
1580cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1581cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
15821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    void sendCleanUpConnection(boolean tearDown, ApnContext apnContext) {
15831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (DBG) log("sendCleanUpConnection: tearDown=" + tearDown + " apnContext=" + apnContext);
15841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        Message msg = obtainMessage(DctConstants.EVENT_CLEAN_UP_CONNECTION);
15851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        msg.arg1 = tearDown ? 1 : 0;
15861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        msg.arg2 = 0;
15871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        msg.obj = apnContext;
15881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        sendMessage(msg);
15891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
1590cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
15911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void cleanUpConnection(boolean tearDown, ApnContext apnContext) {
1592cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext == null) {
1593cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("cleanUpConnection: apn context is null");
1594cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return;
1595cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1596cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1597454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville        DcAsyncChannel dcac = apnContext.getDcAc();
15982dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt        String str = "cleanUpConnection: tearDown=" + tearDown + " reason=" +
15992dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                apnContext.getReason();
16009c32a1e9495f06905377c9e2b91c0ef9cdb0528fJack Yu        if (VDBG) log(str + " apnContext=" + apnContext);
16012dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt        apnContext.requestLog(str);
1602cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (tearDown) {
1603cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (apnContext.isDisconnected()) {
1604cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // The request is tearDown and but ApnContext is not connected.
1605cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // If apnContext is not enabled anymore, break the linkage to the DCAC/DC.
1606cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                apnContext.setState(DctConstants.State.IDLE);
1607cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (!apnContext.isReady()) {
16084750c8c11836338b024e159f04f0cbd13c7444b9Wink Saville                    if (dcac != null) {
16090e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                        str = "cleanUpConnection: teardown, disconnected, !ready";
16102dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                        if (DBG) log(str + " apnContext=" + apnContext);
16112dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                        apnContext.requestLog(str);
16124750c8c11836338b024e159f04f0cbd13c7444b9Wink Saville                        dcac.tearDown(apnContext, "", null);
16134750c8c11836338b024e159f04f0cbd13c7444b9Wink Saville                    }
1614cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnContext.setDataConnectionAc(null);
1615cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
1616cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } else {
1617cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // Connection is still there. Try to clean up.
1618cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (dcac != null) {
1619cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    if (apnContext.getState() != DctConstants.State.DISCONNECTING) {
1620cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        boolean disconnectAll = false;
1621cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        if (PhoneConstants.APN_TYPE_DUN.equals(apnContext.getApnType())) {
1622a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                            // CAF_MSIM is this below condition required.
1623a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                            // if (PhoneConstants.APN_TYPE_DUN.equals(PhoneConstants.APN_TYPE_DEFAULT)) {
16241484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                            if (teardownForDun()) {
162545eaa2335e64a8ff1ad8d5e8224c580ef996f370Wink Saville                                if (DBG) {
162645eaa2335e64a8ff1ad8d5e8224c580ef996f370Wink Saville                                    log("cleanUpConnection: disconnectAll DUN connection");
162745eaa2335e64a8ff1ad8d5e8224c580ef996f370Wink Saville                                }
1628cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                // we need to tear it down - we brought it up just for dun and
1629cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                // other people are camped on it and now dun is done.  We need
1630cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                // to stop using it and let the normal apn list get used to find
1631cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                // connections for the remaining desired connections
1632cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                disconnectAll = true;
1633cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            }
1634cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        }
16351a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt                        final int generation = apnContext.getConnectionGeneration();
16361a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt                        str = "cleanUpConnection: tearing down" + (disconnectAll ? " all" : "") +
16371a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt                                " using gen#" + generation;
16382dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                        if (DBG) log(str + "apnContext=" + apnContext);
16392dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                        apnContext.requestLog(str);
164037cacdfe7ed079d89fb9e80317b5dfd2acb975e5Robert Greenwalt                        Pair<ApnContext, Integer> pair =
16411a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt                                new Pair<ApnContext, Integer>(apnContext, generation);
164237cacdfe7ed079d89fb9e80317b5dfd2acb975e5Robert Greenwalt                        Message msg = obtainMessage(DctConstants.EVENT_DISCONNECT_DONE, pair);
1643cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        if (disconnectAll) {
1644ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                            apnContext.getDcAc().tearDownAll(apnContext.getReason(), msg);
1645cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        } else {
1646ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                            apnContext.getDcAc()
1647cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                .tearDown(apnContext, apnContext.getReason(), msg);
1648cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        }
1649cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        apnContext.setState(DctConstants.State.DISCONNECTING);
1650a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                        mDisconnectPendingCount++;
1651cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    }
1652cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else {
1653cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    // apn is connected but no reference to dcac.
1654cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    // Should not be happen, but reset the state in case.
1655cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnContext.setState(DctConstants.State.IDLE);
16562dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                    apnContext.requestLog("cleanUpConnection: connected, bug no DCAC");
1657cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    mPhone.notifyDataConnection(apnContext.getReason(),
1658cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                                apnContext.getApnType());
1659cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
1660cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1661cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
1662cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // force clean up the data connection.
1663ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (dcac != null) dcac.reqReset();
1664cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            apnContext.setState(DctConstants.State.IDLE);
1665cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
1666cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            apnContext.setDataConnectionAc(null);
1667cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1668cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1669ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        // Make sure reconnection alarm is cleaned up if there is no ApnContext
1670cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // associated to the connection.
1671cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (dcac != null) {
1672ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            cancelReconnectAlarm(apnContext);
1673c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
16742dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt        str = "cleanUpConnection: X tearDown=" + tearDown + " reason=" + apnContext.getReason();
16752dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt        if (DBG) log(str + " apnContext=" + apnContext + " dcac=" + apnContext.getDcAc());
16762dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt        apnContext.requestLog(str);
1677cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1678c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
16791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    ApnSetting fetchDunApn() {
16801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (SystemProperties.getBoolean("net.tethering.noprovisioning", false)) {
16811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            log("fetchDunApn: net.tethering.noprovisioning=true ret: null");
16821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            return null;
16831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
16841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        int bearer = mPhone.getServiceState().getRilDataRadioTechnology();
16851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        ApnSetting retDunSetting = null;
16861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        String apnData = Settings.Global.getString(mResolver, Settings.Global.TETHER_DUN_APN);
16871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        List<ApnSetting> dunSettings = ApnSetting.arrayFromString(apnData);
16881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        IccRecords r = mIccRecords.get();
16891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        for (ApnSetting dunSetting : dunSettings) {
16901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            String operator = (r != null) ? r.getOperatorNumeric() : "";
16911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (!ServiceState.bitmaskHasTech(dunSetting.bearerBitmask, bearer)) continue;
16921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (dunSetting.numeric.equals(operator)) {
16931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (dunSetting.hasMvnoParams()) {
16941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (r != null && ApnSetting.mvnoMatches(r, dunSetting.mvnoType,
16951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            dunSetting.mvnoMatchData)) {
16961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        if (VDBG) {
16971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            log("fetchDunApn: global TETHER_DUN_APN dunSetting=" + dunSetting);
16981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        }
16991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        return dunSetting;
17001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
17011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                } else if (mMvnoMatched == false) {
17021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (VDBG) log("fetchDunApn: global TETHER_DUN_APN dunSetting=" + dunSetting);
17031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    return dunSetting;
17041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
17051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
17061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
17071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
17081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        Context c = mPhone.getContext();
17091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        String[] apnArrayData = c.getResources().getStringArray(R.array.config_tether_apndata);
17101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        for (String apn : apnArrayData) {
17111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            ApnSetting dunSetting = ApnSetting.fromString(apn);
17121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (dunSetting != null) {
17131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (!ServiceState.bitmaskHasTech(dunSetting.bearerBitmask, bearer)) continue;
17141a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (dunSetting.hasMvnoParams()) {
17151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (r != null && ApnSetting.mvnoMatches(r, dunSetting.mvnoType,
17161a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            dunSetting.mvnoMatchData)) {
17171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        if (VDBG) {
17181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            log("fetchDunApn: config_tether_apndata mvno dunSetting=" + dunSetting);
17191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        }
17201a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        return dunSetting;
17211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
17221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                } else if (mMvnoMatched == false) {
17231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    retDunSetting = dunSetting;
17241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
17251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
17261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
17271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
17281a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (VDBG) log("fetchDunApn: config_tether_apndata dunSetting=" + retDunSetting);
17291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        return retDunSetting;
17301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
17311a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
17321a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    public boolean hasMatchedTetherApnSetting() {
17331a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        ApnSetting matched = fetchDunApn();
17341a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        log("hasMatchedTetherApnSetting: APN=" + matched);
17351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        return matched != null;
17361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
17371a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1738cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /**
17391484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt     * Determine if DUN connection is special and we need to teardown on start/stop
17401484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt     */
17411484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt    private boolean teardownForDun() {
17421484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt        // CDMA always needs to do this the profile id is correct
17431484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt        final int rilRat = mPhone.getServiceState().getRilDataRadioTechnology();
17441484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt        if (ServiceState.isCdma(rilRat)) return true;
17451484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt
17461484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt        return (fetchDunApn() != null);
17471484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt    }
17481484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt
17491484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt    /**
1750ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     * Cancels the alarm associated with apnContext.
1751cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *
1752ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     * @param apnContext on which the alarm should be stopped.
1753cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     */
1754ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    private void cancelReconnectAlarm(ApnContext apnContext) {
1755ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (apnContext == null) return;
1756cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1757ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        PendingIntent intent = apnContext.getReconnectIntent();
1758cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1759cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (intent != null) {
1760cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                AlarmManager am =
1761cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    (AlarmManager) mPhone.getContext().getSystemService(Context.ALARM_SERVICE);
1762cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                am.cancel(intent);
1763ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                apnContext.setReconnectIntent(null);
1764cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1765c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1766c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1767cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /**
1768cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @param types comma delimited list of APN types
1769cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @return array of APN types
1770cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     */
1771cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private String[] parseTypes(String types) {
1772c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        String[] result;
1773cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // If unset, set to DEFAULT.
1774cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (types == null || types.equals("")) {
1775c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            result = new String[1];
1776cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            result[0] = PhoneConstants.APN_TYPE_ALL;
1777cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
1778cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            result = types.split(",");
1779c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1780c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        return result;
1781c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1782c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
17831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    boolean isPermanentFail(DcFailCause dcFailCause) {
1784796d3c22f21041116110735c92d7e2c3a7c8f60dAmit Mahajan        return (dcFailCause.isPermanentFail() &&
1785796d3c22f21041116110735c92d7e2c3a7c8f60dAmit Mahajan                (mAttached.get() == false || dcFailCause != DcFailCause.SIGNAL_LOST));
1786796d3c22f21041116110735c92d7e2c3a7c8f60dAmit Mahajan    }
1787796d3c22f21041116110735c92d7e2c3a7c8f60dAmit Mahajan
1788fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi    private ApnSetting makeApnSetting(Cursor cursor) {
1789fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        String[] types = parseTypes(
1790fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.TYPE)));
1791fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        ApnSetting apn = new ApnSetting(
1792fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers._ID)),
1793fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.NUMERIC)),
1794fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.NAME)),
1795fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.APN)),
1796fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                NetworkUtils.trimV4AddrZeros(
1797fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        cursor.getString(
1798fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        cursor.getColumnIndexOrThrow(Telephony.Carriers.PROXY))),
1799fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.PORT)),
1800fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                NetworkUtils.trimV4AddrZeros(
1801fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        cursor.getString(
1802fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        cursor.getColumnIndexOrThrow(Telephony.Carriers.MMSC))),
1803fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                NetworkUtils.trimV4AddrZeros(
1804fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        cursor.getString(
1805fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        cursor.getColumnIndexOrThrow(Telephony.Carriers.MMSPROXY))),
1806fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.MMSPORT)),
1807fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.USER)),
1808fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.PASSWORD)),
18091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.AUTH_TYPE)),
1810fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                types,
1811fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.PROTOCOL)),
1812fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getString(cursor.getColumnIndexOrThrow(
1813fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        Telephony.Carriers.ROAMING_PROTOCOL)),
1814fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                cursor.getInt(cursor.getColumnIndexOrThrow(
1815fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                        Telephony.Carriers.CARRIER_ENABLED)) == 1,
18169d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan                cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.BEARER)),
1817aaf0e8d623b1e94004557573aef9235177ca19e3Amit Mahajan                cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.BEARER_BITMASK)),
18189d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan                cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.PROFILE_ID)),
18199d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan                cursor.getInt(cursor.getColumnIndexOrThrow(
18209d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan                        Telephony.Carriers.MODEM_COGNITIVE)) == 1,
18219d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan                cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.MAX_CONNS)),
18229d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan                cursor.getInt(cursor.getColumnIndexOrThrow(
18239d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan                        Telephony.Carriers.WAIT_TIME)),
1824e9701717e43cc5aacbcf624f77a53be92350662cw                cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.MAX_CONNS_TIME)),
18253262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.MTU)),
18263262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.MVNO_TYPE)),
18273262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.MVNO_MATCH_DATA)));
1828fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        return apn;
1829fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi    }
1830fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi
1831cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private ArrayList<ApnSetting> createApnList(Cursor cursor) {
18323262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal        ArrayList<ApnSetting> mnoApns = new ArrayList<ApnSetting>();
18333262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal        ArrayList<ApnSetting> mvnoApns = new ArrayList<ApnSetting>();
1834fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi        IccRecords r = mIccRecords.get();
1835fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi
1836cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (cursor.moveToFirst()) {
1837cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            do {
18383262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                ApnSetting apn = makeApnSetting(cursor);
18393262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                if (apn == null) {
18403262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                    continue;
18413262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                }
18423262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal
18433262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                if (apn.hasMvnoParams()) {
184463913dc903872c45bab7d2483d633d845dd9c5d6Amit Mahajan                    if (r != null && ApnSetting.mvnoMatches(r, apn.mvnoType, apn.mvnoMatchData)) {
18453262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                        mvnoApns.add(apn);
1846fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                    }
1847fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                } else {
18483262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                    mnoApns.add(apn);
1849fd5de4dae153c57e13bf8979d6f7a8aa86e3dedeSungmin Choi                }
1850cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } while (cursor.moveToNext());
1851cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
18523262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal
18531a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        ArrayList<ApnSetting> result;
18541a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (mvnoApns.isEmpty()) {
18551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            result = mnoApns;
18561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mMvnoMatched = false;
18571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else {
18581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            result = mvnoApns;
18591a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mMvnoMatched = true;
18601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
1861cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("createApnList: X result=" + result);
1862c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        return result;
1863c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1864c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1865454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville    private boolean dataConnectionNotInUse(DcAsyncChannel dcac) {
1866ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (DBG) log("dataConnectionNotInUse: check if dcac is inuse dcac=" + dcac);
1867cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (ApnContext apnContext : mApnContexts.values()) {
1868ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (apnContext.getDcAc() == dcac) {
1869cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) log("dataConnectionNotInUse: in use by apnContext=" + apnContext);
1870cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return false;
1871cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1872cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1873cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // TODO: Fix retry handling so free DataConnections have empty apnlists.
1874cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // Probably move retry handling into DataConnections and reduce complexity
1875cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // of DCT.
1876cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("dataConnectionNotInUse: tearDownAll");
1877ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        dcac.tearDownAll("No connection", null);
1878cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("dataConnectionNotInUse: not in use return true");
1879cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return true;
1880cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1881cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1882454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville    private DcAsyncChannel findFreeDataConnection() {
1883454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville        for (DcAsyncChannel dcac : mDataConnectionAcHashMap.values()) {
1884cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (dcac.isInactiveSync() && dataConnectionNotInUse(dcac)) {
1885cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) {
1886cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    log("findFreeDataConnection: found free DataConnection=" +
1887ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                        " dcac=" + dcac);
1888cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
1889ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                return dcac;
1890cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1891cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1892cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        log("findFreeDataConnection: NO free DataConnection");
1893cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return null;
1894cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1895cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1896203e588e3c42a81aa8a56f595119c181a63b12caWink Saville    private boolean setupData(ApnContext apnContext, int radioTech) {
1897cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("setupData: apnContext=" + apnContext);
18982dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt        apnContext.requestLog("setupData");
1899ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        ApnSetting apnSetting;
19001484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt        DcAsyncChannel dcac = null;
1901cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
19020e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu        apnSetting = apnContext.getNextApnSetting();
19030e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu
1904ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (apnSetting == null) {
1905cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("setupData: return for no apn found!");
1906cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return false;
1907cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1908cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1909231c3c6271a27b5f03444f4d24b52c41c46566abEtan Cohen        int profileId = apnSetting.profileId;
1910231c3c6271a27b5f03444f4d24b52c41c46566abEtan Cohen        if (profileId == 0) {
1911231c3c6271a27b5f03444f4d24b52c41c46566abEtan Cohen            profileId = getApnProfileID(apnContext.getApnType());
1912231c3c6271a27b5f03444f4d24b52c41c46566abEtan Cohen        }
1913231c3c6271a27b5f03444f4d24b52c41c46566abEtan Cohen
19141484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt        // On CDMA, if we're explicitly asking for DUN, we need have
19151484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt        // a dun-profiled connection so we can't share an existing one
19161484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt        // On GSM/LTE we can share existing apn connections provided they support
19171484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt        // this type.
19181484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt        if (apnContext.getApnType() != PhoneConstants.APN_TYPE_DUN ||
19191484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                teardownForDun() == false) {
19201484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt            dcac = checkForCompatibleConnectedApnContext(apnContext);
19211484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt            if (dcac != null) {
19221484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                // Get the dcacApnSetting for the connection we want to share.
19231484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                ApnSetting dcacApnSetting = dcac.getApnSettingSync();
19241484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                if (dcacApnSetting != null) {
19251484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                    // Setting is good, so use it.
19261484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                    apnSetting = dcacApnSetting;
19271484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                }
1928ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            }
1929ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        }
1930ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (dcac == null) {
19313fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            if (isOnlySingleDcAllowed(radioTech)) {
19323fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                if (isHigherPriorityApnContextActive(apnContext)) {
19333fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    if (DBG) {
19343fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                        log("setupData: Higher priority ApnContext active.  Ignoring call");
19353fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    }
19363fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    return false;
19373fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                }
19383fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt
19393fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                // Only lower priority calls left.  Disconnect them all in this single PDP case
19403fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                // so that we can bring up the requested higher priority call (once we receive
19410e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                // response for deactivate request for the calls we are about to disconnect
19423fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                if (cleanUpAllConnections(true, Phone.REASON_SINGLE_PDN_ARBITRATION)) {
19433fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    // If any call actually requested to be disconnected, means we can't
19443fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    // bring up this connection yet as we need to wait for those data calls
19453fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    // to be disconnected.
19463fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    if (DBG) log("setupData: Some calls are disconnecting first.  Wait and retry");
19473fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    return false;
19483fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                }
19493fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt
19503fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                // No other calls are active, so proceed
19513fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                if (DBG) log("setupData: Single pdp. Continue setting up data call.");
19523fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            }
19533fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt
1954ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            dcac = findFreeDataConnection();
1955cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1956ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (dcac == null) {
1957ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                dcac = createDataConnection();
1958cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1959cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1960ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (dcac == null) {
1961ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                if (DBG) log("setupData: No free DataConnection and couldn't create one, WEIRD");
1962cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return false;
1963cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1964cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
19651a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt        final int generation = apnContext.incAndGetConnectionGeneration();
19661a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt        if (DBG) {
19671a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt            log("setupData: dcac=" + dcac + " apnSetting=" + apnSetting + " gen#=" + generation);
19681a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt        }
1969cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1970cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        apnContext.setDataConnectionAc(dcac);
1971ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        apnContext.setApnSetting(apnSetting);
1972cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        apnContext.setState(DctConstants.State.CONNECTING);
1973cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
1974cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1975cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        Message msg = obtainMessage();
1976cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        msg.what = DctConstants.EVENT_DATA_SETUP_COMPLETE;
19771a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt        msg.obj = new Pair<ApnContext, Integer>(apnContext, generation);
19780e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu        dcac.bringUp(apnContext, profileId, radioTech, msg, generation);
1979cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1980cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("setupData: initing!");
1981cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return true;
1982cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1983cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
19841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void setInitialAttachApn() {
19851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        ApnSetting iaApnSetting = null;
19861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        ApnSetting defaultApnSetting = null;
19871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        ApnSetting firstApnSetting = null;
19881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
19891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        log("setInitialApn: E mPreferredApn=" + mPreferredApn);
19901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
19911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (mAllApnSettings != null && !mAllApnSettings.isEmpty()) {
19921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            firstApnSetting = mAllApnSettings.get(0);
19931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            log("setInitialApn: firstApnSetting=" + firstApnSetting);
19941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
19951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            // Search for Initial APN setting and the first apn that can handle default
19961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            for (ApnSetting apn : mAllApnSettings) {
19971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                // Can't use apn.canHandleType(), as that returns true for APNs that have no type.
19981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (ArrayUtils.contains(apn.types, PhoneConstants.APN_TYPE_IA) &&
19991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        apn.carrierEnabled) {
20001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    // The Initial Attach APN is highest priority so use it if there is one
20011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    log("setInitialApn: iaApnSetting=" + apn);
20021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    iaApnSetting = apn;
20031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    break;
20041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                } else if ((defaultApnSetting == null)
20051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        && (apn.canHandleType(PhoneConstants.APN_TYPE_DEFAULT))) {
20061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    // Use the first default apn if no better choice
20071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    log("setInitialApn: defaultApnSetting=" + apn);
20081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    defaultApnSetting = apn;
20091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
20101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
20111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
20121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
20131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        // The priority of apn candidates from highest to lowest is:
20140e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu        //   1) APN_TYPE_IA (Initial Attach)
20151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        //   2) mPreferredApn, i.e. the current preferred apn
20161a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        //   3) The first apn that than handle APN_TYPE_DEFAULT
20171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        //   4) The first APN we can find.
20181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
20191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        ApnSetting initialAttachApnSetting = null;
20201a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (iaApnSetting != null) {
20211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) log("setInitialAttachApn: using iaApnSetting");
20221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            initialAttachApnSetting = iaApnSetting;
20231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else if (mPreferredApn != null) {
20241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) log("setInitialAttachApn: using mPreferredApn");
20251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            initialAttachApnSetting = mPreferredApn;
20261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else if (defaultApnSetting != null) {
20271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) log("setInitialAttachApn: using defaultApnSetting");
20281a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            initialAttachApnSetting = defaultApnSetting;
20291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else if (firstApnSetting != null) {
20301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) log("setInitialAttachApn: using firstApnSetting");
20311a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            initialAttachApnSetting = firstApnSetting;
20321a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
20331a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
20341a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (initialAttachApnSetting == null) {
20351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) log("setInitialAttachApn: X There in no available apn");
20361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else {
20371a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) log("setInitialAttachApn: X selected Apn=" + initialAttachApnSetting);
20381a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
20391a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mPhone.mCi.setInitialAttachApn(initialAttachApnSetting.apn,
20401a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    initialAttachApnSetting.protocol, initialAttachApnSetting.authType,
20411a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    initialAttachApnSetting.user, initialAttachApnSetting.password, null);
20421a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
20431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
20441a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2045c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
2046cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Handles changes to the APN database.
2047c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
2048cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private void onApnChanged() {
2049cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        DctConstants.State overallState = getOverallState();
2050cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean isDisconnected = (overallState == DctConstants.State.IDLE ||
2051cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                overallState == DctConstants.State.FAILED);
2052cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
20531a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (mPhone instanceof GsmCdmaPhone) {
2054cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // The "current" may no longer be valid.  MMS depends on this to send properly. TBD
20551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            ((GsmCdmaPhone)mPhone).updateCurrentCarrierInProvider();
2056cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2057cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2058cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // TODO: It'd be nice to only do this if the changed entrie(s)
2059cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // match the current operator.
2060cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onApnChanged: createAllApnList and cleanUpAllConnections");
2061cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        createAllApnList();
20625d5eea6ed231163c225144316b0d1913d48678a4Sungmin Choi        setInitialAttachApn();
20639a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang        cleanUpConnectionsOnUpdatedApns(!isDisconnected);
2064bda761320929f714951c328bfec6a51a1978db97Wink Saville
20658f6f52e4f7598e44cea1f9e5f4781291f9060d1dWink Saville        // FIXME: See bug 17426028 maybe no conditional is needed.
206638ca51d0f643405df51e78fce6c546424e9f410dShishir Agrawal        if (mPhone.getSubId() == SubscriptionManager.getDefaultDataSubscriptionId()) {
2067ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            setupDataOnConnectableApns(Phone.REASON_APN_CHANGED);
2068c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
2069c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
2070c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
2071c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
2072cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @param cid Connection id provided from RIL.
2073cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @return DataConnectionAc associated with specified cid.
2074c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
2075454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville    private DcAsyncChannel findDataConnectionAcByCid(int cid) {
2076454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville        for (DcAsyncChannel dcac : mDataConnectionAcHashMap.values()) {
2077cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (dcac.getCidSync() == cid) {
2078cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return dcac;
2079cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
2080c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
2081cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return null;
2082c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
2083c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
2084cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // TODO: For multiple Active APNs not exactly sure how to do this.
20851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void gotoIdleAndNotifyDataConnection(String reason) {
2086cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("gotoIdleAndNotifyDataConnection: reason=" + reason);
2087cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        notifyDataConnection(reason);
2088cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2089cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
20903fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt    /**
20913fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     * "Active" here means ApnContext isEnabled() and not in FAILED state
20923fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     * @param apnContext to compare with
20933fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     * @return true if higher priority active apn found
20943fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     */
20953fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt    private boolean isHigherPriorityApnContextActive(ApnContext apnContext) {
20963fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        for (ApnContext otherContext : mPrioritySortedApnContexts) {
20973fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            if (apnContext.getApnType().equalsIgnoreCase(otherContext.getApnType())) return false;
20983fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            if (otherContext.isEnabled() && otherContext.getState() != DctConstants.State.FAILED) {
20993fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                return true;
21003fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            }
21013fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        }
21023fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        return false;
21033fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt    }
21043fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt
21053fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt    /**
21063fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     * Reports if we support multiple connections or not.
21073fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     * This is a combination of factors, based on carrier and RAT.
21083fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     * @param rilRadioTech the RIL Radio Tech currently in use
21093fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     * @return true if only single DataConnection is allowed
21103fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     */
21113fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt    private boolean isOnlySingleDcAllowed(int rilRadioTech) {
21123fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        int[] singleDcRats = mPhone.getContext().getResources().getIntArray(
21133fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                com.android.internal.R.array.config_onlySingleDcAllowed);
21143fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        boolean onlySingleDcAllowed = false;
21153fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        if (Build.IS_DEBUGGABLE &&
21163fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                SystemProperties.getBoolean("persist.telephony.test.singleDc", false)) {
21173fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            onlySingleDcAllowed = true;
21183fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        }
21193fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        if (singleDcRats != null) {
21203fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            for (int i=0; i < singleDcRats.length && onlySingleDcAllowed == false; i++) {
21213fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                if (rilRadioTech == singleDcRats[i]) onlySingleDcAllowed = true;
21223fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            }
21233fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        }
21243fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt
21253fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        if (DBG) log("isOnlySingleDcAllowed(" + rilRadioTech + "): " + onlySingleDcAllowed);
21263fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        return onlySingleDcAllowed;
21273fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt    }
21283fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt
21291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    void sendRestartRadio() {
21301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (DBG)log("sendRestartRadio:");
21311a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        Message msg = obtainMessage(DctConstants.EVENT_RESTART_RADIO);
21321a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        sendMessage(msg);
21331a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
21341a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
21351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void restartRadio() {
2136cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("restartRadio: ************TURN OFF RADIO**************");
2137cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        cleanUpAllConnections(true, Phone.REASON_RADIO_TURNED_OFF);
2138cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mPhone.getServiceStateTracker().powerOffRadioSafely(this);
2139cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        /* Note: no need to call setRadioPower(true).  Assuming the desired
2140cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville         * radio power state is still ON (as tracked by ServiceStateTracker),
2141cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville         * ServiceStateTracker will call setRadioPower when it receives the
2142cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville         * RADIO_STATE_CHANGED notification for the power off.  And if the
2143cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville         * desired power state has changed in the interim, we don't want to
2144cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville         * override it with an unconditional power on.
2145cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville         */
2146cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2147cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        int reset = Integer.parseInt(SystemProperties.get("net.ppp.reset-by-timeout", "0"));
21480e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu        SystemProperties.set("net.ppp.reset-by-timeout", String.valueOf(reset + 1));
2149cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2150cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2151cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /**
2152cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Return true if data connection need to be setup after disconnected due to
2153cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * reason.
2154cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *
21550e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu     * @param apnContext APN context
2156cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @return true if try setup data connection is need for this reason
2157cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     */
21583fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt    private boolean retryAfterDisconnected(ApnContext apnContext) {
2159cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean retry = true;
21603fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        String reason = apnContext.getReason();
2161cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
21623fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        if ( Phone.REASON_RADIO_TURNED_OFF.equals(reason) ||
21633fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                (isOnlySingleDcAllowed(mPhone.getServiceState().getRilDataRadioTechnology())
21643fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                 && isHigherPriorityApnContextActive(apnContext))) {
2165cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            retry = false;
2166cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2167cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return retry;
2168cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2169cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
21700e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu    private void startAlarmForReconnect(long delay, ApnContext apnContext) {
2171cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        String apnType = apnContext.getApnType();
217274672e8ee972f12406b72551261b4cc7e0651933Wink Saville
217374672e8ee972f12406b72551261b4cc7e0651933Wink Saville        Intent intent = new Intent(INTENT_RECONNECT_ALARM + "." + apnType);
217474672e8ee972f12406b72551261b4cc7e0651933Wink Saville        intent.putExtra(INTENT_RECONNECT_ALARM_EXTRA_REASON, apnContext.getReason());
2175cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        intent.putExtra(INTENT_RECONNECT_ALARM_EXTRA_TYPE, apnType);
217667d43cfed4b996c20780bfec8fde1ae8c1391779Junda Liu        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
2177cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2178a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        // Get current sub id.
217938ca51d0f643405df51e78fce6c546424e9f410dShishir Agrawal        int subId = SubscriptionManager.getDefaultDataSubscriptionId();
2180a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        intent.putExtra(PhoneConstants.SUBSCRIPTION_KEY, subId);
2181a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
218274672e8ee972f12406b72551261b4cc7e0651933Wink Saville        if (DBG) {
218374672e8ee972f12406b72551261b4cc7e0651933Wink Saville            log("startAlarmForReconnect: delay=" + delay + " action=" + intent.getAction()
218474672e8ee972f12406b72551261b4cc7e0651933Wink Saville                    + " apn=" + apnContext);
218574672e8ee972f12406b72551261b4cc7e0651933Wink Saville        }
218674672e8ee972f12406b72551261b4cc7e0651933Wink Saville
21870e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu        PendingIntent alarmIntent = PendingIntent.getBroadcast(mPhone.getContext(), 0,
2188cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                        intent, PendingIntent.FLAG_UPDATE_CURRENT);
2189ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        apnContext.setReconnectIntent(alarmIntent);
21907d6d7d6cb68ee37b4bee33588ba2594e9cf0c197Jack Yu
21917d6d7d6cb68ee37b4bee33588ba2594e9cf0c197Jack Yu        // Use the exact timer instead of the inexact one to provide better user experience.
21927d6d7d6cb68ee37b4bee33588ba2594e9cf0c197Jack Yu        // In some extreme cases, we saw the retry was delayed for few minutes.
21937d6d7d6cb68ee37b4bee33588ba2594e9cf0c197Jack Yu        mAlarmManager.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP,
2194cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                SystemClock.elapsedRealtime() + delay, alarmIntent);
2195cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2196cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2197ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    private void notifyNoData(DcFailCause lastFailCauseCode,
2198cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                              ApnContext apnContext) {
2199cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log( "notifyNoData: type=" + apnContext.getApnType());
2200796d3c22f21041116110735c92d7e2c3a7c8f60dAmit Mahajan        if (isPermanentFail(lastFailCauseCode)
2201cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            && (!apnContext.getApnType().equals(PhoneConstants.APN_TYPE_DEFAULT))) {
2202cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            mPhone.notifyDataConnectionFailed(apnContext.getReason(), apnContext.getApnType());
2203cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2204cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2205cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
22061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    public boolean getAutoAttachOnCreation() {
22071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        return mAutoAttachOnCreation.get();
22081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
22091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
22101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onRecordsLoadedOrSubIdChanged() {
22111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (DBG) log("onRecordsLoadedOrSubIdChanged: createAllApnList");
221212fffcf0d8df6b8268806d9aa7cc7a662e73743bJing Zhao        mAutoAttachOnCreationConfig = mPhone.getContext().getResources()
221312fffcf0d8df6b8268806d9aa7cc7a662e73743bJing Zhao                .getBoolean(com.android.internal.R.bool.config_auto_attach_data_on_creation);
2214bda761320929f714951c328bfec6a51a1978db97Wink Saville
2215cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        createAllApnList();
22165d5eea6ed231163c225144316b0d1913d48678a4Sungmin Choi        setInitialAttachApn();
221722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mPhone.mCi.getRadioState().isOn()) {
22181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) log("onRecordsLoadedOrSubIdChanged: notifying data availability");
2219cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyOffApnsOfAvailability(Phone.REASON_SIM_LOADED);
2220cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2221bda761320929f714951c328bfec6a51a1978db97Wink Saville        setupDataOnConnectableApns(Phone.REASON_SIM_LOADED);
2222cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2223cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
22240469925aace7a2254e0cef90bd7398fbd72622faShishir Agrawal    private void onSimNotReady() {
22250469925aace7a2254e0cef90bd7398fbd72622faShishir Agrawal        if (DBG) log("onSimNotReady");
22260469925aace7a2254e0cef90bd7398fbd72622faShishir Agrawal
22270469925aace7a2254e0cef90bd7398fbd72622faShishir Agrawal        cleanUpAllConnections(true, Phone.REASON_SIM_NOT_READY);
22280469925aace7a2254e0cef90bd7398fbd72622faShishir Agrawal        mAllApnSettings = null;
22290469925aace7a2254e0cef90bd7398fbd72622faShishir Agrawal        mAutoAttachOnCreationConfig = false;
22300469925aace7a2254e0cef90bd7398fbd72622faShishir Agrawal    }
22310469925aace7a2254e0cef90bd7398fbd72622faShishir Agrawal
22321a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onSetDependencyMet(String apnType, boolean met) {
2233cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // don't allow users to tweak hipri to work around default dependency not met
2234cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (PhoneConstants.APN_TYPE_HIPRI.equals(apnType)) return;
2235cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2236cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ApnContext apnContext = mApnContexts.get(apnType);
2237cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext == null) {
2238cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            loge("onSetDependencyMet: ApnContext not found in onSetDependencyMet(" +
2239cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnType + ", " + met + ")");
2240cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return;
2241cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2242cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        applyNewState(apnContext, apnContext.isEnabled(), met);
2243cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (PhoneConstants.APN_TYPE_DEFAULT.equals(apnType)) {
2244cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // tie actions on default to similar actions on HIPRI regarding dependencyMet
2245cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            apnContext = mApnContexts.get(PhoneConstants.APN_TYPE_HIPRI);
2246cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (apnContext != null) applyNewState(apnContext, apnContext.isEnabled(), met);
2247cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2248cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2249c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
22501a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onSetPolicyDataEnabled(boolean enabled) {
22511a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        synchronized (mDataEnabledLock) {
22521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            final boolean prevEnabled = getAnyDataEnabled();
22531a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (sPolicyDataEnabled != enabled) {
22541a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                sPolicyDataEnabled = enabled;
22551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (prevEnabled != getAnyDataEnabled()) {
22561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (!prevEnabled) {
22571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        onTrySetupData(Phone.REASON_DATA_ENABLED);
22581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    } else {
22591a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        onCleanUpAllConnections(Phone.REASON_DATA_SPECIFIC_DISABLED);
22601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
22611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
22621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
22631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
22641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
22651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
22661a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2267cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private void applyNewState(ApnContext apnContext, boolean enabled, boolean met) {
2268cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean cleanup = false;
2269cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean trySetup = false;
22702dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt        String str ="applyNewState(" + apnContext.getApnType() + ", " + enabled +
22712dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                "(" + apnContext.isEnabled() + "), " + met + "(" +
22722dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                apnContext.getDependencyMet() +"))";
22732dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt        if (DBG) log(str);
22742dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt        apnContext.requestLog(str);
22752dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt
2276cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext.isReady()) {
2277305122cd621385652826cf7d8cd4e651dc6b5e9fRobert Greenwalt            cleanup = true;
22782428693913ae731d4ace3414429f5e91af24ea36Wink Saville            if (enabled && met) {
22792428693913ae731d4ace3414429f5e91af24ea36Wink Saville                DctConstants.State state = apnContext.getState();
22802428693913ae731d4ace3414429f5e91af24ea36Wink Saville                switch(state) {
22812428693913ae731d4ace3414429f5e91af24ea36Wink Saville                    case CONNECTING:
22822428693913ae731d4ace3414429f5e91af24ea36Wink Saville                    case SCANNING:
22832428693913ae731d4ace3414429f5e91af24ea36Wink Saville                    case CONNECTED:
22842428693913ae731d4ace3414429f5e91af24ea36Wink Saville                    case DISCONNECTING:
22852428693913ae731d4ace3414429f5e91af24ea36Wink Saville                        // We're "READY" and active so just return
22862428693913ae731d4ace3414429f5e91af24ea36Wink Saville                        if (DBG) log("applyNewState: 'ready' so return");
22872dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt                        apnContext.requestLog("applyNewState state=" + state + ", so return");
22882428693913ae731d4ace3414429f5e91af24ea36Wink Saville                        return;
22892428693913ae731d4ace3414429f5e91af24ea36Wink Saville                    case IDLE:
22902428693913ae731d4ace3414429f5e91af24ea36Wink Saville                        // fall through: this is unexpected but if it happens cleanup and try setup
22912428693913ae731d4ace3414429f5e91af24ea36Wink Saville                    case FAILED:
22922428693913ae731d4ace3414429f5e91af24ea36Wink Saville                    case RETRYING: {
22932428693913ae731d4ace3414429f5e91af24ea36Wink Saville                        // We're "READY" but not active so disconnect (cleanup = true) and
22942428693913ae731d4ace3414429f5e91af24ea36Wink Saville                        // connect (trySetup = true) to be sure we retry the connection.
22952428693913ae731d4ace3414429f5e91af24ea36Wink Saville                        trySetup = true;
22962428693913ae731d4ace3414429f5e91af24ea36Wink Saville                        apnContext.setReason(Phone.REASON_DATA_ENABLED);
22972428693913ae731d4ace3414429f5e91af24ea36Wink Saville                        break;
22982428693913ae731d4ace3414429f5e91af24ea36Wink Saville                    }
22992428693913ae731d4ace3414429f5e91af24ea36Wink Saville                }
2300305122cd621385652826cf7d8cd4e651dc6b5e9fRobert Greenwalt            } else if (met) {
2301cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                apnContext.setReason(Phone.REASON_DATA_DISABLED);
2302305122cd621385652826cf7d8cd4e651dc6b5e9fRobert Greenwalt                // If ConnectivityService has disabled this network, stop trying to bring
2303305122cd621385652826cf7d8cd4e651dc6b5e9fRobert Greenwalt                // it up, but do not tear it down - ConnectivityService will do that
2304305122cd621385652826cf7d8cd4e651dc6b5e9fRobert Greenwalt                // directly by talking with the DataConnection.
23051484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                //
23061484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                // This doesn't apply to DUN, however.  Those connections have special
23071484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                // requirements from carriers and we need stop using them when the dun
23081484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                // request goes away.  This applies to both CDMA and GSM because they both
23091484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                // can declare the DUN APN sharable by default traffic, thus still satisfying
23101484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                // those requests and not torn down organically.
23111484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                if (apnContext.getApnType() == PhoneConstants.APN_TYPE_DUN && teardownForDun()) {
23121484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                    cleanup = true;
23131484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                } else {
23141484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                    cleanup = false;
23151484bfe9c58cfd2ddf59a5b8dad7373a36de946dRobert Greenwalt                }
2316cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } else {
2317cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                apnContext.setReason(Phone.REASON_DATA_DEPENDENCY_UNMET);
2318cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
2319cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
2320cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (enabled && met) {
2321cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (apnContext.isEnabled()) {
2322cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnContext.setReason(Phone.REASON_DATA_DEPENDENCY_MET);
2323cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else {
2324cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnContext.setReason(Phone.REASON_DATA_ENABLED);
2325c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
2326cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (apnContext.getState() == DctConstants.State.FAILED) {
2327cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnContext.setState(DctConstants.State.IDLE);
2328cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
2329cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                trySetup = true;
2330cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
2331cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2332cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        apnContext.setEnabled(enabled);
2333cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        apnContext.setDependencyMet(met);
2334cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (cleanup) cleanUpConnection(true, apnContext);
23350d2abb5518d6a86619d2c2db04867c338b2092d4Robert Greenwalt        if (trySetup) {
23360d2abb5518d6a86619d2c2db04867c338b2092d4Robert Greenwalt            apnContext.resetErrorCodeRetries();
23370d2abb5518d6a86619d2c2db04867c338b2092d4Robert Greenwalt            trySetupData(apnContext);
23380d2abb5518d6a86619d2c2db04867c338b2092d4Robert Greenwalt        }
2339cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2340c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
2341454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville    private DcAsyncChannel checkForCompatibleConnectedApnContext(ApnContext apnContext) {
2342cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        String apnType = apnContext.getApnType();
2343cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ApnSetting dunSetting = null;
2344cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2345cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (PhoneConstants.APN_TYPE_DUN.equals(apnType)) {
2346cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            dunSetting = fetchDunApn();
2347cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2348ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (DBG) {
2349ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            log("checkForCompatibleConnectedApnContext: apnContext=" + apnContext );
2350ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        }
2351cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2352454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville        DcAsyncChannel potentialDcac = null;
2353ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        ApnContext potentialApnCtx = null;
2354ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        for (ApnContext curApnCtx : mApnContexts.values()) {
2355454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville            DcAsyncChannel curDcac = curApnCtx.getDcAc();
2356ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (curDcac != null) {
2357ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                ApnSetting apnSetting = curApnCtx.getApnSetting();
2358a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                log("apnSetting: " + apnSetting);
2359cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (dunSetting != null) {
2360cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    if (dunSetting.equals(apnSetting)) {
2361ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                        switch (curApnCtx.getState()) {
2362cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            case CONNECTED:
2363cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                if (DBG) {
2364ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                    log("checkForCompatibleConnectedApnContext:"
2365ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                            + " found dun conn=" + curDcac
2366ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                            + " curApnCtx=" + curApnCtx);
2367cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                }
2368ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                return curDcac;
2369ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                            case RETRYING:
2370cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            case CONNECTING:
2371ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                potentialDcac = curDcac;
2372ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                potentialApnCtx = curApnCtx;
2373cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            default:
2374cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                // Not connected, potential unchanged
2375cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                break;
2376cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        }
2377cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    }
2378cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else if (apnSetting != null && apnSetting.canHandleType(apnType)) {
2379ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                    switch (curApnCtx.getState()) {
2380cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        case CONNECTED:
2381cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            if (DBG) {
2382ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                log("checkForCompatibleConnectedApnContext:"
2383ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                        + " found canHandle conn=" + curDcac
2384ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                        + " curApnCtx=" + curApnCtx);
2385cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            }
2386ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                            return curDcac;
2387ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                        case RETRYING:
2388cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        case CONNECTING:
2389ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                            potentialDcac = curDcac;
2390ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                            potentialApnCtx = curApnCtx;
2391cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        default:
2392cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            // Not connected, potential unchanged
2393cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            break;
2394cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    }
2395cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
2396ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            } else {
2397ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                if (VDBG) {
2398ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                    log("checkForCompatibleConnectedApnContext: not conn curApnCtx=" + curApnCtx);
2399ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                }
2400cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
2401cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2402ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (potentialDcac != null) {
2403cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) {
2404ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                log("checkForCompatibleConnectedApnContext: found potential conn=" + potentialDcac
2405ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                        + " curApnCtx=" + potentialApnCtx);
2406cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
2407ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            return potentialDcac;
2408cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2409c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
2410ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (DBG) log("checkForCompatibleConnectedApnContext: NO conn apnContext=" + apnContext);
2411cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return null;
2412cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2413c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
241427b650c406018355a88a41528db7859e232728a0Jack Yu    public void setEnabled(int id, boolean enable) {
24151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        Message msg = obtainMessage(DctConstants.EVENT_ENABLE_NEW_APN);
24161a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        msg.arg1 = id;
24171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        msg.arg2 = (enable ? DctConstants.ENABLED : DctConstants.DISABLED);
24181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        sendMessage(msg);
24191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
24201a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
24211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onEnableApn(int apnId, int enabled) {
2422af5593594070f825032be46dced573cd195956e1Robert Greenwalt        ApnContext apnContext = mApnContextsById.get(apnId);
2423cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext == null) {
2424cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            loge("onEnableApn(" + apnId + ", " + enabled + "): NO ApnContext");
2425cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return;
2426cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2427cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // TODO change our retry manager to use the appropriate numbers for the new APN
2428cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onEnableApn: apnContext=" + apnContext + " call applyNewState");
2429cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        applyNewState(apnContext, enabled == DctConstants.ENABLED, apnContext.getDependencyMet());
2430cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2431c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
2432cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // TODO: We shouldnt need this.
24331a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean onTrySetupData(String reason) {
2434cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onTrySetupData: reason=" + reason);
2435ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        setupDataOnConnectableApns(reason);
2436cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return true;
2437cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2438c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
24391a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean onTrySetupData(ApnContext apnContext) {
2440cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onTrySetupData: apnContext=" + apnContext);
2441cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return trySetupData(apnContext);
2442cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2443c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
24441a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /**
24451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * Return current {@link android.provider.Settings.Global#MOBILE_DATA} value.
24461a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     */
24471a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    public boolean getDataEnabled() {
24481a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        boolean retVal = "true".equalsIgnoreCase(SystemProperties.get(
24491a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                "ro.com.android.mobiledata", "true"));
24501a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        try {
24511a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (TelephonyManager.getDefault().getSimCount() == 1) {
24521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                retVal = Settings.Global.getInt(mResolver, Settings.Global.MOBILE_DATA,
24531a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        retVal ? 1 : 0) != 0;
24541a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else {
24551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                int phoneSubId = mPhone.getSubId();
24561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                retVal = TelephonyManager.getIntWithSubId(mResolver, Settings.Global.MOBILE_DATA,
24571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        phoneSubId) != 0;
24581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
2459092e6bd60f1a4a3a55fb73ad0efca1122b8e15e2Jack Yu            if (VDBG) log("getDataEnabled: getIntWithSubId retVal=" + retVal);
24601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } catch (SettingNotFoundException snfe) {
24611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            retVal = "true".equalsIgnoreCase(
24621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    SystemProperties.get("ro.com.android.mobiledata", "true"));
24631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) {
24641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                log("getDataEnabled: system property ro.com.android.mobiledata retVal=" + retVal);
24651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
24661a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
24671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        return retVal;
24681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
24691a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
24701a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /**
24711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * Modify {@link android.provider.Settings.Global#DATA_ROAMING} value.
24721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     */
24731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    public void setDataOnRoamingEnabled(boolean enabled) {
24741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        final int phoneSubId = mPhone.getSubId();
24751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (getDataOnRoamingEnabled() != enabled) {
24761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            int roaming = enabled ? 1 : 0;
24771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
24781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            // For single SIM phones, this is a per phone property.
24791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (TelephonyManager.getDefault().getSimCount() == 1) {
24801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                Settings.Global.putInt(mResolver, Settings.Global.DATA_ROAMING, roaming);
24811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else {
24821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                Settings.Global.putInt(mResolver, Settings.Global.DATA_ROAMING +
24831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                         phoneSubId, roaming);
24841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
24851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
24861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mSubscriptionManager.setDataRoaming(roaming, phoneSubId);
24871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            // will trigger handleDataOnRoamingChange() through observer
24881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) {
24891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu               log("setDataOnRoamingEnabled: set phoneSubId=" + phoneSubId
24901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                       + " isRoaming=" + enabled);
24911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
24921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else {
24931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) {
24941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                log("setDataOnRoamingEnabled: unchanged phoneSubId=" + phoneSubId
24951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        + " isRoaming=" + enabled);
24961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu             }
24971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
24981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
24991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
25001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /**
25011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * Return current {@link android.provider.Settings.Global#DATA_ROAMING} value.
25021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     */
25031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    public boolean getDataOnRoamingEnabled() {
25041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        boolean isDataRoamingEnabled = "true".equalsIgnoreCase(SystemProperties.get(
25051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                "ro.com.android.dataroaming", "false"));
25061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        final int phoneSubId = mPhone.getSubId();
25071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
25081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        try {
25091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            // For single SIM phones, this is a per phone property.
25101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (TelephonyManager.getDefault().getSimCount() == 1) {
25111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                isDataRoamingEnabled = Settings.Global.getInt(mResolver,
25121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        Settings.Global.DATA_ROAMING, isDataRoamingEnabled ? 1 : 0) != 0;
25131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else {
25141a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                isDataRoamingEnabled = TelephonyManager.getIntWithSubId(mResolver,
25151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        Settings.Global.DATA_ROAMING, phoneSubId) != 0;
25161a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
25171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } catch (SettingNotFoundException snfe) {
25181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) log("getDataOnRoamingEnabled: SettingNofFoundException snfe=" + snfe);
25191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
25201a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (VDBG) {
25211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            log("getDataOnRoamingEnabled: phoneSubId=" + phoneSubId +
25221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    " isDataRoamingEnabled=" + isDataRoamingEnabled);
25231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
25241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        return isDataRoamingEnabled;
25251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
25261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
25271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onRoamingOff() {
2528cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onRoamingOff");
2529c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
25306bc4098827f3070a44b5e51508b455d7c7be9c07Wink Saville        if (!mUserDataEnabled) return;
2531c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
2532bda761320929f714951c328bfec6a51a1978db97Wink Saville        if (getDataOnRoamingEnabled() == false) {
2533cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyOffApnsOfAvailability(Phone.REASON_ROAMING_OFF);
2534bda761320929f714951c328bfec6a51a1978db97Wink Saville            setupDataOnConnectableApns(Phone.REASON_ROAMING_OFF);
2535cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
2536cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyDataConnection(Phone.REASON_ROAMING_OFF);
2537cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2538cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2539cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
25401a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onRoamingOn() {
25416bc4098827f3070a44b5e51508b455d7c7be9c07Wink Saville        if (DBG) log("onRoamingOn");
2542bda761320929f714951c328bfec6a51a1978db97Wink Saville
25436bc4098827f3070a44b5e51508b455d7c7be9c07Wink Saville        if (!mUserDataEnabled) return;
2544cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2545bda761320929f714951c328bfec6a51a1978db97Wink Saville        if (getDataOnRoamingEnabled()) {
2546cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("onRoamingOn: setup data on roaming");
2547ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            setupDataOnConnectableApns(Phone.REASON_ROAMING_ON);
2548cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyDataConnection(Phone.REASON_ROAMING_ON);
2549cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
2550cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("onRoamingOn: Tear down data connection on roaming.");
2551cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            cleanUpAllConnections(true, Phone.REASON_ROAMING_ON);
2552cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyOffApnsOfAvailability(Phone.REASON_ROAMING_ON);
2553cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2554cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2555cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
25561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onRadioAvailable() {
2557cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onRadioAvailable");
2558cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (mPhone.getSimulatedRadioControl() != null) {
2559cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // Assume data is connected on the simulator
2560cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // FIXME  this can be improved
2561cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // setState(DctConstants.State.CONNECTED);
2562cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyDataConnection(null);
2563cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2564cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("onRadioAvailable: We're on the simulator; assuming data is connected");
2565cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2566cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2567cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        IccRecords r = mIccRecords.get();
2568cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (r != null && r.getRecordsLoaded()) {
2569cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyOffApnsOfAvailability(null);
2570cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2571cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2572cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (getOverallState() != DctConstants.State.IDLE) {
2573cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            cleanUpConnection(true, null);
2574cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2575cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2576cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
25771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onRadioOffOrNotAvailable() {
2578cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // Make sure our reconnect delay starts at the initial value
2579cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // next time the radio comes on
2580cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2581cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mReregisterOnReconnectFailure = false;
2582cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2583cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (mPhone.getSimulatedRadioControl() != null) {
2584cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // Assume data is connected on the simulator
2585cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // FIXME  this can be improved
2586cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("We're on the simulator; assuming radio off is meaningless");
2587cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
2588cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("onRadioOffOrNotAvailable: is off and clean up all connections");
2589cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            cleanUpAllConnections(false, Phone.REASON_RADIO_TURNED_OFF);
2590cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2591cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        notifyOffApnsOfAvailability(null);
2592cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
2593cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
25941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void completeConnection(ApnContext apnContext) {
2595c9b81a0c05128694c617fcdd67e73821895822feWink Saville
2596c9b81a0c05128694c617fcdd67e73821895822feWink Saville        if (DBG) log("completeConnection: successful, notify the world apnContext=" + apnContext);
2597c9b81a0c05128694c617fcdd67e73821895822feWink Saville
2598c9b81a0c05128694c617fcdd67e73821895822feWink Saville        if (mIsProvisioning && !TextUtils.isEmpty(mProvisioningUrl)) {
2599c9b81a0c05128694c617fcdd67e73821895822feWink Saville            if (DBG) {
2600c9b81a0c05128694c617fcdd67e73821895822feWink Saville                log("completeConnection: MOBILE_PROVISIONING_ACTION url="
2601c9b81a0c05128694c617fcdd67e73821895822feWink Saville                        + mProvisioningUrl);
2602c9b81a0c05128694c617fcdd67e73821895822feWink Saville            }
2603c8dc0c8244aac9f3985a53bc94b8ec2e295db430Robert Greenwalt            Intent newIntent = Intent.makeMainSelectorActivity(Intent.ACTION_MAIN,
2604c8dc0c8244aac9f3985a53bc94b8ec2e295db430Robert Greenwalt                    Intent.CATEGORY_APP_BROWSER);
2605c8dc0c8244aac9f3985a53bc94b8ec2e295db430Robert Greenwalt            newIntent.setData(Uri.parse(mProvisioningUrl));
2606c9b81a0c05128694c617fcdd67e73821895822feWink Saville            newIntent.setFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT |
2607c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    Intent.FLAG_ACTIVITY_NEW_TASK);
2608c9b81a0c05128694c617fcdd67e73821895822feWink Saville            try {
2609c9b81a0c05128694c617fcdd67e73821895822feWink Saville                mPhone.getContext().startActivity(newIntent);
2610c9b81a0c05128694c617fcdd67e73821895822feWink Saville            } catch (ActivityNotFoundException e) {
2611c9b81a0c05128694c617fcdd67e73821895822feWink Saville                loge("completeConnection: startActivityAsUser failed" + e);
2612c9b81a0c05128694c617fcdd67e73821895822feWink Saville            }
2613c9b81a0c05128694c617fcdd67e73821895822feWink Saville        }
2614c9b81a0c05128694c617fcdd67e73821895822feWink Saville        mIsProvisioning = false;
2615c9b81a0c05128694c617fcdd67e73821895822feWink Saville        mProvisioningUrl = null;
26162b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen        if (mProvisioningSpinner != null) {
26172b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            sendMessage(obtainMessage(DctConstants.CMD_CLEAR_PROVISIONING_SPINNER,
26182b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                    mProvisioningSpinner));
26192b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen        }
2620c9b81a0c05128694c617fcdd67e73821895822feWink Saville
2621c9b81a0c05128694c617fcdd67e73821895822feWink Saville        mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
2622c9b81a0c05128694c617fcdd67e73821895822feWink Saville        startNetStatPoll();
2623c9b81a0c05128694c617fcdd67e73821895822feWink Saville        startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
2624c9b81a0c05128694c617fcdd67e73821895822feWink Saville    }
2625c9b81a0c05128694c617fcdd67e73821895822feWink Saville
2626ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    /**
2627ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     * A SETUP (aka bringUp) has completed, possibly with an error. If
2628ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     * there is an error this method will call {@link #onDataSetupCompleteError}.
2629ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     */
26301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onDataSetupComplete(AsyncResult ar) {
2631608588e9af271f0f5640236809f27c626f9d98e9Robert Greenwalt
2632ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        DcFailCause cause = DcFailCause.UNKNOWN;
2633cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean handleError = false;
2634ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt        ApnContext apnContext = getValidApnContext(ar, "onDataSetupComplete");
2635cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2636ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt        if (apnContext == null) return;
2637cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2638cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (ar.exception == null) {
2639454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville            DcAsyncChannel dcac = apnContext.getDcAc();
2640cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2641cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (RADIO_TESTS) {
2642cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // Note: To change radio.test.onDSC.null.dcac from command line you need to
2643cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // adb root and adb remount and from the command line you can only change the
2644cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // value to 1 once. To change it a second time you can reboot or execute
2645cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // adb shell stop and then adb shell start. The command line to set the value is:
2646ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink 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');"
2647cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                ContentResolver cr = mPhone.getContext().getContentResolver();
2648cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                String radioTestProperty = "radio.test.onDSC.null.dcac";
2649cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (Settings.System.getInt(cr, radioTestProperty, 0) == 1) {
2650cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    log("onDataSetupComplete: " + radioTestProperty +
2651cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            " is true, set dcac to null and reset property to false");
2652cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    dcac = null;
2653cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    Settings.System.putInt(cr, radioTestProperty, 0);
2654cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    log("onDataSetupComplete: " + radioTestProperty + "=" +
2655cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            Settings.System.getInt(mPhone.getContext().getContentResolver(),
2656cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                    radioTestProperty, -1));
2657cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
2658c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
2659cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (dcac == null) {
2660cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                log("onDataSetupComplete: no connection to DC, handle as error");
2661ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                cause = DcFailCause.CONNECTION_TO_DATACONNECTIONAC_BROKEN;
2662cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                handleError = true;
2663cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } else {
2664cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                ApnSetting apn = apnContext.getApnSetting();
2665cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) {
2666cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    log("onDataSetupComplete: success apn=" + (apn == null ? "unknown" : apn.apn));
2667cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
2668cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (apn != null && apn.proxy != null && apn.proxy.length() != 0) {
2669cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    try {
2670cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        String port = apn.port;
2671cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        if (TextUtils.isEmpty(port)) port = "8080";
26729c180aedfc9f0d20525c0128487d3500e6c0a715Jason Monk                        ProxyInfo proxy = new ProxyInfo(apn.proxy,
2673cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                Integer.parseInt(port), null);
2674cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        dcac.setLinkPropertiesHttpProxySync(proxy);
2675cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    } catch (NumberFormatException e) {
2676cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        loge("onDataSetupComplete: NumberFormatException making ProxyProperties (" +
2677cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                apn.port + "): " + e);
2678cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    }
2679cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
2680cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2681cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // everything is setup
2682cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if(TextUtils.equals(apnContext.getApnType(),PhoneConstants.APN_TYPE_DEFAULT)) {
268327b650c406018355a88a41528db7859e232728a0Jack Yu                    try {
268427b650c406018355a88a41528db7859e232728a0Jack Yu                        SystemProperties.set(PUPPET_MASTER_RADIO_STRESS_TEST, "true");
268527b650c406018355a88a41528db7859e232728a0Jack Yu                    } catch (RuntimeException ex) {
268627b650c406018355a88a41528db7859e232728a0Jack Yu                        log("Failed to set PUPPET_MASTER_RADIO_STRESS_TEST to true");
268727b650c406018355a88a41528db7859e232728a0Jack Yu                    }
268822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    if (mCanSetPreferApn && mPreferredApn == null) {
26890e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                        if (DBG) log("onDataSetupComplete: PREFERRED APN is null");
2690cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        mPreferredApn = apn;
2691cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        if (mPreferredApn != null) {
2692cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            setPreferredApn(mPreferredApn.id);
2693cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        }
2694cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    }
2695cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else {
269627b650c406018355a88a41528db7859e232728a0Jack Yu                    try {
269727b650c406018355a88a41528db7859e232728a0Jack Yu                        SystemProperties.set(PUPPET_MASTER_RADIO_STRESS_TEST, "false");
269827b650c406018355a88a41528db7859e232728a0Jack Yu                    } catch (RuntimeException ex) {
269927b650c406018355a88a41528db7859e232728a0Jack Yu                        log("Failed to set PUPPET_MASTER_RADIO_STRESS_TEST to false");
270027b650c406018355a88a41528db7859e232728a0Jack Yu                    }
2701cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
2702c9b81a0c05128694c617fcdd67e73821895822feWink Saville
2703c9b81a0c05128694c617fcdd67e73821895822feWink Saville                // A connection is setup
2704c9b81a0c05128694c617fcdd67e73821895822feWink Saville                apnContext.setState(DctConstants.State.CONNECTED);
27050e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu
2706c9b81a0c05128694c617fcdd67e73821895822feWink Saville                boolean isProvApn = apnContext.isProvisioningApn();
2707b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                final ConnectivityManager cm = ConnectivityManager.from(mPhone.getContext());
2708b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                if (mProvisionBroadcastReceiver != null) {
2709b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    mPhone.getContext().unregisterReceiver(mProvisionBroadcastReceiver);
2710b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    mProvisionBroadcastReceiver = null;
2711b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                }
2712c9b81a0c05128694c617fcdd67e73821895822feWink Saville                if ((!isProvApn) || mIsProvisioning) {
2713b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    // Hide any provisioning notification.
2714b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    cm.setProvisioningNotificationVisible(false, ConnectivityManager.TYPE_MOBILE,
2715b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                            mProvisionActionName);
2716c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    // Complete the connection normally notifying the world we're connected.
2717c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    // We do this if this isn't a special provisioning apn or if we've been
2718c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    // told its time to provision.
2719c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    completeConnection(apnContext);
2720c9b81a0c05128694c617fcdd67e73821895822feWink Saville                } else {
2721c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    // This is a provisioning APN that we're reporting as connected. Later
2722c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    // when the user desires to upgrade this to a "default" connection,
2723c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    // mIsProvisioning == true, we'll go through the code path above.
2724c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    // mIsProvisioning becomes true when CMD_ENABLE_MOBILE_PROVISIONING
2725c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    // is sent to the DCT.
2726c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    if (DBG) {
2727c9b81a0c05128694c617fcdd67e73821895822feWink Saville                        log("onDataSetupComplete: successful, BUT send connected to prov apn as"
2728c9b81a0c05128694c617fcdd67e73821895822feWink Saville                                + " mIsProvisioning:" + mIsProvisioning + " == false"
2729c9b81a0c05128694c617fcdd67e73821895822feWink Saville                                + " && (isProvisioningApn:" + isProvApn + " == true");
2730c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    }
2731c9b81a0c05128694c617fcdd67e73821895822feWink Saville
2732b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    // While radio is up, grab provisioning URL.  The URL contains ICCID which
2733b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    // disappears when radio is off.
2734b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    mProvisionBroadcastReceiver = new ProvisionNotificationBroadcastReceiver(
27352b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                            cm.getMobileProvisioningUrl(),
27362b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                            TelephonyManager.getDefault().getNetworkOperatorName());
2737b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    mPhone.getContext().registerReceiver(mProvisionBroadcastReceiver,
2738b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                            new IntentFilter(mProvisionActionName));
2739b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    // Put up user notification that sign-in is required.
2740b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    cm.setProvisioningNotificationVisible(true, ConnectivityManager.TYPE_MOBILE,
2741b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                            mProvisionActionName);
2742b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    // Turn off radio to save battery and avoid wasting carrier resources.
2743b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    // The network isn't usable and network validation will just fail anyhow.
2744b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen                    setRadio(false);
2745c9b81a0c05128694c617fcdd67e73821895822feWink Saville                }
2746c9b81a0c05128694c617fcdd67e73821895822feWink Saville                if (DBG) {
2747c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    log("onDataSetupComplete: SETUP complete type=" + apnContext.getApnType()
2748c9b81a0c05128694c617fcdd67e73821895822feWink Saville                        + ", reason:" + apnContext.getReason());
2749c9b81a0c05128694c617fcdd67e73821895822feWink Saville                }
2750c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
2751cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
2752ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            cause = (DcFailCause) (ar.result);
2753cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) {
2754cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                ApnSetting apn = apnContext.getApnSetting();
2755cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                log(String.format("onDataSetupComplete: error apn=%s cause=%s",
2756cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        (apn == null ? "unknown" : apn.apn), cause));
2757c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
2758cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (cause.isEventLoggable()) {
2759cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // Log this failure to the Event Logs.
2760cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                int cid = getCellLocationId();
2761cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                EventLog.writeEvent(EventLogTags.PDP_SETUP_FAIL,
2762cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        cause.ordinal(), cid, TelephonyManager.getDefault().getNetworkType());
2763c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
27640742246233c3f03f864d23e52d89e1845d994701Antonio Marín Cerezuela            ApnSetting apn = apnContext.getApnSetting();
27650742246233c3f03f864d23e52d89e1845d994701Antonio Marín Cerezuela            mPhone.notifyPreciseDataConnectionFailed(apnContext.getReason(),
27660742246233c3f03f864d23e52d89e1845d994701Antonio Marín Cerezuela                    apnContext.getApnType(), apn != null ? apn.apn : "unknown", cause.toString());
2767cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
27680e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            if (cause.isRestartRadioFail() || apnContext.restartOnError(cause.getErrorCode())) {
27690e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                if (DBG) log("Modem restarted.");
27700e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                sendRestartRadio();
27710e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            }
2772cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
27730e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            // If the data call failure cause is a permanent failure, we mark the APN as permanent
27740e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            // failed.
27750e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            if (isPermanentFail(cause)) {
27760e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                log("cause = " + cause + ", mark apn as permanent failed. apn = " + apn);
27770e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                apnContext.markApnPermanentFailed(apn);
2778c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
27790e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu
2780cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            handleError = true;
2781cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
2782cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2783cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (handleError) {
2784ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            onDataSetupCompleteError(ar);
2785ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        }
2786a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
2787a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        /* If flag is set to false after SETUP_DATA_CALL is invoked, we need
2788a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville         * to clean data connections.
2789a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville         */
2790a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (!mInternalDataEnabled) {
2791a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            cleanUpAllConnections(null);
2792a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
2793a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
2794ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    }
2795cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2796ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    /**
2797ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt     * check for obsolete messages.  Return ApnContext if valid, null if not
2798ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt     */
2799ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt    private ApnContext getValidApnContext(AsyncResult ar, String logString) {
2800ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt        if (ar != null && ar.userObj instanceof Pair) {
2801ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt            Pair<ApnContext, Integer>pair = (Pair<ApnContext, Integer>)ar.userObj;
2802ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt            ApnContext apnContext = pair.first;
2803ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt            if (apnContext != null) {
28041a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt                final int generation = apnContext.getConnectionGeneration();
28051a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt                if (DBG) {
28061a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt                    log("getValidApnContext (" + logString + ") on " + apnContext + " got " +
28071a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt                            generation + " vs " + pair.second);
28081a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt                }
28091a1cc3f5759471edcf51294439f0e0b71922d6a0Robert Greenwalt                if (generation == pair.second) {
2810ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt                    return apnContext;
2811ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt                } else {
2812ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt                    log("ignoring obsolete " + logString);
2813ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt                    return null;
2814ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt                }
2815ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt            }
2816ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt        }
2817ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt        throw new RuntimeException(logString + ": No apnContext");
2818ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt    }
2819ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt
2820ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt    /**
2821ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     * Error has occurred during the SETUP {aka bringUP} request and the DCT
2822ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     * should either try the next waiting APN or start over from the
2823ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     * beginning if the list is empty. Between each SETUP request there will
2824ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville     * be a delay defined by {@link #getApnDelay()}.
2825ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     */
28261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onDataSetupCompleteError(AsyncResult ar) {
28270e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu
2828ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt        ApnContext apnContext = getValidApnContext(ar, "onDataSetupCompleteError");
2829ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
2830ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt        if (apnContext == null) return;
2831ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
28320e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu        long delay = apnContext.getDelayForNextApn(mFailFast);
2833ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
28340e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu        // Check if we need to retry or not.
28350e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu        if (delay > 0) {
28360e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            if (DBG) log("onDataSetupCompleteError: Try next APN. delay = " + delay);
2837ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            apnContext.setState(DctConstants.State.SCANNING);
2838ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            // Wait a bit before trying the next APN, so that
2839ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            // we're not tying up the RIL command channel
28400e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            startAlarmForReconnect(delay, apnContext);
28410e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu        } else {
28420e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            // If we are not going to retry any APN, set this APN context to failed state.
28430e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            // This would be the final state of a data connection.
28440e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            apnContext.setState(DctConstants.State.FAILED);
28450e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            mPhone.notifyDataConnection(Phone.REASON_APN_FAILED, apnContext.getApnType());
28460e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            apnContext.setDataConnectionAc(null);
28470e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            log("onDataSetupCompleteError: Stop retrying APNs.");
2848c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
2849c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
2850c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
2851c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
2852cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Called when EVENT_DISCONNECT_DONE is received.
2853c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
28541a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onDisconnectDone(AsyncResult ar) {
2855ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt        ApnContext apnContext = getValidApnContext(ar, "onDisconnectDone");
2856ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt        if (apnContext == null) return;
2857c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
2858cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if(DBG) log("onDisconnectDone: EVENT_DISCONNECT_DONE apnContext=" + apnContext);
2859cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        apnContext.setState(DctConstants.State.IDLE);
2860cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2861cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
2862cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2863cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // if all data connection are gone, check whether Airplane mode request was
2864cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // pending.
2865cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (isDisconnected()) {
2866cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (mPhone.getServiceStateTracker().processPendingRadioPowerOffAfterDataOff()) {
2867449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville                if(DBG) log("onDisconnectDone: radio will be turned off, no retries");
2868cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // Radio will be turned off. No need to retry data setup
2869cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                apnContext.setApnSetting(null);
2870cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                apnContext.setDataConnectionAc(null);
2871a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
2872a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                // Need to notify disconnect as well, in the case of switching Airplane mode.
2873a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                // Otherwise, it would cause 30s delayed to turn on Airplane mode.
28740e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                if (mDisconnectPendingCount > 0) {
2875a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    mDisconnectPendingCount--;
28760e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                }
2877a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
2878a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                if (mDisconnectPendingCount == 0) {
2879a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    notifyDataDisconnectComplete();
2880a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    notifyAllDataDisconnected();
2881a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                }
2882cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return;
2883cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
2884c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
2885c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
2886cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // If APN is still enabled, try to bring it back up automatically
28873fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt        if (mAttached.get() && apnContext.isReady() && retryAfterDisconnected(apnContext)) {
288827b650c406018355a88a41528db7859e232728a0Jack Yu            try {
288927b650c406018355a88a41528db7859e232728a0Jack Yu                SystemProperties.set(PUPPET_MASTER_RADIO_STRESS_TEST, "false");
289027b650c406018355a88a41528db7859e232728a0Jack Yu            } catch (RuntimeException ex) {
289127b650c406018355a88a41528db7859e232728a0Jack Yu                log("Failed to set PUPPET_MASTER_RADIO_STRESS_TEST to false");
289227b650c406018355a88a41528db7859e232728a0Jack Yu            }
2893cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // Wait a bit before trying the next APN, so that
2894cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // we're not tying up the RIL command channel.
2895cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // This also helps in any external dependency to turn off the context.
28960e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            if (DBG) log("onDisconnectDone: attached, ready and retry after disconnect");
28970e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            long delay = apnContext.getInterApnDelay(mFailFast);
28980e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            if (delay > 0) {
28990e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                // Data connection is in IDLE state, so when we reconnect later, we'll rebuild
29000e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                // the waiting APN list, which will also reset/reconfigure the retry manager.
29010e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                startAlarmForReconnect(delay, apnContext);
29020e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            }
2903c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } else {
2904449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville            boolean restartRadioAfterProvisioning = mPhone.getContext().getResources().getBoolean(
2905449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville                    com.android.internal.R.bool.config_restartRadioAfterProvisioning);
2906449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville
2907449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville            if (apnContext.isProvisioningApn() && restartRadioAfterProvisioning) {
2908449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville                log("onDisconnectDone: restartRadio after provisioning");
2909449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville                restartRadio();
2910449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville            }
2911cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            apnContext.setApnSetting(null);
2912cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            apnContext.setDataConnectionAc(null);
29133fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            if (isOnlySingleDcAllowed(mPhone.getServiceState().getRilDataRadioTechnology())) {
2914449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville                if(DBG) log("onDisconnectDone: isOnlySigneDcAllowed true so setup single apn");
29153fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                setupDataOnConnectableApns(Phone.REASON_SINGLE_PDN_ARBITRATION);
2916449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville            } else {
2917449cbf85380bd1d6716b7ab002da1efb9493bb02Wink Saville                if(DBG) log("onDisconnectDone: not retrying");
29183fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            }
2919c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
2920a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
2921a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (mDisconnectPendingCount > 0)
2922a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mDisconnectPendingCount--;
2923a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
2924a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (mDisconnectPendingCount == 0) {
2925c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt            apnContext.setConcurrentVoiceAndDataAllowed(
2926c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt                    mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed());
2927a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            notifyDataDisconnectComplete();
2928a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            notifyAllDataDisconnected();
2929a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
2930a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
2931c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
2932c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
2933ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    /**
2934ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     * Called when EVENT_DISCONNECT_DC_RETRYING is received.
2935ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     */
29361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onDisconnectDcRetrying(AsyncResult ar) {
2937ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        // We could just do this in DC!!!
2938ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt        ApnContext apnContext = getValidApnContext(ar, "onDisconnectDcRetrying");
2939ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt        if (apnContext == null) return;
2940ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
2941ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        apnContext.setState(DctConstants.State.RETRYING);
2942ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if(DBG) log("onDisconnectDcRetrying: apnContext=" + apnContext);
2943ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
2944ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
2945ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    }
2946ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
29471a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onVoiceCallStarted() {
2948cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onVoiceCallStarted");
2949ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville        mInVoiceCall = true;
2950cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (isConnected() && ! mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) {
2951cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("onVoiceCallStarted stop polling");
2952cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            stopNetStatPoll();
2953cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            stopDataStallAlarm();
2954cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            notifyDataConnection(Phone.REASON_VOICE_CALL_STARTED);
2955c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
2956c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
2957c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
29581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onVoiceCallEnded() {
2959cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onVoiceCallEnded");
2960ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville        mInVoiceCall = false;
2961cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (isConnected()) {
2962cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (!mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) {
2963cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                startNetStatPoll();
2964cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
2965cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                notifyDataConnection(Phone.REASON_VOICE_CALL_ENDED);
2966cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } else {
2967cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // clean slate after call end.
2968cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                resetPollStats();
2969c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
2970c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
2971bda761320929f714951c328bfec6a51a1978db97Wink Saville        // reset reconnect timer
2972bda761320929f714951c328bfec6a51a1978db97Wink Saville        setupDataOnConnectableApns(Phone.REASON_VOICE_CALL_ENDED);
2973c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
2974c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
29751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onCleanUpConnection(boolean tearDown, int apnId, String reason) {
2976cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("onCleanUpConnection");
2977af5593594070f825032be46dced573cd195956e1Robert Greenwalt        ApnContext apnContext = mApnContextsById.get(apnId);
2978cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnContext != null) {
2979cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            apnContext.setReason(reason);
2980cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            cleanUpConnection(tearDown, apnContext);
2981c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
2982c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
2983c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
29841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean isConnected() {
2985cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (ApnContext apnContext : mApnContexts.values()) {
2986ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (apnContext.getState() == DctConstants.State.CONNECTED) {
2987cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // At least one context is connected, return true
2988cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return true;
2989c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
2990c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
2991cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // There are not any contexts connected, return false
2992cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return false;
2993c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
2994c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
2995cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public boolean isDisconnected() {
2996cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (ApnContext apnContext : mApnContexts.values()) {
2997cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (!apnContext.isDisconnected()) {
2998cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // At least one context was not disconnected return false
2999cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return false;
3000cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
3001c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3002cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // All contexts were disconnected so return true
3003cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return true;
3004c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
3005c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
30061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void notifyDataConnection(String reason) {
3007cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("notifyDataConnection: reason=" + reason);
3008cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (ApnContext apnContext : mApnContexts.values()) {
3009187a39f896f88eb6c5e4306d9595546654825976Wink Saville            if (mAttached.get() && apnContext.isReady()) {
3010187a39f896f88eb6c5e4306d9595546654825976Wink Saville                if (DBG) log("notifyDataConnection: type:" + apnContext.getApnType());
3011cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mPhone.notifyDataConnection(reason != null ? reason : apnContext.getReason(),
3012cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        apnContext.getApnType());
3013cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
3014c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3015cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        notifyOffApnsOfAvailability(reason);
3016c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
3017c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
30181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void setDataProfilesAsNeeded() {
30191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (DBG) log("setDataProfilesAsNeeded");
30201a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (mAllApnSettings != null && !mAllApnSettings.isEmpty()) {
30211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            ArrayList<DataProfile> dps = new ArrayList<DataProfile>();
30221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            for (ApnSetting apn : mAllApnSettings) {
30231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (apn.modemCognitive) {
30241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    DataProfile dp = new DataProfile(apn,
30251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            mPhone.getServiceState().getDataRoaming());
30261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    boolean isDup = false;
30271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    for(DataProfile dpIn : dps) {
30281a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        if (dp.equals(dpIn)) {
30291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            isDup = true;
30301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            break;
30311a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        }
30321a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
30331a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (!isDup) {
30341a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        dps.add(dp);
30351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
30361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
30371a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
30381a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if(dps.size() > 0) {
30391a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mPhone.mCi.setDataProfile(dps.toArray(new DataProfile[0]), null);
30401a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
30411a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
30421a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
30431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3044c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
3045cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Based on the sim operator numeric, create a list for all possible
3046cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Data Connections and setup the preferredApn.
3047c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
3048cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private void createAllApnList() {
30491a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mMvnoMatched = false;
3050ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        mAllApnSettings = new ArrayList<ApnSetting>();
3051cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        IccRecords r = mIccRecords.get();
3052cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        String operator = (r != null) ? r.getOperatorNumeric() : "";
3053cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (operator != null) {
3054cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            String selection = "numeric = '" + operator + "'";
305560bc489803a3557526e1f95e34c237e70f28bc50Sungmin Choi            String orderBy = "_id";
3056cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // query only enabled apn.
3057cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // carrier_enabled : 1 means enabled apn, 0 disabled apn.
30589d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan            // selection += " and carrier_enabled = 1";
3059cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("createAllApnList: selection=" + selection);
3060cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
3061cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            Cursor cursor = mPhone.getContext().getContentResolver().query(
306260bc489803a3557526e1f95e34c237e70f28bc50Sungmin Choi                    Telephony.Carriers.CONTENT_URI, null, selection, null, orderBy);
3063cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
3064cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (cursor != null) {
3065cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (cursor.getCount() > 0) {
3066ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                    mAllApnSettings = createApnList(cursor);
3067cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
3068cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                cursor.close();
3069cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
3070c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3071c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
307276f43316a5a6082d601bffd4b6898d0bd81e11fcram        addEmergencyApnSetting();
307376f43316a5a6082d601bffd4b6898d0bd81e11fcram
307429c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        dedupeApnSettings();
307529c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt
3076ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (mAllApnSettings.isEmpty()) {
3077cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("createAllApnList: No APN found for carrier: " + operator);
3078cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            mPreferredApn = null;
3079ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            // TODO: What is the right behavior?
3080cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            //notifyNoData(DataConnection.FailCause.MISSING_UNKNOWN_APN);
3081c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } else {
3082cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            mPreferredApn = getPreferredApn();
3083cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (mPreferredApn != null && !mPreferredApn.numeric.equals(operator)) {
3084cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mPreferredApn = null;
3085cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                setPreferredApn(-1);
3086cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
3087cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("createAllApnList: mPreferredApn=" + mPreferredApn);
3088c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3089ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (DBG) log("createAllApnList: X mAllApnSettings=" + mAllApnSettings);
30909d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan
30919d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan        setDataProfilesAsNeeded();
3092c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
3093c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
309429c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt    private void dedupeApnSettings() {
309529c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        ArrayList<ApnSetting> resultApns = new ArrayList<ApnSetting>();
309629c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt
309729c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        // coalesce APNs if they are similar enough to prevent
309829c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        // us from bringing up two data calls with the same interface
309929c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        int i = 0;
310029c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        while (i < mAllApnSettings.size() - 1) {
310129c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt            ApnSetting first = mAllApnSettings.get(i);
310229c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt            ApnSetting second = null;
310329c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt            int j = i + 1;
310429c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt            while (j < mAllApnSettings.size()) {
310529c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                second = mAllApnSettings.get(j);
310629c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                if (apnsSimilar(first, second)) {
310729c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                    ApnSetting newApn = mergeApns(first, second);
310829c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                    mAllApnSettings.set(i, newApn);
310929c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                    first = newApn;
311029c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                    mAllApnSettings.remove(j);
311129c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                } else {
311229c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                    j++;
311329c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                }
311429c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt            }
311529c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt            i++;
311629c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        }
311729c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt    }
311829c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt
3119d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe    //check whether the types of two APN same (even only one type of each APN is same)
3120d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe    private boolean apnTypeSameAny(ApnSetting first, ApnSetting second) {
3121d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe        if(VDBG) {
3122d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe            StringBuilder apnType1 = new StringBuilder(first.apn + ": ");
3123d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe            for(int index1 = 0; index1 < first.types.length; index1++) {
3124d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe                apnType1.append(first.types[index1]);
3125d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe                apnType1.append(",");
3126d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe            }
3127d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe
3128d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe            StringBuilder apnType2 = new StringBuilder(second.apn + ": ");
3129d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe            for(int index1 = 0; index1 < second.types.length; index1++) {
3130d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe                apnType2.append(second.types[index1]);
3131d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe                apnType2.append(",");
3132d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe            }
3133d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe            log("APN1: is " + apnType1);
3134d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe            log("APN2: is " + apnType2);
3135d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe        }
3136d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe
3137d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe        for(int index1 = 0; index1 < first.types.length; index1++) {
3138d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe            for(int index2 = 0; index2 < second.types.length; index2++) {
3139d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe                if(first.types[index1].equals(PhoneConstants.APN_TYPE_ALL) ||
3140d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe                        second.types[index2].equals(PhoneConstants.APN_TYPE_ALL) ||
3141d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe                        first.types[index1].equals(second.types[index2])) {
3142d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe                    if(VDBG)log("apnTypeSameAny: return true");
3143d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe                    return true;
3144d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe                }
3145d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe            }
3146d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe        }
3147d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe
3148d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe        if(VDBG)log("apnTypeSameAny: return false");
3149d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe        return false;
3150d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe    }
3151d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe
315229c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt    // Check if neither mention DUN and are substantially similar
315329c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt    private boolean apnsSimilar(ApnSetting first, ApnSetting second) {
315429c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        return (first.canHandleType(PhoneConstants.APN_TYPE_DUN) == false &&
315529c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                second.canHandleType(PhoneConstants.APN_TYPE_DUN) == false &&
315629c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                Objects.equals(first.apn, second.apn) &&
3157d86df358b8fe07160caa12147b6e4ad34d378ce6xinhe                !apnTypeSameAny(first, second) &&
315861cdbcf2de392d043de0e4a533fbc615fc423000Amit Mahajan                xorEquals(first.proxy, second.proxy) &&
315961cdbcf2de392d043de0e4a533fbc615fc423000Amit Mahajan                xorEquals(first.port, second.port) &&
316029c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                first.carrierEnabled == second.carrierEnabled &&
3161aaf0e8d623b1e94004557573aef9235177ca19e3Amit Mahajan                first.bearerBitmask == second.bearerBitmask &&
316229c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                first.profileId == second.profileId &&
316329c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                Objects.equals(first.mvnoType, second.mvnoType) &&
316429c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                Objects.equals(first.mvnoMatchData, second.mvnoMatchData) &&
316529c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                xorEquals(first.mmsc, second.mmsc) &&
316629c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                xorEquals(first.mmsProxy, second.mmsProxy) &&
316729c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                xorEquals(first.mmsPort, second.mmsPort));
316829c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt    }
316929c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt
317029c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt    // equal or one is not specified
317129c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt    private boolean xorEquals(String first, String second) {
317229c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        return (Objects.equals(first, second) ||
317329c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                TextUtils.isEmpty(first) ||
317429c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                TextUtils.isEmpty(second));
317529c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt    }
317629c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt
317729c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt    private ApnSetting mergeApns(ApnSetting dest, ApnSetting src) {
3178bca51fc3a191d3ca30df627b75374db0941571c5Sungmin Choi        int id = dest.id;
317929c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        ArrayList<String> resultTypes = new ArrayList<String>();
318029c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        resultTypes.addAll(Arrays.asList(dest.types));
318129c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        for (String srcType : src.types) {
318229c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt            if (resultTypes.contains(srcType) == false) resultTypes.add(srcType);
3183bca51fc3a191d3ca30df627b75374db0941571c5Sungmin Choi            if (srcType.equals(PhoneConstants.APN_TYPE_DEFAULT)) id = src.id;
318429c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        }
318529c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        String mmsc = (TextUtils.isEmpty(dest.mmsc) ? src.mmsc : dest.mmsc);
318629c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        String mmsProxy = (TextUtils.isEmpty(dest.mmsProxy) ? src.mmsProxy : dest.mmsProxy);
318729c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt        String mmsPort = (TextUtils.isEmpty(dest.mmsPort) ? src.mmsPort : dest.mmsPort);
318861cdbcf2de392d043de0e4a533fbc615fc423000Amit Mahajan        String proxy = (TextUtils.isEmpty(dest.proxy) ? src.proxy : dest.proxy);
318961cdbcf2de392d043de0e4a533fbc615fc423000Amit Mahajan        String port = (TextUtils.isEmpty(dest.port) ? src.port : dest.port);
319061cdbcf2de392d043de0e4a533fbc615fc423000Amit Mahajan        String protocol = src.protocol.equals("IPV4V6") ? src.protocol : dest.protocol;
319161cdbcf2de392d043de0e4a533fbc615fc423000Amit Mahajan        String roamingProtocol = src.roamingProtocol.equals("IPV4V6") ? src.roamingProtocol :
319261cdbcf2de392d043de0e4a533fbc615fc423000Amit Mahajan                dest.roamingProtocol;
3193aaf0e8d623b1e94004557573aef9235177ca19e3Amit Mahajan        int bearerBitmask = (dest.bearerBitmask == 0 || src.bearerBitmask == 0) ?
3194aaf0e8d623b1e94004557573aef9235177ca19e3Amit Mahajan                0 : (dest.bearerBitmask | src.bearerBitmask);
319529c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt
3196bca51fc3a191d3ca30df627b75374db0941571c5Sungmin Choi        return new ApnSetting(id, dest.numeric, dest.carrier, dest.apn,
319761cdbcf2de392d043de0e4a533fbc615fc423000Amit Mahajan                proxy, port, mmsc, mmsProxy, mmsPort, dest.user, dest.password,
319861cdbcf2de392d043de0e4a533fbc615fc423000Amit Mahajan                dest.authType, resultTypes.toArray(new String[0]), protocol,
3199aaf0e8d623b1e94004557573aef9235177ca19e3Amit Mahajan                roamingProtocol, dest.carrierEnabled, 0, bearerBitmask, dest.profileId,
320029c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                (dest.modemCognitive || src.modemCognitive), dest.maxConns, dest.waitTime,
320129c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt                dest.maxConnsTime, dest.mtu, dest.mvnoType, dest.mvnoMatchData);
320229c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt    }
320329c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt
3204ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    /** Return the DC AsyncChannel for the new data connection */
3205454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville    private DcAsyncChannel createDataConnection() {
3206cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("createDataConnection E");
3207cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
3208cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        int id = mUniqueIdGenerator.getAndIncrement();
3209ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        DataConnection conn = DataConnection.makeDataConnection(mPhone, id,
3210ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                                                this, mDcTesterFailBringUpAll, mDcc);
3211cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mDataConnections.put(id, conn);
3212454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville        DcAsyncChannel dcac = new DcAsyncChannel(conn, LOG_TAG);
3213cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        int status = dcac.fullyConnectSync(mPhone.getContext(), this, conn.getHandler());
3214cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (status == AsyncChannel.STATUS_SUCCESSFUL) {
3215ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            mDataConnectionAcHashMap.put(dcac.getDataConnectionIdSync(), dcac);
3216c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } else {
3217ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            loge("createDataConnection: Could not connect to dcac=" + dcac + " status=" + status);
3218c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3219cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
3220cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("createDataConnection() X id=" + id + " dc=" + conn);
3221ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        return dcac;
3222c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
3223c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
3224cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private void destroyDataConnections() {
3225cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if(mDataConnections != null) {
3226cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("destroyDataConnections: clear mDataConnectionList");
3227cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            mDataConnections.clear();
3228cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
3229cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("destroyDataConnections: mDataConnecitonList is empty, ignore");
3230c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3231c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
3232c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
3233c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
3234cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Build a list of APNs to be used to create PDP's.
3235c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
3236cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @param requestedApnType
3237cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @return waitingApns list to be used to create PDP
3238cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *          error when waitingApns.isEmpty()
3239c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
3240203e588e3c42a81aa8a56f595119c181a63b12caWink Saville    private ArrayList<ApnSetting> buildWaitingApns(String requestedApnType, int radioTech) {
3241cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("buildWaitingApns: E requestedApnType=" + requestedApnType);
3242cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ArrayList<ApnSetting> apnList = new ArrayList<ApnSetting>();
3243cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
3244cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (requestedApnType.equals(PhoneConstants.APN_TYPE_DUN)) {
3245cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            ApnSetting dun = fetchDunApn();
3246cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (dun != null) {
3247cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                apnList.add(dun);
3248cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) log("buildWaitingApns: X added APN_TYPE_DUN apnList=" + apnList);
3249cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return apnList;
3250c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
3251c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3252c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
3253cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        IccRecords r = mIccRecords.get();
3254cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        String operator = (r != null) ? r.getOperatorNumeric() : "";
3255c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
3256cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // This is a workaround for a bug (7305641) where we don't failover to other
3257cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // suitable APNs if our preferred APN fails.  On prepaid ATT sims we need to
3258cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // failover to a provisioning APN, but once we've used their default data
3259cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // connection we are locked to it for life.  This change allows ATT devices
3260cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // to say they don't want to use preferred at all.
3261cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean usePreferred = true;
3262cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        try {
3263cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            usePreferred = ! mPhone.getContext().getResources().getBoolean(com.android.
3264cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    internal.R.bool.config_dontPreferApn);
3265cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } catch (Resources.NotFoundException e) {
3266cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("buildWaitingApns: usePreferred NotFoundException set to true");
3267cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            usePreferred = true;
3268cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
3269bf660a4647db8151609cdfa0ecc4c96e1518947fSungmin Choi        if (usePreferred) {
3270bf660a4647db8151609cdfa0ecc4c96e1518947fSungmin Choi            mPreferredApn = getPreferredApn();
3271bf660a4647db8151609cdfa0ecc4c96e1518947fSungmin Choi        }
3272cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) {
3273cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("buildWaitingApns: usePreferred=" + usePreferred
327422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    + " canSetPreferApn=" + mCanSetPreferApn
3275cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    + " mPreferredApn=" + mPreferredApn
3276cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    + " operator=" + operator + " radioTech=" + radioTech
3277cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    + " IccRecords r=" + r);
3278cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
3279c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
328022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (usePreferred && mCanSetPreferApn && mPreferredApn != null &&
3281cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mPreferredApn.canHandleType(requestedApnType)) {
3282cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) {
3283cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                log("buildWaitingApns: Preferred APN:" + operator + ":"
3284cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        + mPreferredApn.numeric + ":" + mPreferredApn);
3285cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
3286cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (mPreferredApn.numeric.equals(operator)) {
3287aaf0e8d623b1e94004557573aef9235177ca19e3Amit Mahajan                if (ServiceState.bitmaskHasTech(mPreferredApn.bearerBitmask, radioTech)) {
3288cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    apnList.add(mPreferredApn);
3289cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    if (DBG) log("buildWaitingApns: X added preferred apnList=" + apnList);
3290cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    return apnList;
3291cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else {
3292cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    if (DBG) log("buildWaitingApns: no preferred APN");
3293cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    setPreferredApn(-1);
3294cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    mPreferredApn = null;
3295c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
3296cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } else {
3297cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) log("buildWaitingApns: no preferred APN");
3298cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                setPreferredApn(-1);
3299cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mPreferredApn = null;
3300c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
3301c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3302ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (mAllApnSettings != null) {
3303ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (DBG) log("buildWaitingApns: mAllApnSettings=" + mAllApnSettings);
3304ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            for (ApnSetting apn : mAllApnSettings) {
3305cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (apn.canHandleType(requestedApnType)) {
3306aaf0e8d623b1e94004557573aef9235177ca19e3Amit Mahajan                    if (ServiceState.bitmaskHasTech(apn.bearerBitmask, radioTech)) {
33079232dafa7ea833fc0b3a6024d6c7e23fc8e961eaRobert Greenwalt                        if (DBG) log("buildWaitingApns: adding apn=" + apn);
3308cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        apnList.add(apn);
3309c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    } else {
3310cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        if (DBG) {
3311aaf0e8d623b1e94004557573aef9235177ca19e3Amit Mahajan                            log("buildWaitingApns: bearerBitmask:" + apn.bearerBitmask + " does " +
3312aaf0e8d623b1e94004557573aef9235177ca19e3Amit Mahajan                                    "not include radioTech:" + radioTech);
3313cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        }
3314c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    }
33159232dafa7ea833fc0b3a6024d6c7e23fc8e961eaRobert Greenwalt                } else if (DBG) {
331627b650c406018355a88a41528db7859e232728a0Jack Yu                    log("buildWaitingApns: couldn't handle requested ApnType="
3317cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            + requestedApnType);
3318c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
3319c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
3320cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
33214bd0ae43eb0cb9969dee4f30cddc18a71da68190Jack Yu            loge("mAllApnSettings is null!");
3322c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
33230e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu        if (DBG) log("buildWaitingApns: " + apnList.size() + " APNs in the list: " + apnList);
3324cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return apnList;
3325c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
3326c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
3327cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private String apnListToString (ArrayList<ApnSetting> apns) {
3328cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        StringBuilder result = new StringBuilder();
3329cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (int i = 0, size = apns.size(); i < size; i++) {
3330cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            result.append('[')
3331cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                  .append(apns.get(i).toString())
3332cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                  .append(']');
3333c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
3334cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return result.toString();
3335c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
3336c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
3337cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private void setPreferredApn(int pos) {
333822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (!mCanSetPreferApn) {
3339cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("setPreferredApn: X !canSEtPreferApn");
3340cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return;
3341cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
3342cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
33436bc4098827f3070a44b5e51508b455d7c7be9c07Wink Saville        String subId = Long.toString(mPhone.getSubId());
33446bc4098827f3070a44b5e51508b455d7c7be9c07Wink Saville        Uri uri = Uri.withAppendedPath(PREFERAPN_NO_UPDATE_URI_USING_SUBID, subId);
3345cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        log("setPreferredApn: delete");
3346cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ContentResolver resolver = mPhone.getContext().getContentResolver();
33476bc4098827f3070a44b5e51508b455d7c7be9c07Wink Saville        resolver.delete(uri, null, null);
3348cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
3349cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (pos >= 0) {
3350cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("setPreferredApn: insert");
3351cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            ContentValues values = new ContentValues();
3352cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            values.put(APN_ID, pos);
33536bc4098827f3070a44b5e51508b455d7c7be9c07Wink Saville            resolver.insert(uri, values);
3354cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
3355cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
3356cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
3357cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private ApnSetting getPreferredApn() {
33584bd0ae43eb0cb9969dee4f30cddc18a71da68190Jack Yu        if (mAllApnSettings == null || mAllApnSettings.isEmpty()) {
33594bd0ae43eb0cb9969dee4f30cddc18a71da68190Jack Yu            log("getPreferredApn: mAllApnSettings is " + ((mAllApnSettings == null)?"null":"empty"));
3360cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return null;
3361cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
3362cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
33636bc4098827f3070a44b5e51508b455d7c7be9c07Wink Saville        String subId = Long.toString(mPhone.getSubId());
33646bc4098827f3070a44b5e51508b455d7c7be9c07Wink Saville        Uri uri = Uri.withAppendedPath(PREFERAPN_NO_UPDATE_URI_USING_SUBID, subId);
3365cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        Cursor cursor = mPhone.getContext().getContentResolver().query(
33666bc4098827f3070a44b5e51508b455d7c7be9c07Wink Saville                uri, new String[] { "_id", "name", "apn" },
3367cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                null, null, Telephony.Carriers.DEFAULT_SORT_ORDER);
3368cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
3369cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (cursor != null) {
337022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mCanSetPreferApn = true;
3371cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
337222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mCanSetPreferApn = false;
3373cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
3374cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        log("getPreferredApn: mRequestedApnType=" + mRequestedApnType + " cursor=" + cursor
3375cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                + " cursor.count=" + ((cursor != null) ? cursor.getCount() : 0));
3376cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
337722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mCanSetPreferApn && cursor.getCount() > 0) {
3378cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            int pos;
3379cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            cursor.moveToFirst();
3380cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            pos = cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers._ID));
3381ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            for(ApnSetting p : mAllApnSettings) {
3382cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                log("getPreferredApn: apnSetting=" + p);
3383cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (p.id == pos && p.canHandleType(mRequestedApnType)) {
3384cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    log("getPreferredApn: X found apnSetting" + p);
3385cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    cursor.close();
3386cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    return p;
3387cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
3388cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            }
3389cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
3390cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
3391cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (cursor != null) {
3392cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            cursor.close();
3393cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
3394cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
3395cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        log("getPreferredApn: X not found");
3396cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return null;
3397cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    }
3398cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
3399cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
3400cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public void handleMessage (Message msg) {
34011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (VDBG) log("handleMessage msg=" + msg);
3402cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
3403cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        switch (msg.what) {
3404cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_RECORDS_LOADED:
34051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                // If onRecordsLoadedOrSubIdChanged() is not called here, it should be called on
34061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                // onSubscriptionsChanged() when a valid subId is available.
34071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                int subId = mPhone.getSubId();
34081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (SubscriptionManager.isValidSubscriptionId(subId)) {
34091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    onRecordsLoadedOrSubIdChanged();
34101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                } else {
34111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    log("Ignoring EVENT_RECORDS_LOADED as subId is not valid: " + subId);
34121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
3413cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
3414cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
3415cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_DATA_CONNECTION_DETACHED:
3416cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                onDataConnectionDetached();
3417cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
3418cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
3419cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_DATA_CONNECTION_ATTACHED:
3420bda761320929f714951c328bfec6a51a1978db97Wink Saville                onDataConnectionAttached();
3421cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
3422cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
3423cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_DO_RECOVERY:
3424cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                doRecovery();
3425cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
3426cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
3427cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_APN_CHANGED:
3428cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                onApnChanged();
3429cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
3430cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
3431cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_PS_RESTRICT_ENABLED:
3432cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                /**
3433cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                 * We don't need to explicitly to tear down the PDP context
3434cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                 * when PS restricted is enabled. The base band will deactive
3435cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                 * PDP context and notify us with PDP_CONTEXT_CHANGED.
3436cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                 * But we should stop the network polling and prevent reset PDP.
3437cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                 */
3438cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) log("EVENT_PS_RESTRICT_ENABLED " + mIsPsRestricted);
3439cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                stopNetStatPoll();
3440cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                stopDataStallAlarm();
3441cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mIsPsRestricted = true;
3442cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                break;
3443cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
3444cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_PS_RESTRICT_DISABLED:
3445cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                /**
3446cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                 * When PS restrict is removed, we need setup PDP connection if
3447cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                 * PDP connection is down.
3448cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                 */
3449cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) log("EVENT_PS_RESTRICT_DISABLED " + mIsPsRestricted);
3450cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mIsPsRestricted  = false;
3451cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (isConnected()) {
3452cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    startNetStatPoll();
3453cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
3454cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else {
3455cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    // TODO: Should all PDN states be checked to fail?
3456ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                    if (mState == DctConstants.State.FAILED) {
3457cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        cleanUpAllConnections(false, Phone.REASON_PS_RESTRICT_ENABLED);
3458cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        mReregisterOnReconnectFailure = false;
3459cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    }
3460af5593594070f825032be46dced573cd195956e1Robert Greenwalt                    ApnContext apnContext = mApnContextsById.get(DctConstants.APN_DEFAULT_ID);
34613fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    if (apnContext != null) {
34623fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                        apnContext.setReason(Phone.REASON_PS_RESTRICT_ENABLED);
34633fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                        trySetupData(apnContext);
34643fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    } else {
34653fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                        loge("**** Default ApnContext not found ****");
34663fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                        if (Build.IS_DEBUGGABLE) {
34673fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                            throw new RuntimeException("Default ApnContext not found");
34683fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                        }
34693fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    }
3470cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
3471cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                break;
3472ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
3473cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_TRY_SETUP_DATA:
3474cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (msg.obj instanceof ApnContext) {
3475cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    onTrySetupData((ApnContext)msg.obj);
3476cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else if (msg.obj instanceof String) {
3477cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    onTrySetupData((String)msg.obj);
3478cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else {
3479cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    loge("EVENT_TRY_SETUP request w/o apnContext or String");
3480cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
3481cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                break;
3482cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
3483cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_CLEAN_UP_CONNECTION:
3484cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                boolean tearDown = (msg.arg1 == 0) ? false : true;
3485cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) log("EVENT_CLEAN_UP_CONNECTION tearDown=" + tearDown);
3486cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (msg.obj instanceof ApnContext) {
3487cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    cleanUpConnection(tearDown, (ApnContext)msg.obj);
3488cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else {
34891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    onCleanUpConnection(tearDown, msg.arg2, (String) msg.obj);
3490cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
3491cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                break;
34921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_SET_INTERNAL_DATA_ENABLE: {
34931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                final boolean enabled = (msg.arg1 == DctConstants.ENABLED) ? true : false;
3494a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                onSetInternalDataEnabled(enabled, (Message) msg.obj);
3495a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                break;
34961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
3497a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case DctConstants.EVENT_CLEAN_UP_ALL_CONNECTIONS:
34981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if ((msg.obj != null) && (msg.obj instanceof String == false)) {
34991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    msg.obj = null;
3500a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                }
35011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onCleanUpAllConnections((String) msg.obj);
3502a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                break;
3503ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
3504220d43e0611edd0f3a2eb7a33bb38a008fff0868Wink Saville            case DctConstants.EVENT_DATA_RAT_CHANGED:
3505220d43e0611edd0f3a2eb7a33bb38a008fff0868Wink Saville                //May new Network allow setupData, so try it here
3506c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt                setupDataOnConnectableApns(Phone.REASON_NW_TYPE_CHANGED,
3507c2d1d6b2725b4611360d2725624a0d8905d75694Robert Greenwalt                        RetryFailures.ONLY_ON_CHANGE);
3508220d43e0611edd0f3a2eb7a33bb38a008fff0868Wink Saville                break;
3509220d43e0611edd0f3a2eb7a33bb38a008fff0868Wink Saville
35102b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen            case DctConstants.CMD_CLEAR_PROVISIONING_SPINNER:
35112b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                // Check message sender intended to clear the current spinner.
35122b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                if (mProvisioningSpinner == msg.obj) {
35132b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                    mProvisioningSpinner.dismiss();
35142b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                    mProvisioningSpinner = null;
35152b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                }
35162b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen                break;
35171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case AsyncChannel.CMD_CHANNEL_DISCONNECTED: {
35181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                log("DISCONNECTED_CONNECTED: msg=" + msg);
35191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                DcAsyncChannel dcac = (DcAsyncChannel) msg.obj;
35201a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mDataConnectionAcHashMap.remove(dcac.getDataConnectionIdSync());
35211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                dcac.disconnected();
35221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
35231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
35241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_ENABLE_NEW_APN:
35251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onEnableApn(msg.arg1, msg.arg2);
35261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
35271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
35281a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_DATA_STALL_ALARM:
35291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onDataStallAlarm(msg.arg1);
35301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
35311a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
35321a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_ROAMING_OFF:
35331a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onRoamingOff();
35341a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
35351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
35361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_ROAMING_ON:
35371a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onRoamingOn();
35381a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
35391a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
35401a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_RADIO_AVAILABLE:
35411a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onRadioAvailable();
35421a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
35431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
35441a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_RADIO_OFF_OR_NOT_AVAILABLE:
35451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onRadioOffOrNotAvailable();
35461a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
35471a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
35481a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_DATA_SETUP_COMPLETE:
35491a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onDataSetupComplete((AsyncResult) msg.obj);
35501a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
35511a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
35521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_DATA_SETUP_COMPLETE_ERROR:
35531a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onDataSetupCompleteError((AsyncResult) msg.obj);
35541a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
35551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_DISCONNECT_DONE:
35561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                log("DataConnectionTracker.handleMessage: EVENT_DISCONNECT_DONE msg=" + msg);
35571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onDisconnectDone((AsyncResult) msg.obj);
35581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
35591a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
35601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_DISCONNECT_DC_RETRYING:
35611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                log("DataConnectionTracker.handleMessage: EVENT_DISCONNECT_DC_RETRYING msg=" + msg);
35621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onDisconnectDcRetrying((AsyncResult) msg.obj);
35631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
35641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
35651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_VOICE_CALL_STARTED:
35661a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onVoiceCallStarted();
35671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
35681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
35691a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_VOICE_CALL_ENDED:
35701a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onVoiceCallEnded();
35711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
35721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
35731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_RESET_DONE: {
35741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) log("EVENT_RESET_DONE");
35751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onResetDone((AsyncResult) msg.obj);
35761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
35771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
35781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.CMD_SET_USER_DATA_ENABLE: {
35791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                final boolean enabled = (msg.arg1 == DctConstants.ENABLED) ? true : false;
35801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) log("CMD_SET_USER_DATA_ENABLE enabled=" + enabled);
35811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onSetUserDataEnabled(enabled);
35821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
35831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
35841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            // TODO - remove
35851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.CMD_SET_DEPENDENCY_MET: {
35861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                boolean met = (msg.arg1 == DctConstants.ENABLED) ? true : false;
35871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) log("CMD_SET_DEPENDENCY_MET met=" + met);
35881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                Bundle bundle = msg.getData();
35891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (bundle != null) {
35901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    String apnType = (String)bundle.get(DctConstants.APN_TYPE_KEY);
35911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (apnType != null) {
35921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        onSetDependencyMet(apnType, met);
35931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
35941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
35951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
35961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
35971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.CMD_SET_POLICY_DATA_ENABLE: {
35981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                final boolean enabled = (msg.arg1 == DctConstants.ENABLED) ? true : false;
35991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onSetPolicyDataEnabled(enabled);
36001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
36011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
36021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.CMD_SET_ENABLE_FAIL_FAST_MOBILE_DATA: {
36031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                sEnableFailFastRefCounter += (msg.arg1 == DctConstants.ENABLED) ? 1 : -1;
36041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) {
36051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    log("CMD_SET_ENABLE_FAIL_FAST_MOBILE_DATA: "
36061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            + " sEnableFailFastRefCounter=" + sEnableFailFastRefCounter);
36071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
36081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (sEnableFailFastRefCounter < 0) {
36091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    final String s = "CMD_SET_ENABLE_FAIL_FAST_MOBILE_DATA: "
36101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            + "sEnableFailFastRefCounter:" + sEnableFailFastRefCounter + " < 0";
36111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    loge(s);
36121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    sEnableFailFastRefCounter = 0;
36131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
36141a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                final boolean enabled = sEnableFailFastRefCounter > 0;
36151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) {
36161a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    log("CMD_SET_ENABLE_FAIL_FAST_MOBILE_DATA: enabled=" + enabled
36171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            + " sEnableFailFastRefCounter=" + sEnableFailFastRefCounter);
36181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
36191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (mFailFast != enabled) {
36201a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    mFailFast = enabled;
36210e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu
36221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    mDataStallDetectionEnabled = !enabled;
36231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (mDataStallDetectionEnabled
36241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            && (getOverallState() == DctConstants.State.CONNECTED)
36251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            && (!mInVoiceCall ||
36261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                                    mPhone.getServiceStateTracker()
36271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                                        .isConcurrentVoiceAndDataAllowed())) {
36281a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        if (DBG) log("CMD_SET_ENABLE_FAIL_FAST_MOBILE_DATA: start data stall");
36291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        stopDataStallAlarm();
36301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
36311a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    } else {
36321a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        if (DBG) log("CMD_SET_ENABLE_FAIL_FAST_MOBILE_DATA: stop data stall");
36331a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        stopDataStallAlarm();
36341a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
36351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
36362b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen
36371a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
36381a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
36391a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.CMD_ENABLE_MOBILE_PROVISIONING: {
36401a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                Bundle bundle = msg.getData();
36411a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (bundle != null) {
36421a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    try {
36431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        mProvisioningUrl = (String)bundle.get(DctConstants.PROVISIONING_URL_KEY);
36441a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    } catch(ClassCastException e) {
36451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        loge("CMD_ENABLE_MOBILE_PROVISIONING: provisioning url not a string" + e);
36461a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        mProvisioningUrl = null;
36471a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
36481a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
36491a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (TextUtils.isEmpty(mProvisioningUrl)) {
36501a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    loge("CMD_ENABLE_MOBILE_PROVISIONING: provisioning url is empty, ignoring");
36511a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    mIsProvisioning = false;
36521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    mProvisioningUrl = null;
36531a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                } else {
36541a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    loge("CMD_ENABLE_MOBILE_PROVISIONING: provisioningUrl=" + mProvisioningUrl);
36551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    mIsProvisioning = true;
36561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    startProvisioningApnAlarm();
36571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
36581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
36591a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
36601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_PROVISIONING_APN_ALARM: {
36611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) log("EVENT_PROVISIONING_APN_ALARM");
3662af5593594070f825032be46dced573cd195956e1Robert Greenwalt                ApnContext apnCtx = mApnContextsById.get(DctConstants.APN_DEFAULT_ID);
36631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (apnCtx.isProvisioningApn() && apnCtx.isConnectedOrConnecting()) {
36641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (mProvisioningApnAlarmTag == msg.arg1) {
36651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        if (DBG) log("EVENT_PROVISIONING_APN_ALARM: Disconnecting");
36661a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        mIsProvisioning = false;
36671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        mProvisioningUrl = null;
36681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        stopProvisioningApnAlarm();
36691a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        sendCleanUpConnection(true, apnCtx);
36701a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    } else {
36711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        if (DBG) {
36721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            log("EVENT_PROVISIONING_APN_ALARM: ignore stale tag,"
36731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                                    + " mProvisioningApnAlarmTag:" + mProvisioningApnAlarmTag
36741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                                    + " != arg1:" + msg.arg1);
36751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        }
36761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
36771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                } else {
36781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (DBG) log("EVENT_PROVISIONING_APN_ALARM: Not connected ignore");
36791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
36801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
36811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
36821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.CMD_IS_PROVISIONING_APN: {
36831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) log("CMD_IS_PROVISIONING_APN");
36841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                boolean isProvApn;
36851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                try {
36861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    String apnType = null;
36871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    Bundle bundle = msg.getData();
36881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (bundle != null) {
36891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        apnType = (String)bundle.get(DctConstants.APN_TYPE_KEY);
36901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
36911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (TextUtils.isEmpty(apnType)) {
36921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        loge("CMD_IS_PROVISIONING_APN: apnType is empty");
36931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        isProvApn = false;
36941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    } else {
36951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        isProvApn = isProvisioningApn(apnType);
36961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
36971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                } catch (ClassCastException e) {
36981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    loge("CMD_IS_PROVISIONING_APN: NO provisioning url ignoring");
36991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    isProvApn = false;
37001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
37011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) log("CMD_IS_PROVISIONING_APN: ret=" + isProvApn);
37021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mReplyAc.replyToMessage(msg, DctConstants.CMD_IS_PROVISIONING_APN,
37031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        isProvApn ? DctConstants.ENABLED : DctConstants.DISABLED);
37041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
37051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
37061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_ICC_CHANGED: {
37071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                onUpdateIcc();
37081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
37091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
37101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_RESTART_RADIO: {
37111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                restartRadio();
37121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
37131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
37141a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.CMD_NET_STAT_POLL: {
37151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (msg.arg1 == DctConstants.ENABLED) {
37161a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    handleStartNetStatPoll((DctConstants.Activity)msg.obj);
37171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                } else if (msg.arg1 == DctConstants.DISABLED) {
37181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    handleStopNetStatPoll((DctConstants.Activity)msg.obj);
37191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
37201a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
37211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
37221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case DctConstants.EVENT_DATA_STATE_CHANGED: {
37231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                // no longer do anything, but still registered - clean up log
37241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                // TODO - why are we still registering?
37251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
37261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
3727cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            default:
37281a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                Rlog.e("DcTracker", "Unhandled event=" + msg);
3729cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
37301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3731cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
3732cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    }
3733cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
37341a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private int getApnProfileID(String apnType) {
3735cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (TextUtils.equals(apnType, PhoneConstants.APN_TYPE_IMS)) {
3736cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return RILConstants.DATA_PROFILE_IMS;
3737cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else if (TextUtils.equals(apnType, PhoneConstants.APN_TYPE_FOTA)) {
3738cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return RILConstants.DATA_PROFILE_FOTA;
3739cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else if (TextUtils.equals(apnType, PhoneConstants.APN_TYPE_CBS)) {
3740cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return RILConstants.DATA_PROFILE_CBS;
37411b5fe200e47f40f82f0e28502a5f40bce64a82e6Wink Saville        } else if (TextUtils.equals(apnType, PhoneConstants.APN_TYPE_IA)) {
37421b5fe200e47f40f82f0e28502a5f40bce64a82e6Wink Saville            return RILConstants.DATA_PROFILE_DEFAULT; // DEFAULT for now
374345df26444864daad60afdd4d121ab4043da3834bSungmin Choi        } else if (TextUtils.equals(apnType, PhoneConstants.APN_TYPE_DUN)) {
374445df26444864daad60afdd4d121ab4043da3834bSungmin Choi            return RILConstants.DATA_PROFILE_TETHERED;
3745cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
3746cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return RILConstants.DATA_PROFILE_DEFAULT;
3747cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
3748cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
3749cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
3750cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private int getCellLocationId() {
3751cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        int cid = -1;
3752cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        CellLocation loc = mPhone.getCellLocation();
3753cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
3754cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (loc != null) {
3755cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (loc instanceof GsmCellLocation) {
3756cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                cid = ((GsmCellLocation)loc).getCid();
3757cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } else if (loc instanceof CdmaCellLocation) {
3758cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                cid = ((CdmaCellLocation)loc).getBaseStationId();
3759cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            }
3760cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
3761cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return cid;
3762cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    }
3763cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
3764a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private IccRecords getUiccRecords(int appFamily) {
3765a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        return mUiccController.getIccRecords(mPhone.getPhoneId(), appFamily);
3766a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
3767a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
3768a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
37691a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onUpdateIcc() {
3770cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (mUiccController == null ) {
3771cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            return;
3772cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
3773cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
3774a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        IccRecords newIccRecords = getUiccRecords(UiccController.APP_FAM_3GPP);
3775cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
3776cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        IccRecords r = mIccRecords.get();
3777cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (r != newIccRecords) {
3778cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (r != null) {
3779cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                log("Removing stale icc objects.");
3780cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                r.unregisterForRecordsLoaded(this);
3781cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mIccRecords.set(null);
37829aaa228cbb37657d12a87b5058676e449866f2acJeevaka Badrappan            }
3783cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (newIccRecords != null) {
37841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (SubscriptionManager.isValidSubscriptionId(mPhone.getSubId())) {
3785aa863054476b152fe9323defd197fa946a47033fSungmin Choi                    log("New records found.");
3786aa863054476b152fe9323defd197fa946a47033fSungmin Choi                    mIccRecords.set(newIccRecords);
3787aa863054476b152fe9323defd197fa946a47033fSungmin Choi                    newIccRecords.registerForRecordsLoaded(
3788aa863054476b152fe9323defd197fa946a47033fSungmin Choi                            this, DctConstants.EVENT_RECORDS_LOADED, null);
3789aa863054476b152fe9323defd197fa946a47033fSungmin Choi                }
37900469925aace7a2254e0cef90bd7398fbd72622faShishir Agrawal            } else {
37910469925aace7a2254e0cef90bd7398fbd72622faShishir Agrawal                onSimNotReady();
37929aaa228cbb37657d12a87b5058676e449866f2acJeevaka Badrappan            }
37939aaa228cbb37657d12a87b5058676e449866f2acJeevaka Badrappan        }
3794cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    }
3795cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
3796a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public void update() {
3797a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        log("update sub = " + mPhone.getSubId());
3798bda761320929f714951c328bfec6a51a1978db97Wink Saville        log("update(): Active DDS, register for all events now!");
3799bda761320929f714951c328bfec6a51a1978db97Wink Saville        registerForAllEvents();
3800bda761320929f714951c328bfec6a51a1978db97Wink Saville        onUpdateIcc();
3801a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
38022bb2331aa5c5285f70a7404d61ee71ede4831056Shishir Agrawal        mUserDataEnabled = getDataEnabled();
3803bda761320929f714951c328bfec6a51a1978db97Wink Saville
38041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        ((GsmCdmaPhone)mPhone).updateCurrentCarrierInProvider();
3805a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
3806a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
3807a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public void cleanUpAllConnections(String cause) {
3808a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        cleanUpAllConnections(cause, null);
3809a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
3810a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
3811a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public void updateRecords() {
3812bda761320929f714951c328bfec6a51a1978db97Wink Saville        onUpdateIcc();
3813a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
3814a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
3815a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public void cleanUpAllConnections(String cause, Message disconnectAllCompleteMsg) {
3816a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        log("cleanUpAllConnections");
3817a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (disconnectAllCompleteMsg != null) {
3818a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mDisconnectAllCompleteMsgList.add(disconnectAllCompleteMsg);
3819a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
3820a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
3821a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        Message msg = obtainMessage(DctConstants.EVENT_CLEAN_UP_ALL_CONNECTIONS);
3822a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        msg.obj = cause;
3823a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        sendMessage(msg);
3824a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
3825a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
38261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void notifyDataDisconnectComplete() {
3827a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        log("notifyDataDisconnectComplete");
3828a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        for (Message m: mDisconnectAllCompleteMsgList) {
3829a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            m.sendToTarget();
3830a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
3831a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mDisconnectAllCompleteMsgList.clear();
3832a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
3833a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
3834a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
38351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void notifyAllDataDisconnected() {
3836a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        sEnableFailFastRefCounter = 0;
3837a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mFailFast = false;
3838a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mAllDataDisconnectedRegistrants.notifyRegistrants();
3839a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
3840a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
3841a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public void registerForAllDataDisconnected(Handler h, int what, Object obj) {
3842a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mAllDataDisconnectedRegistrants.addUnique(h, what, obj);
3843a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
3844a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (isDisconnected()) {
3845a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            log("notify All Data Disconnected");
3846a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            notifyAllDataDisconnected();
3847a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
3848a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
3849a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
3850a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public void unregisterForAllDataDisconnected(Handler h) {
3851a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mAllDataDisconnectedRegistrants.remove(h);
3852a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
3853a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
3854a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
38551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onSetInternalDataEnabled(boolean enabled, Message onCompleteMsg) {
38566bc4098827f3070a44b5e51508b455d7c7be9c07Wink Saville        if (DBG) log("onSetInternalDataEnabled: enabled=" + enabled);
3857a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        boolean sendOnComplete = true;
3858a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
3859a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        synchronized (mDataEnabledLock) {
3860a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mInternalDataEnabled = enabled;
3861a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (enabled) {
3862a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                log("onSetInternalDataEnabled: changed to enabled, try to setup data call");
3863a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                onTrySetupData(Phone.REASON_DATA_ENABLED);
3864a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            } else {
3865a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                sendOnComplete = false;
3866a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                log("onSetInternalDataEnabled: changed to disabled, cleanUpAllConnections");
3867a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                cleanUpAllConnections(null, onCompleteMsg);
3868a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
3869a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
3870a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
3871a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (sendOnComplete) {
3872a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (onCompleteMsg != null) {
3873a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                onCompleteMsg.sendToTarget();
3874a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
3875a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
3876a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
3877a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
3878a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public boolean setInternalDataEnabledFlag(boolean enable) {
38796bc4098827f3070a44b5e51508b455d7c7be9c07Wink Saville        if (DBG) log("setInternalDataEnabledFlag(" + enable + ")");
3880a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
3881a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (mInternalDataEnabled != enable) {
3882a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mInternalDataEnabled = enable;
3883a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
3884a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        return true;
3885a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
3886a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
3887a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public boolean setInternalDataEnabled(boolean enable) {
3888a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        return setInternalDataEnabled(enable, null);
3889a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
3890a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
3891a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public boolean setInternalDataEnabled(boolean enable, Message onCompleteMsg) {
38926bc4098827f3070a44b5e51508b455d7c7be9c07Wink Saville        if (DBG) log("setInternalDataEnabled(" + enable + ")");
3893a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
3894a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        Message msg = obtainMessage(DctConstants.EVENT_SET_INTERNAL_DATA_ENABLE, onCompleteMsg);
3895a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        msg.arg1 = (enable ? DctConstants.ENABLED : DctConstants.DISABLED);
3896a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        sendMessage(msg);
3897a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        return true;
3898a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
3899a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
3900a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public void setDataAllowed(boolean enable, Message response) {
39016bc4098827f3070a44b5e51508b455d7c7be9c07Wink Saville         if (DBG) log("setDataAllowed: enable=" + enable);
39021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu         isCleanupRequired.set(!enable);
3903a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville         mPhone.mCi.setDataAllowed(enable, response);
3904a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville         mInternalDataEnabled = enable;
3905a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
3906a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
39071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void log(String s) {
3908a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        Rlog.d(LOG_TAG, "[" + mPhone.getPhoneId() + "]" + s);
3909cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    }
3910cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
39111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void loge(String s) {
3912a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        Rlog.e(LOG_TAG, "[" + mPhone.getPhoneId() + "]" + s);
3913cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    }
3914cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
3915c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
39161a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println("DcTracker:");
39171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" RADIO_TESTS=" + RADIO_TESTS);
39181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mInternalDataEnabled=" + mInternalDataEnabled);
39191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mUserDataEnabled=" + mUserDataEnabled);
39201a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" sPolicyDataEnabed=" + sPolicyDataEnabled);
39211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.flush();
39221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mRequestedApnType=" + mRequestedApnType);
39231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mPhone=" + mPhone.getPhoneName());
39241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mActivity=" + mActivity);
39251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mState=" + mState);
39261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mTxPkts=" + mTxPkts);
39271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mRxPkts=" + mRxPkts);
39281a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mNetStatPollPeriod=" + mNetStatPollPeriod);
39291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mNetStatPollEnabled=" + mNetStatPollEnabled);
39301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mDataStallTxRxSum=" + mDataStallTxRxSum);
39311a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mDataStallAlarmTag=" + mDataStallAlarmTag);
39321a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mDataStallDetectionEanbled=" + mDataStallDetectionEnabled);
39331a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mSentSinceLastRecv=" + mSentSinceLastRecv);
39341a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mNoRecvPollCount=" + mNoRecvPollCount);
39351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mResolver=" + mResolver);
39361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mIsWifiConnected=" + mIsWifiConnected);
39371a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mReconnectIntent=" + mReconnectIntent);
39381a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mAutoAttachOnCreation=" + mAutoAttachOnCreation.get());
39391a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mIsScreenOn=" + mIsScreenOn);
39401a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mUniqueIdGenerator=" + mUniqueIdGenerator);
39411a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.flush();
39421a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" ***************************************");
39431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        DcController dcc = mDcc;
39441a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (dcc != null) {
39451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            dcc.dump(fd, pw, args);
39461a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else {
39471a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            pw.println(" mDcc=null");
39481a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
39491a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" ***************************************");
39501a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        HashMap<Integer, DataConnection> dcs = mDataConnections;
39511a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (dcs != null) {
39521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            Set<Entry<Integer, DataConnection> > mDcSet = mDataConnections.entrySet();
39531a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            pw.println(" mDataConnections: count=" + mDcSet.size());
39541a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            for (Entry<Integer, DataConnection> entry : mDcSet) {
39551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                pw.printf(" *** mDataConnection[%d] \n", entry.getKey());
39561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                entry.getValue().dump(fd, pw, args);
39571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
39581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else {
39591a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            pw.println("mDataConnections=null");
39601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
39611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" ***************************************");
39621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.flush();
39631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        HashMap<String, Integer> apnToDcId = mApnToDataConnectionId;
39641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (apnToDcId != null) {
39651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            Set<Entry<String, Integer>> apnToDcIdSet = apnToDcId.entrySet();
39661a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            pw.println(" mApnToDataConnectonId size=" + apnToDcIdSet.size());
39671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            for (Entry<String, Integer> entry : apnToDcIdSet) {
39681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                pw.printf(" mApnToDataConnectonId[%s]=%d\n", entry.getKey(), entry.getValue());
39691a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
39701a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else {
39711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            pw.println("mApnToDataConnectionId=null");
39721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
39731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" ***************************************");
39741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.flush();
39751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        ConcurrentHashMap<String, ApnContext> apnCtxs = mApnContexts;
39761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (apnCtxs != null) {
39771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            Set<Entry<String, ApnContext>> apnCtxsSet = apnCtxs.entrySet();
39781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            pw.println(" mApnContexts size=" + apnCtxsSet.size());
39791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            for (Entry<String, ApnContext> entry : apnCtxsSet) {
39801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                entry.getValue().dump(fd, pw, args);
39811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
39821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            pw.println(" ***************************************");
39831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else {
39841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            pw.println(" mApnContexts=null");
39851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
39861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.flush();
39871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        ArrayList<ApnSetting> apnSettings = mAllApnSettings;
39881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (apnSettings != null) {
39891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            pw.println(" mAllApnSettings size=" + apnSettings.size());
39901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            for (int i=0; i < apnSettings.size(); i++) {
39911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                pw.printf(" mAllApnSettings[%d]: %s\n", i, apnSettings.get(i));
39921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
39931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            pw.flush();
39941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else {
39951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            pw.println(" mAllApnSettings=null");
39961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
39971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mPreferredApn=" + mPreferredApn);
39981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mIsPsRestricted=" + mIsPsRestricted);
39991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mIsDisposed=" + mIsDisposed);
40001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mIntentReceiver=" + mIntentReceiver);
40011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mDataRoamingSettingObserver=" + mDataRoamingSettingObserver);
4002cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        pw.println(" mReregisterOnReconnectFailure=" + mReregisterOnReconnectFailure);
400322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" canSetPreferApn=" + mCanSetPreferApn);
4004cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        pw.println(" mApnObserver=" + mApnObserver);
4005cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        pw.println(" getOverallState=" + getOverallState());
4006ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        pw.println(" mDataConnectionAsyncChannels=%s\n" + mDataConnectionAcHashMap);
4007187a39f896f88eb6c5e4306d9595546654825976Wink Saville        pw.println(" mAttached=" + mAttached.get());
40081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.flush();
4009c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
4010a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4011bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram    public String[] getPcscfAddress(String apnType) {
4012a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        log("getPcscfAddress()");
4013bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram        ApnContext apnContext = null;
4014bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram
4015bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram        if(apnType == null){
4016bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram            log("apnType is null, return null");
4017bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram            return null;
4018bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram        }
4019a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4020bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram        if (TextUtils.equals(apnType, PhoneConstants.APN_TYPE_EMERGENCY)) {
4021af5593594070f825032be46dced573cd195956e1Robert Greenwalt            apnContext = mApnContextsById.get(DctConstants.APN_EMERGENCY_ID);
4022bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram        } else if (TextUtils.equals(apnType, PhoneConstants.APN_TYPE_IMS)) {
4023af5593594070f825032be46dced573cd195956e1Robert Greenwalt            apnContext = mApnContextsById.get(DctConstants.APN_IMS_ID);
4024bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram        } else {
4025bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram            log("apnType is invalid, return null");
4026bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram            return null;
4027bc78e2f9988f380a3b88d4cb4a9c0b80b8f44beeram        }
4028a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4029a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (apnContext == null) {
4030a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            log("apnContext is null, return null");
4031a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            return null;
4032a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
4033a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4034a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        DcAsyncChannel dcac = apnContext.getDcAc();
4035a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        String[] result = null;
4036a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4037a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (dcac != null) {
4038a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            result = dcac.getPcscfAddr();
4039a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4040a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            for (int i = 0; i < result.length; i++) {
4041a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                log("Pcscf[" + i + "]: " + result[i]);
4042a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
4043a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            return result;
4044a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
4045a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        return null;
4046a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
4047a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
404876f43316a5a6082d601bffd4b6898d0bd81e11fcram    /**
404976f43316a5a6082d601bffd4b6898d0bd81e11fcram     * Read APN configuration from Telephony.db for Emergency APN
405076f43316a5a6082d601bffd4b6898d0bd81e11fcram     * All opertors recognize the connection request for EPDN based on APN type
405176f43316a5a6082d601bffd4b6898d0bd81e11fcram     * PLMN name,APN name are not mandatory parameters
405276f43316a5a6082d601bffd4b6898d0bd81e11fcram     */
405376f43316a5a6082d601bffd4b6898d0bd81e11fcram    private void initEmergencyApnSetting() {
405476f43316a5a6082d601bffd4b6898d0bd81e11fcram        // Operator Numeric is not available when sim records are not loaded.
405576f43316a5a6082d601bffd4b6898d0bd81e11fcram        // Query Telephony.db with APN type as EPDN request does not
405676f43316a5a6082d601bffd4b6898d0bd81e11fcram        // require APN name, plmn and all operators support same APN config.
405776f43316a5a6082d601bffd4b6898d0bd81e11fcram        // DB will contain only one entry for Emergency APN
405876f43316a5a6082d601bffd4b6898d0bd81e11fcram        String selection = "type=\"emergency\"";
405976f43316a5a6082d601bffd4b6898d0bd81e11fcram        Cursor cursor = mPhone.getContext().getContentResolver().query(
406076f43316a5a6082d601bffd4b6898d0bd81e11fcram                Telephony.Carriers.CONTENT_URI, null, selection, null, null);
406176f43316a5a6082d601bffd4b6898d0bd81e11fcram
406276f43316a5a6082d601bffd4b6898d0bd81e11fcram        if (cursor != null) {
406376f43316a5a6082d601bffd4b6898d0bd81e11fcram            if (cursor.getCount() > 0) {
406476f43316a5a6082d601bffd4b6898d0bd81e11fcram                if (cursor.moveToFirst()) {
406576f43316a5a6082d601bffd4b6898d0bd81e11fcram                    mEmergencyApn = makeApnSetting(cursor);
406676f43316a5a6082d601bffd4b6898d0bd81e11fcram                }
406776f43316a5a6082d601bffd4b6898d0bd81e11fcram            }
406876f43316a5a6082d601bffd4b6898d0bd81e11fcram            cursor.close();
406976f43316a5a6082d601bffd4b6898d0bd81e11fcram        }
407076f43316a5a6082d601bffd4b6898d0bd81e11fcram    }
407176f43316a5a6082d601bffd4b6898d0bd81e11fcram
407276f43316a5a6082d601bffd4b6898d0bd81e11fcram    /**
407376f43316a5a6082d601bffd4b6898d0bd81e11fcram     * Add the Emergency APN settings to APN settings list
407476f43316a5a6082d601bffd4b6898d0bd81e11fcram     */
407576f43316a5a6082d601bffd4b6898d0bd81e11fcram    private void addEmergencyApnSetting() {
407676f43316a5a6082d601bffd4b6898d0bd81e11fcram        if(mEmergencyApn != null) {
407776f43316a5a6082d601bffd4b6898d0bd81e11fcram            if(mAllApnSettings == null) {
407876f43316a5a6082d601bffd4b6898d0bd81e11fcram                mAllApnSettings = new ArrayList<ApnSetting>();
407976f43316a5a6082d601bffd4b6898d0bd81e11fcram            } else {
408076f43316a5a6082d601bffd4b6898d0bd81e11fcram                boolean hasEmergencyApn = false;
408176f43316a5a6082d601bffd4b6898d0bd81e11fcram                for (ApnSetting apn : mAllApnSettings) {
408276f43316a5a6082d601bffd4b6898d0bd81e11fcram                    if (ArrayUtils.contains(apn.types, PhoneConstants.APN_TYPE_EMERGENCY)) {
408376f43316a5a6082d601bffd4b6898d0bd81e11fcram                        hasEmergencyApn = true;
408476f43316a5a6082d601bffd4b6898d0bd81e11fcram                        break;
408576f43316a5a6082d601bffd4b6898d0bd81e11fcram                    }
408676f43316a5a6082d601bffd4b6898d0bd81e11fcram                }
408776f43316a5a6082d601bffd4b6898d0bd81e11fcram
408876f43316a5a6082d601bffd4b6898d0bd81e11fcram                if(hasEmergencyApn == false) {
408976f43316a5a6082d601bffd4b6898d0bd81e11fcram                    mAllApnSettings.add(mEmergencyApn);
409076f43316a5a6082d601bffd4b6898d0bd81e11fcram                } else {
409176f43316a5a6082d601bffd4b6898d0bd81e11fcram                    log("addEmergencyApnSetting - E-APN setting is already present");
409276f43316a5a6082d601bffd4b6898d0bd81e11fcram                }
409376f43316a5a6082d601bffd4b6898d0bd81e11fcram            }
409476f43316a5a6082d601bffd4b6898d0bd81e11fcram        }
409576f43316a5a6082d601bffd4b6898d0bd81e11fcram    }
40969a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang
40979a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang    private void cleanUpConnectionsOnUpdatedApns(boolean tearDown) {
40989a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang        if (DBG) log("cleanUpConnectionsOnUpdatedApns: tearDown=" + tearDown);
40999a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang        if (mAllApnSettings.isEmpty()) {
41009a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang            cleanUpAllConnections(tearDown, Phone.REASON_APN_CHANGED);
41019a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang        } else {
41029a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang            for (ApnContext apnContext : mApnContexts.values()) {
41039a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang                if (VDBG) log("cleanUpConnectionsOnUpdatedApns for "+ apnContext);
41049a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang
41059a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang                boolean cleanUpApn = true;
41069a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang                ArrayList<ApnSetting> currentWaitingApns = apnContext.getWaitingApns();
41079a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang
41089a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang                if ((currentWaitingApns != null) && (!apnContext.isDisconnected())) {
41099a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang                    int radioTech = mPhone.getServiceState().getRilDataRadioTechnology();
41109a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang                    ArrayList<ApnSetting> waitingApns = buildWaitingApns(
41119a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang                            apnContext.getApnType(), radioTech);
41129a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang                    if (VDBG) log("new waitingApns:" + waitingApns);
41139a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang                    if (waitingApns.size() == currentWaitingApns.size()) {
41149a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang                        cleanUpApn = false;
41159a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang                        for (int i = 0; i < waitingApns.size(); i++) {
41169a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang                            if (!currentWaitingApns.get(i).equals(waitingApns.get(i))) {
41179a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang                                if (VDBG) log("new waiting apn is different at " + i);
41189a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang                                cleanUpApn = true;
41199a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang                                apnContext.setWaitingApns(waitingApns);
41209a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang                                break;
41219a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang                            }
41229a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang                        }
41239a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang                    }
41249a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang                }
41259a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang
41269a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang                if (cleanUpApn) {
41279a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang                    apnContext.setReason(Phone.REASON_APN_CHANGED);
41289a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang                    cleanUpConnection(true, apnContext);
41299a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang                }
41309a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang            }
41319a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang        }
41329a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang
41339a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang        if (!isConnected()) {
41349a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang            stopNetStatPoll();
41359a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang            stopDataStallAlarm();
41369a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang        }
41379a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang
41389a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang        mRequestedApnType = PhoneConstants.APN_TYPE_DEFAULT;
41399a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang
41409a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang        if (DBG) log("mDisconnectPendingCount = " + mDisconnectPendingCount);
41419a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang        if (tearDown && mDisconnectPendingCount == 0) {
41429a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang            notifyDataDisconnectComplete();
41439a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang            notifyAllDataDisconnected();
41449a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang        }
41459a90f1dde8fa4bd7b1606742909c2f2f28a28a2fHui Wang    }
41461a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
41471a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /**
41481a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * Polling stuff
41491a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     */
41501a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void resetPollStats() {
41511a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mTxPkts = -1;
41521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mRxPkts = -1;
41531a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mNetStatPollPeriod = POLL_NETSTAT_MILLIS;
41541a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
41551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
41561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void startNetStatPoll() {
41571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (getOverallState() == DctConstants.State.CONNECTED
41581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                && mNetStatPollEnabled == false) {
41591a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) {
41601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                log("startNetStatPoll");
41611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
41621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            resetPollStats();
41631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mNetStatPollEnabled = true;
41641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mPollNetStat.run();
41651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
41661a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (mPhone != null) {
41671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mPhone.notifyDataActivity();
41681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
41691a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
41701a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
41711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void stopNetStatPoll() {
41721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mNetStatPollEnabled = false;
41731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        removeCallbacks(mPollNetStat);
41741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (DBG) {
41751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            log("stopNetStatPoll");
41761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
41771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
41781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        // To sync data activity icon in the case of switching data connection to send MMS.
41791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (mPhone != null) {
41801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mPhone.notifyDataActivity();
41811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
41821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
41831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
41841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    public void sendStartNetStatPoll(DctConstants.Activity activity) {
41851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        Message msg = obtainMessage(DctConstants.CMD_NET_STAT_POLL);
41861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        msg.arg1 = DctConstants.ENABLED;
41871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        msg.obj = activity;
41881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        sendMessage(msg);
41891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
41901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
41911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void handleStartNetStatPoll(DctConstants.Activity activity) {
41921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        startNetStatPoll();
41931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
41941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        setActivity(activity);
41951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
41961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
41971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    public void sendStopNetStatPoll(DctConstants.Activity activity) {
41981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        Message msg = obtainMessage(DctConstants.CMD_NET_STAT_POLL);
41991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        msg.arg1 = DctConstants.DISABLED;
42001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        msg.obj = activity;
42011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        sendMessage(msg);
42021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
42031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
42041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void handleStopNetStatPoll(DctConstants.Activity activity) {
42051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        stopNetStatPoll();
42061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        stopDataStallAlarm();
42071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        setActivity(activity);
42081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
42091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
42101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void updateDataActivity() {
42111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        long sent, received;
42121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
42131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        DctConstants.Activity newActivity;
42141a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
42151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        TxRxSum preTxRxSum = new TxRxSum(mTxPkts, mRxPkts);
42161a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        TxRxSum curTxRxSum = new TxRxSum();
42171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        curTxRxSum.updateTxRxSum();
42181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mTxPkts = curTxRxSum.txPkts;
42191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mRxPkts = curTxRxSum.rxPkts;
42201a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
42211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (VDBG) {
42221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            log("updateDataActivity: curTxRxSum=" + curTxRxSum + " preTxRxSum=" + preTxRxSum);
42231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
42241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
42251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (mNetStatPollEnabled && (preTxRxSum.txPkts > 0 || preTxRxSum.rxPkts > 0)) {
42261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            sent = mTxPkts - preTxRxSum.txPkts;
42271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            received = mRxPkts - preTxRxSum.rxPkts;
42281a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
42291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (VDBG)
42301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                log("updateDataActivity: sent=" + sent + " received=" + received);
42311a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (sent > 0 && received > 0) {
42321a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                newActivity = DctConstants.Activity.DATAINANDOUT;
42331a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else if (sent > 0 && received == 0) {
42341a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                newActivity = DctConstants.Activity.DATAOUT;
42351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else if (sent == 0 && received > 0) {
42361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                newActivity = DctConstants.Activity.DATAIN;
42371a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else {
42381a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                newActivity = (mActivity == DctConstants.Activity.DORMANT) ?
42391a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        mActivity : DctConstants.Activity.NONE;
42401a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
42411a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
42421a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (mActivity != newActivity && mIsScreenOn) {
42431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (VDBG)
42441a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    log("updateDataActivity: newActivity=" + newActivity);
42451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mActivity = newActivity;
42461a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mPhone.notifyDataActivity();
42471a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
42481a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
42491a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
42501a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
42511a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /**
42521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * Data-Stall
42531a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     */
42541a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // Recovery action taken in case of data stall
42551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static class RecoveryAction {
42561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public static final int GET_DATA_CALL_LIST      = 0;
42571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public static final int CLEANUP                 = 1;
42581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public static final int REREGISTER              = 2;
42591a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public static final int RADIO_RESTART           = 3;
42601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public static final int RADIO_RESTART_WITH_PROP = 4;
42611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
42621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        private static boolean isAggressiveRecovery(int value) {
42631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            return ((value == RecoveryAction.CLEANUP) ||
42641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    (value == RecoveryAction.REREGISTER) ||
42651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    (value == RecoveryAction.RADIO_RESTART) ||
42661a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    (value == RecoveryAction.RADIO_RESTART_WITH_PROP));
42671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
42681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
42691a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
42701a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private int getRecoveryAction() {
42711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        int action = Settings.System.getInt(mResolver,
42721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                "radio.data.stall.recovery.action", RecoveryAction.GET_DATA_CALL_LIST);
42731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (VDBG_STALL) log("getRecoveryAction: " + action);
42741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        return action;
42751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
42761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
42771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void putRecoveryAction(int action) {
42781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        Settings.System.putInt(mResolver, "radio.data.stall.recovery.action", action);
42791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (VDBG_STALL) log("putRecoveryAction: " + action);
42801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
42811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
42821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void doRecovery() {
42831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (getOverallState() == DctConstants.State.CONNECTED) {
42841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            // Go through a series of recovery steps, each action transitions to the next action
42851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            int recoveryAction = getRecoveryAction();
42861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            switch (recoveryAction) {
42871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case RecoveryAction.GET_DATA_CALL_LIST:
42881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                EventLog.writeEvent(EventLogTags.DATA_STALL_RECOVERY_GET_DATA_CALL_LIST,
42891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        mSentSinceLastRecv);
42901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) log("doRecovery() get data call list");
42911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mPhone.mCi.getDataCallList(obtainMessage(DctConstants.EVENT_DATA_STATE_CHANGED));
42921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                putRecoveryAction(RecoveryAction.CLEANUP);
42931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
42941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case RecoveryAction.CLEANUP:
42951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                EventLog.writeEvent(EventLogTags.DATA_STALL_RECOVERY_CLEANUP, mSentSinceLastRecv);
42961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) log("doRecovery() cleanup all connections");
42971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                cleanUpAllConnections(Phone.REASON_PDP_RESET);
42981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                putRecoveryAction(RecoveryAction.REREGISTER);
42991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
43001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case RecoveryAction.REREGISTER:
43011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                EventLog.writeEvent(EventLogTags.DATA_STALL_RECOVERY_REREGISTER,
43021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        mSentSinceLastRecv);
43031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) log("doRecovery() re-register");
43041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mPhone.getServiceStateTracker().reRegisterNetwork(null);
43051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                putRecoveryAction(RecoveryAction.RADIO_RESTART);
43061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
43071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case RecoveryAction.RADIO_RESTART:
43081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                EventLog.writeEvent(EventLogTags.DATA_STALL_RECOVERY_RADIO_RESTART,
43091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        mSentSinceLastRecv);
43101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) log("restarting radio");
43111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                putRecoveryAction(RecoveryAction.RADIO_RESTART_WITH_PROP);
43121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                restartRadio();
43131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
43141a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case RecoveryAction.RADIO_RESTART_WITH_PROP:
43151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                // This is in case radio restart has not recovered the data.
43161a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                // It will set an additional "gsm.radioreset" property to tell
43171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                // RIL or system to take further action.
43181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                // The implementation of hard reset recovery action is up to OEM product.
43191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                // Once RADIO_RESET property is consumed, it is expected to set back
43201a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                // to false by RIL.
43211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                EventLog.writeEvent(EventLogTags.DATA_STALL_RECOVERY_RADIO_RESTART_WITH_PROP, -1);
43221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) log("restarting radio with gsm.radioreset to true");
43231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                SystemProperties.set(RADIO_RESET_PROPERTY, "true");
43241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                // give 1 sec so property change can be notified.
43251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                try {
43261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    Thread.sleep(1000);
43271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                } catch (InterruptedException e) {}
43281a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                restartRadio();
43291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                putRecoveryAction(RecoveryAction.GET_DATA_CALL_LIST);
43301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
43311a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            default:
43321a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                throw new RuntimeException("doRecovery: Invalid recoveryAction=" +
43331a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    recoveryAction);
43341a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
43351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mSentSinceLastRecv = 0;
43361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
43371a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
43381a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
43391a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void updateDataStallInfo() {
43401a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        long sent, received;
43411a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
43421a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        TxRxSum preTxRxSum = new TxRxSum(mDataStallTxRxSum);
43431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mDataStallTxRxSum.updateTxRxSum();
43441a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
43451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (VDBG_STALL) {
43461a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            log("updateDataStallInfo: mDataStallTxRxSum=" + mDataStallTxRxSum +
43471a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    " preTxRxSum=" + preTxRxSum);
43481a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
43491a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
43501a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        sent = mDataStallTxRxSum.txPkts - preTxRxSum.txPkts;
43511a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        received = mDataStallTxRxSum.rxPkts - preTxRxSum.rxPkts;
43521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
43531a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (RADIO_TESTS) {
43541a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (SystemProperties.getBoolean("radio.test.data.stall", false)) {
43551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                log("updateDataStallInfo: radio.test.data.stall true received = 0;");
43561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                received = 0;
43571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
43581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
43591a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if ( sent > 0 && received > 0 ) {
43601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (VDBG_STALL) log("updateDataStallInfo: IN/OUT");
43611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mSentSinceLastRecv = 0;
43621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            putRecoveryAction(RecoveryAction.GET_DATA_CALL_LIST);
43631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else if (sent > 0 && received == 0) {
43641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (mPhone.getState() == PhoneConstants.State.IDLE) {
43651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mSentSinceLastRecv += sent;
43661a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else {
43671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mSentSinceLastRecv = 0;
43681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
43691a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) {
43701a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                log("updateDataStallInfo: OUT sent=" + sent +
43711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        " mSentSinceLastRecv=" + mSentSinceLastRecv);
43721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
43731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else if (sent == 0 && received > 0) {
43741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (VDBG_STALL) log("updateDataStallInfo: IN");
43751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mSentSinceLastRecv = 0;
43761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            putRecoveryAction(RecoveryAction.GET_DATA_CALL_LIST);
43771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else {
43781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (VDBG_STALL) log("updateDataStallInfo: NONE");
43791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
43801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
43811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
43821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onDataStallAlarm(int tag) {
43831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (mDataStallAlarmTag != tag) {
43841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) {
43851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                log("onDataStallAlarm: ignore, tag=" + tag + " expecting " + mDataStallAlarmTag);
43861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
43871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            return;
43881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
43891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        updateDataStallInfo();
43901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
43911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        int hangWatchdogTrigger = Settings.Global.getInt(mResolver,
43921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                Settings.Global.PDP_WATCHDOG_TRIGGER_PACKET_COUNT,
43931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                NUMBER_SENT_PACKETS_OF_HANG);
43941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
43951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        boolean suspectedStall = DATA_STALL_NOT_SUSPECTED;
43961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (mSentSinceLastRecv >= hangWatchdogTrigger) {
43971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) {
43981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                log("onDataStallAlarm: tag=" + tag + " do recovery action=" + getRecoveryAction());
43991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
44001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            suspectedStall = DATA_STALL_SUSPECTED;
44011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            sendMessage(obtainMessage(DctConstants.EVENT_DO_RECOVERY));
44021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else {
44031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (VDBG_STALL) {
44041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                log("onDataStallAlarm: tag=" + tag + " Sent " + String.valueOf(mSentSinceLastRecv) +
44051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    " pkts since last received, < watchdogTrigger=" + hangWatchdogTrigger);
44061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
44071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
44081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        startDataStallAlarm(suspectedStall);
44091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
44101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
44111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void startDataStallAlarm(boolean suspectedStall) {
44121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        int nextAction = getRecoveryAction();
44131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        int delayInMs;
44141a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
44151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (mDataStallDetectionEnabled && getOverallState() == DctConstants.State.CONNECTED) {
44161a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            // If screen is on or data stall is currently suspected, set the alarm
44170e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            // with an aggressive timeout.
44181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (mIsScreenOn || suspectedStall || RecoveryAction.isAggressiveRecovery(nextAction)) {
44191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                delayInMs = Settings.Global.getInt(mResolver,
44201a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        Settings.Global.DATA_STALL_ALARM_AGGRESSIVE_DELAY_IN_MS,
44211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        DATA_STALL_ALARM_AGGRESSIVE_DELAY_IN_MS_DEFAULT);
44221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else {
44231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                delayInMs = Settings.Global.getInt(mResolver,
44241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        Settings.Global.DATA_STALL_ALARM_NON_AGGRESSIVE_DELAY_IN_MS,
44251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        DATA_STALL_ALARM_NON_AGGRESSIVE_DELAY_IN_MS_DEFAULT);
44261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
44271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
44281a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mDataStallAlarmTag += 1;
44291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (VDBG_STALL) {
44301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                log("startDataStallAlarm: tag=" + mDataStallAlarmTag +
44311a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        " delay=" + (delayInMs / 1000) + "s");
44321a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
44331a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            Intent intent = new Intent(INTENT_DATA_STALL_ALARM);
44341a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            intent.putExtra(DATA_STALL_ALARM_TAG_EXTRA, mDataStallAlarmTag);
44351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mDataStallAlarmIntent = PendingIntent.getBroadcast(mPhone.getContext(), 0, intent,
44361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    PendingIntent.FLAG_UPDATE_CURRENT);
44371a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
44381a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    SystemClock.elapsedRealtime() + delayInMs, mDataStallAlarmIntent);
44391a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else {
44401a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (VDBG_STALL) {
44411a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                log("startDataStallAlarm: NOT started, no connection tag=" + mDataStallAlarmTag);
44421a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
44431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
44441a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
44451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
44461a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void stopDataStallAlarm() {
44471a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (VDBG_STALL) {
44481a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            log("stopDataStallAlarm: current tag=" + mDataStallAlarmTag +
44491a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    " mDataStallAlarmIntent=" + mDataStallAlarmIntent);
44501a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
44511a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mDataStallAlarmTag += 1;
44521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (mDataStallAlarmIntent != null) {
44531a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mAlarmManager.cancel(mDataStallAlarmIntent);
44541a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mDataStallAlarmIntent = null;
44551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
44561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
44571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
44581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void restartDataStallAlarm() {
44591a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (isConnected() == false) return;
44601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        // To be called on screen status change.
44611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        // Do not cancel the alarm if it is set with aggressive timeout.
44621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        int nextAction = getRecoveryAction();
44631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
44641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (RecoveryAction.isAggressiveRecovery(nextAction)) {
44651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (DBG) log("restartDataStallAlarm: action is pending. not resetting the alarm.");
44661a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            return;
44671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
44681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (VDBG_STALL) log("restartDataStallAlarm: stop then start.");
44691a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        stopDataStallAlarm();
44701a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
44711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
44721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
44731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /**
44741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * Provisioning APN
44751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     */
44761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void onActionIntentProvisioningApnAlarm(Intent intent) {
44771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (DBG) log("onActionIntentProvisioningApnAlarm: action=" + intent.getAction());
44781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        Message msg = obtainMessage(DctConstants.EVENT_PROVISIONING_APN_ALARM,
44791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                intent.getAction());
44801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        msg.arg1 = intent.getIntExtra(PROVISIONING_APN_ALARM_TAG_EXTRA, 0);
44811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        sendMessage(msg);
44821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
44831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
44841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void startProvisioningApnAlarm() {
44851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        int delayInMs = Settings.Global.getInt(mResolver,
44861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                                Settings.Global.PROVISIONING_APN_ALARM_DELAY_IN_MS,
44871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                                PROVISIONING_APN_ALARM_DELAY_IN_MS_DEFAULT);
44881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (Build.IS_DEBUGGABLE) {
44891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            // Allow debug code to use a system property to provide another value
44901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            String delayInMsStrg = Integer.toString(delayInMs);
44911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            delayInMsStrg = System.getProperty(DEBUG_PROV_APN_ALARM, delayInMsStrg);
44921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            try {
44931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                delayInMs = Integer.parseInt(delayInMsStrg);
44941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } catch (NumberFormatException e) {
44951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                loge("startProvisioningApnAlarm: e=" + e);
44961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
44971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
44981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mProvisioningApnAlarmTag += 1;
44991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (DBG) {
45001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            log("startProvisioningApnAlarm: tag=" + mProvisioningApnAlarmTag +
45011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    " delay=" + (delayInMs / 1000) + "s");
45021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
45031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        Intent intent = new Intent(INTENT_PROVISIONING_APN_ALARM);
45041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        intent.putExtra(PROVISIONING_APN_ALARM_TAG_EXTRA, mProvisioningApnAlarmTag);
45051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mProvisioningApnAlarmIntent = PendingIntent.getBroadcast(mPhone.getContext(), 0, intent,
45061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                PendingIntent.FLAG_UPDATE_CURRENT);
45071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
45081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                SystemClock.elapsedRealtime() + delayInMs, mProvisioningApnAlarmIntent);
45091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
45101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
45111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void stopProvisioningApnAlarm() {
45121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (DBG) {
45131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            log("stopProvisioningApnAlarm: current tag=" + mProvisioningApnAlarmTag +
45141a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    " mProvsioningApnAlarmIntent=" + mProvisioningApnAlarmIntent);
45151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
45161a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mProvisioningApnAlarmTag += 1;
45171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (mProvisioningApnAlarmIntent != null) {
45181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mAlarmManager.cancel(mProvisioningApnAlarmIntent);
45191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mProvisioningApnAlarmIntent = null;
45201a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
45211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
45221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4523c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville}
4524