1cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville/*
2cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville * Copyright (C) 2006 The Android Open Source Project
3cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville *
4cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville * Licensed under the Apache License, Version 2.0 (the "License");
5cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville * you may not use this file except in compliance with the License.
6cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville * You may obtain a copy of the License at
7cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville *
8cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville *      http://www.apache.org/licenses/LICENSE-2.0
9cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville *
10cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville * Unless required by applicable law or agreed to in writing, software
11cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville * distributed under the License is distributed on an "AS IS" BASIS,
12cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville * See the License for the specific language governing permissions and
14cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville * limitations under the License.
15cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville */
16cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
17cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savillepackage com.android.internal.telephony.dataconnection;
18cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
19cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.app.AlarmManager;
20cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.app.PendingIntent;
21cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.content.BroadcastReceiver;
22cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.content.ContentResolver;
23cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.content.Context;
24cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.content.Intent;
25cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.content.IntentFilter;
26cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.content.SharedPreferences;
27cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.database.ContentObserver;
28c9b81a0c05128694c617fcdd67e73821895822feWink Savilleimport android.net.ConnectivityManager;
29cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.net.LinkCapabilities;
30cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.net.LinkProperties;
31cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.net.NetworkInfo;
32cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.net.TrafficStats;
33cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.net.wifi.WifiManager;
34cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.os.AsyncResult;
35d54f9906ce6218a0a9e7a274342082901e7d5d18Wink Savilleimport android.os.Build;
36cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.os.Bundle;
37cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.os.Handler;
38ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Savilleimport android.os.HandlerThread;
39cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.os.Message;
40cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.os.Messenger;
41cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.os.SystemClock;
42cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.os.SystemProperties;
43cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.preference.PreferenceManager;
44cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.provider.Settings;
45cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.provider.Settings.SettingNotFoundException;
46cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.telephony.TelephonyManager;
47cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.text.TextUtils;
48cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.util.EventLog;
49cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport android.telephony.Rlog;
50cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
51cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport com.android.internal.R;
52cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport com.android.internal.telephony.DctConstants;
53c9b81a0c05128694c617fcdd67e73821895822feWink Savilleimport com.android.internal.telephony.DctConstants.State;
54cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport com.android.internal.telephony.EventLogTags;
55cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport com.android.internal.telephony.Phone;
56cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport com.android.internal.telephony.PhoneBase;
57cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport com.android.internal.telephony.PhoneConstants;
58cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport com.android.internal.telephony.uicc.IccRecords;
59cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport com.android.internal.telephony.uicc.UiccController;
60cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport com.android.internal.util.AsyncChannel;
61dd6e67fb45fa3ce0d43f8d874cd7ffaeddf0926fLorenzo Colittiimport com.android.internal.util.ArrayUtils;
62cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
63cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport java.io.FileDescriptor;
64cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport java.io.PrintWriter;
65cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport java.util.ArrayList;
663fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwaltimport java.util.Comparator;
67cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport java.util.HashMap;
68cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport java.util.Map.Entry;
69cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport java.util.Set;
70cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport java.util.concurrent.ConcurrentHashMap;
71cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport java.util.concurrent.atomic.AtomicInteger;
72cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleimport java.util.concurrent.atomic.AtomicReference;
733fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwaltimport java.util.PriorityQueue;
74cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
75cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville/**
76cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville * {@hide}
77cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville */
78454b1dfd508844b42eb775e4ab2359be74d3672bWink Savillepublic abstract class DcTrackerBase extends Handler {
79cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected static final boolean DBG = true;
80ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    protected static final boolean VDBG = false; // STOPSHIP if true
81ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    protected static final boolean VDBG_STALL = true; // STOPSHIP if true
82cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected static final boolean RADIO_TESTS = false;
83cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
84cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /**
85cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Constants for the data connection activity:
86cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * physical link down/up
87cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     */
88cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected static final int DATA_CONNECTION_ACTIVE_PH_LINK_INACTIVE = 0;
89cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected static final int DATA_CONNECTION_ACTIVE_PH_LINK_DOWN = 1;
90cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected static final int DATA_CONNECTION_ACTIVE_PH_LINK_UP = 2;
91cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
92cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /** Delay between APN attempts.
93cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        Note the property override mechanism is there just for testing purpose only. */
94ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville    protected static final int APN_DELAY_DEFAULT_MILLIS = 20000;
95cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
96ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville    /** Delay between APN attempts when in fail fast mode */
97ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville    protected static final int APN_FAIL_FAST_DELAY_DEFAULT_MILLIS = 3000;
98da1dd2e1bccb6141109a65d4e40253f39c405537Wink Saville
99ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    AlarmManager mAlarmManager;
100ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
101cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected Object mDataEnabledLock = new Object();
102cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
103cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // responds to the setInternalDataEnabled call - used internally to turn off data
104cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // for example during emergency calls
105cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected boolean mInternalDataEnabled = true;
106cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
107cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // responds to public (user) API to enable/disable data use
108cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // independent of mInternalDataEnabled and requests for APN access
109cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // persisted
110cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected boolean mUserDataEnabled = true;
111cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
112cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // TODO: move away from static state once 5587429 is fixed.
113cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected static boolean sPolicyDataEnabled = true;
114cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
11522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    private boolean[] mDataEnabled = new boolean[DctConstants.APN_NUM_TYPES];
116cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
11722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    private int mEnabledCount = 0;
118cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
119cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /* Currently requested APN type (TODO: This should probably be a parameter not a member) */
120cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected String mRequestedApnType = PhoneConstants.APN_TYPE_DEFAULT;
121cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
122cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /** Retry configuration: A doubling of retry times from 5secs to 30minutes */
123cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected static final String DEFAULT_DATA_RETRY_CONFIG = "default_randomization=2000,"
124cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        + "5000,10000,20000,40000,80000:5000,160000:5000,"
125cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        + "320000:5000,640000:5000,1280000:5000,1800000:5000";
126cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
127cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /** Retry configuration for secondary networks: 4 tries in 20 sec */
128cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected static final String SECONDARY_DATA_RETRY_CONFIG =
129cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            "max_retries=3, 5000, 5000, 5000";
130cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
131cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /** Slow poll when attempting connection recovery. */
132cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected static final int POLL_NETSTAT_SLOW_MILLIS = 5000;
133cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /** Default max failure count before attempting to network re-registration. */
134cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected static final int DEFAULT_MAX_PDP_RESET_FAIL = 3;
135cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
136cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /**
137cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * After detecting a potential connection problem, this is the max number
138cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * of subsequent polls before attempting recovery.
139cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     */
140cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected static final int NO_RECV_POLL_LIMIT = 24;
141cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // 1 sec. default polling interval when screen is on.
142cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected static final int POLL_NETSTAT_MILLIS = 1000;
143cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // 10 min. default polling interval when screen is off.
144cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected static final int POLL_NETSTAT_SCREEN_OFF_MILLIS = 1000*60*10;
145cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // 2 min for round trip time
146cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected static final int POLL_LONGEST_RTT = 120 * 1000;
147cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // Default sent packets without ack which triggers initial recovery steps
148cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected static final int NUMBER_SENT_PACKETS_OF_HANG = 10;
149cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // how long to wait before switching back to default APN
150cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected static final int RESTORE_DEFAULT_APN_DELAY = 1 * 60 * 1000;
151cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // system property that can override the above value
152cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected static final String APN_RESTORE_DELAY_PROP_NAME = "android.telephony.apn-restore";
153cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // represents an invalid IP address
154cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected static final String NULL_IP = "0.0.0.0";
155cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
156cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // Default for the data stall alarm while non-aggressive stall detection
157cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected static final int DATA_STALL_ALARM_NON_AGGRESSIVE_DELAY_IN_MS_DEFAULT = 1000 * 60 * 6;
158cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // Default for the data stall alarm for aggressive stall detection
159cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected static final int DATA_STALL_ALARM_AGGRESSIVE_DELAY_IN_MS_DEFAULT = 1000 * 60;
160cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // If attempt is less than this value we're doing first level recovery
161cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected static final int DATA_STALL_NO_RECV_POLL_LIMIT = 1;
162cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // Tag for tracking stale alarms
163cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected static final String DATA_STALL_ALARM_TAG_EXTRA = "data.stall.alram.tag";
164cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
165cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected static final boolean DATA_STALL_SUSPECTED = true;
166cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected static final boolean DATA_STALL_NOT_SUSPECTED = false;
167cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
168cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected String RADIO_RESET_PROPERTY = "gsm.radioreset";
169cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
170ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    protected static final String INTENT_RECONNECT_ALARM =
171ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            "com.android.internal.telephony.data-reconnect";
172ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    protected static final String INTENT_RECONNECT_ALARM_EXTRA_TYPE = "reconnect_alarm_extra_type";
173cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected static final String INTENT_RECONNECT_ALARM_EXTRA_REASON =
174ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            "reconnect_alarm_extra_reason";
175ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
176ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    protected static final String INTENT_RESTART_TRYSETUP_ALARM =
177ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            "com.android.internal.telephony.data-restart-trysetup";
178ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    protected static final String INTENT_RESTART_TRYSETUP_ALARM_EXTRA_TYPE =
179ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            "restart_trysetup_alarm_extra_type";
180ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
181ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    protected static final String INTENT_DATA_STALL_ALARM =
182ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            "com.android.internal.telephony.data-stall";
183ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
184cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
185cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
186cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected static final String DEFALUT_DATA_ON_BOOT_PROP = "net.def_data_on_boot";
187cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
188ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    protected DcTesterFailBringUpAll mDcTesterFailBringUpAll;
189ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    protected DcController mDcc;
190ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
191cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // member variables
192cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected PhoneBase mPhone;
193cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected UiccController mUiccController;
194cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected AtomicReference<IccRecords> mIccRecords = new AtomicReference<IccRecords>();
195cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected DctConstants.Activity mActivity = DctConstants.Activity.NONE;
196cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected DctConstants.State mState = DctConstants.State.IDLE;
197cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected Handler mDataConnectionTracker = null;
198cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
199cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected long mTxPkts;
200cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected long mRxPkts;
201cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected int mNetStatPollPeriod;
202cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected boolean mNetStatPollEnabled = false;
203cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
204cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected TxRxSum mDataStallTxRxSum = new TxRxSum(0, 0);
205cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // Used to track stale data stall alarms.
206cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected int mDataStallAlarmTag = (int) SystemClock.elapsedRealtime();
207cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // The current data stall alarm intent
208cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected PendingIntent mDataStallAlarmIntent = null;
209cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // Number of packets sent since the last received packet
210cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected long mSentSinceLastRecv;
211cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // Controls when a simple recovery attempt it to be tried
212cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected int mNoRecvPollCount = 0;
213d54f9906ce6218a0a9e7a274342082901e7d5d18Wink Saville    // Refrence counter for enabling fail fast
21416a01fe85457587ad5fd02ea06aa2882baf3535bWink Saville    protected static int sEnableFailFastRefCounter = 0;
215ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville    // True if data stall detection is enabled
216ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville    protected volatile boolean mDataStallDetectionEnabled = true;
217ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville
218ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville    protected volatile boolean mFailFast = false;
219ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville
220ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville    // True when in voice call
221ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville    protected boolean mInVoiceCall = false;
222cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
223cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // wifi connection status will be updated by sticky intent
224cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected boolean mIsWifiConnected = false;
225cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
226cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /** Intent sent when the reconnect alarm fires. */
227cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected PendingIntent mReconnectIntent = null;
228cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
229cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /** CID of active data connection */
230cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected int mCidActive;
231cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
232cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // When false we will not auto attach and manually attaching is required.
233cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected boolean mAutoAttachOnCreation = false;
234cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
235cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // State of screen
236cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // (TODO: Reconsider tying directly to screen, maybe this is
237cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    //        really a lower power mode")
238cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected boolean mIsScreenOn = true;
239cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
240cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /** Allows the generation of unique Id's for DataConnection objects */
241cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected AtomicInteger mUniqueIdGenerator = new AtomicInteger(0);
242cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
243cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /** The data connections. */
244ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    protected HashMap<Integer, DataConnection> mDataConnections =
245ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        new HashMap<Integer, DataConnection>();
246cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
247cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /** The data connection async channels */
248454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville    protected HashMap<Integer, DcAsyncChannel> mDataConnectionAcHashMap =
249454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville        new HashMap<Integer, DcAsyncChannel>();
250cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
251cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /** Convert an ApnType string to Id (TODO: Use "enumeration" instead of String for ApnType) */
252cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected HashMap<String, Integer> mApnToDataConnectionId =
253cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                    new HashMap<String, Integer>();
254cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
255cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /** Phone.APN_TYPE_* ===> ApnContext */
2563fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt    protected final ConcurrentHashMap<String, ApnContext> mApnContexts =
257cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                                    new ConcurrentHashMap<String, ApnContext>();
258cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
2593fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt    /** kept in sync with mApnContexts
2603fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt     * Higher numbers are higher priority and sorted so highest priority is first */
2613fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt    protected final PriorityQueue<ApnContext>mPrioritySortedApnContexts =
2623fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            new PriorityQueue<ApnContext>(5,
2633fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            new Comparator<ApnContext>() {
2643fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                public int compare(ApnContext c1, ApnContext c2) {
2653fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                    return c2.priority - c1.priority;
2663fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt                }
2673fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt            } );
2683fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt
269cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /* Currently active APN */
270cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected ApnSetting mActiveApn;
271cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
272cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /** allApns holds all apns */
273ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    protected ArrayList<ApnSetting> mAllApnSettings = null;
274cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
275cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /** preferred apn */
276cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected ApnSetting mPreferredApn = null;
277cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
278cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /** Is packet service restricted by network */
279cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected boolean mIsPsRestricted = false;
280cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
281cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /* Once disposed dont handle any messages */
282cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected boolean mIsDisposed = false;
283cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
284cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected ContentResolver mResolver;
285cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
286c9b81a0c05128694c617fcdd67e73821895822feWink Saville    /* Set to true with CMD_ENABLE_MOBILE_PROVISIONING */
287c9b81a0c05128694c617fcdd67e73821895822feWink Saville    protected boolean mIsProvisioning = false;
288c9b81a0c05128694c617fcdd67e73821895822feWink Saville
289e9063f6973039d66e12d0d930af03906d377969eWink Saville    /* The Url passed as object parameter in CMD_ENABLE_MOBILE_PROVISIONING */
290c9b81a0c05128694c617fcdd67e73821895822feWink Saville    protected String mProvisioningUrl = null;
291c9b81a0c05128694c617fcdd67e73821895822feWink Saville
292e9063f6973039d66e12d0d930af03906d377969eWink Saville    /* Intent for the provisioning apn alarm */
293e9063f6973039d66e12d0d930af03906d377969eWink Saville    protected static final String INTENT_PROVISIONING_APN_ALARM =
294e9063f6973039d66e12d0d930af03906d377969eWink Saville            "com.android.internal.telephony.provisioning_apn_alarm";
295e9063f6973039d66e12d0d930af03906d377969eWink Saville
296e9063f6973039d66e12d0d930af03906d377969eWink Saville    /* Tag for tracking stale alarms */
297e9063f6973039d66e12d0d930af03906d377969eWink Saville    protected static final String PROVISIONING_APN_ALARM_TAG_EXTRA = "provisioning.apn.alarm.tag";
298e9063f6973039d66e12d0d930af03906d377969eWink Saville
299e9063f6973039d66e12d0d930af03906d377969eWink Saville    /* Debug property for overriding the PROVISIONING_APN_ALARM_DELAY_IN_MS */
300e9063f6973039d66e12d0d930af03906d377969eWink Saville    protected static final String DEBUG_PROV_APN_ALARM =
301e9063f6973039d66e12d0d930af03906d377969eWink Saville            "persist.debug.prov_apn_alarm";
302e9063f6973039d66e12d0d930af03906d377969eWink Saville
303e9063f6973039d66e12d0d930af03906d377969eWink Saville    /* Default for the provisioning apn alarm timeout */
304e9063f6973039d66e12d0d930af03906d377969eWink Saville    protected static final int PROVISIONING_APN_ALARM_DELAY_IN_MS_DEFAULT = 1000 * 60 * 15;
305e9063f6973039d66e12d0d930af03906d377969eWink Saville
306e9063f6973039d66e12d0d930af03906d377969eWink Saville    /* The provision apn alarm intent used to disable the provisioning apn */
307e9063f6973039d66e12d0d930af03906d377969eWink Saville    protected PendingIntent mProvisioningApnAlarmIntent = null;
308e9063f6973039d66e12d0d930af03906d377969eWink Saville
309e9063f6973039d66e12d0d930af03906d377969eWink Saville    /* Used to track stale provisioning apn alarms */
310e9063f6973039d66e12d0d930af03906d377969eWink Saville    protected int mProvisioningApnAlarmTag = (int) SystemClock.elapsedRealtime();
311e9063f6973039d66e12d0d930af03906d377969eWink Saville
312c9b81a0c05128694c617fcdd67e73821895822feWink Saville    protected AsyncChannel mReplyAc = new AsyncChannel();
313c9b81a0c05128694c617fcdd67e73821895822feWink Saville
314cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected BroadcastReceiver mIntentReceiver = new BroadcastReceiver ()
315cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    {
316cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        @Override
317cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        public void onReceive(Context context, Intent intent)
318cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        {
319cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            String action = intent.getAction();
320cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("onReceive: action=" + action);
321cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (action.equals(Intent.ACTION_SCREEN_ON)) {
322cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mIsScreenOn = true;
323cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                stopNetStatPoll();
324cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                startNetStatPoll();
325cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                restartDataStallAlarm();
326cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } else if (action.equals(Intent.ACTION_SCREEN_OFF)) {
327cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mIsScreenOn = false;
328cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                stopNetStatPoll();
329cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                startNetStatPoll();
330cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                restartDataStallAlarm();
331ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            } else if (action.startsWith(INTENT_RECONNECT_ALARM)) {
332cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) log("Reconnect alarm. Previous state was " + mState);
333cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                onActionIntentReconnectAlarm(intent);
334ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            } else if (action.startsWith(INTENT_RESTART_TRYSETUP_ALARM)) {
335ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                if (DBG) log("Restart trySetup alarm");
336ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                onActionIntentRestartTrySetupAlarm(intent);
337ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            } else if (action.equals(INTENT_DATA_STALL_ALARM)) {
338cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                onActionIntentDataStallAlarm(intent);
339e9063f6973039d66e12d0d930af03906d377969eWink Saville            } else if (action.equals(INTENT_PROVISIONING_APN_ALARM)) {
340e9063f6973039d66e12d0d930af03906d377969eWink Saville                onActionIntentProvisioningApnAlarm(intent);
341cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } else if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
342cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                final android.net.NetworkInfo networkInfo = (NetworkInfo)
343cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
344cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mIsWifiConnected = (networkInfo != null && networkInfo.isConnected());
345cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) log("NETWORK_STATE_CHANGED_ACTION: mIsWifiConnected=" + mIsWifiConnected);
346cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } else if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) {
347cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                final boolean enabled = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,
348cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        WifiManager.WIFI_STATE_UNKNOWN) == WifiManager.WIFI_STATE_ENABLED;
349cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
350cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (!enabled) {
351cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    // when WiFi got disabled, the NETWORK_STATE_CHANGED_ACTION
352cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    // quit and won't report disconnected until next enabling.
353cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    mIsWifiConnected = false;
354cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
355cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) log("WIFI_STATE_CHANGED_ACTION: enabled=" + enabled
356cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        + " mIsWifiConnected=" + mIsWifiConnected);
357cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
358cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
359cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    };
360cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
361cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private Runnable mPollNetStat = new Runnable()
362cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    {
363cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        @Override
364cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        public void run() {
365cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            updateDataActivity();
366cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
367cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (mIsScreenOn) {
368cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mNetStatPollPeriod = Settings.Global.getInt(mResolver,
369cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        Settings.Global.PDP_WATCHDOG_POLL_INTERVAL_MS, POLL_NETSTAT_MILLIS);
370cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } else {
371cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mNetStatPollPeriod = Settings.Global.getInt(mResolver,
372cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        Settings.Global.PDP_WATCHDOG_LONG_POLL_INTERVAL_MS,
373cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        POLL_NETSTAT_SCREEN_OFF_MILLIS);
374cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
375cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
376cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (mNetStatPollEnabled) {
377cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mDataConnectionTracker.postDelayed(this, mNetStatPollPeriod);
378cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
379cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
380cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    };
381cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
382cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private class DataRoamingSettingObserver extends ContentObserver {
383ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
384ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        public DataRoamingSettingObserver(Handler handler, Context context) {
385cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            super(handler);
386ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            mResolver = context.getContentResolver();
387cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
388cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
389ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        public void register() {
390ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            mResolver.registerContentObserver(
391cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    Settings.Global.getUriFor(Settings.Global.DATA_ROAMING), false, this);
392cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
393cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
394ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        public void unregister() {
395ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            mResolver.unregisterContentObserver(this);
396cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
397cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
398cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        @Override
399cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        public void onChange(boolean selfChange) {
400cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // already running on mPhone handler thread
401ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (mPhone.getServiceState().getRoaming()) {
402ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                sendMessage(obtainMessage(DctConstants.EVENT_ROAMING_ON));
403ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            }
404cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
405cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
406ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    private final DataRoamingSettingObserver mDataRoamingSettingObserver;
407ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
408ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    /**
409ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     * The Initial MaxRetry sent to a DataConnection as a parameter
410ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     * to DataConnectionAc.bringUp. This value can be defined at compile
411ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     * time using the SystemProperty Settings.Global.DCT_INITIAL_MAX_RETRY
412ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     * and at runtime using gservices to change Settings.Global.DCT_INITIAL_MAX_RETRY.
413ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     */
414ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    private static final int DEFAULT_MDC_INITIAL_RETRY = 1;
415ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    protected int getInitialMaxRetry() {
416ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville        if (mFailFast) {
417ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville            return 0;
418ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville        }
419ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        // Get default value from system property or use DEFAULT_MDC_INITIAL_RETRY
420ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        int value = SystemProperties.getInt(
421ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                Settings.Global.MDC_INITIAL_MAX_RETRY, DEFAULT_MDC_INITIAL_RETRY);
422ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
423ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        // Check if its been overridden
424ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        return Settings.Global.getInt(mResolver,
425ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                Settings.Global.MDC_INITIAL_MAX_RETRY, value);
426ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    }
427cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
428cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /**
429ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     * Maintain the sum of transmit and receive packets.
430cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *
431ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville     * The packet counts are initialized and reset to -1 and
432cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * remain -1 until they can be updated.
433cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     */
434cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public class TxRxSum {
435cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        public long txPkts;
436cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        public long rxPkts;
437cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
438cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        public TxRxSum() {
439cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            reset();
440cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
441cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
442cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        public TxRxSum(long txPkts, long rxPkts) {
443cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            this.txPkts = txPkts;
444cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            this.rxPkts = rxPkts;
445cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
446cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
447cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        public TxRxSum(TxRxSum sum) {
448cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            txPkts = sum.txPkts;
449cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            rxPkts = sum.rxPkts;
450cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
451cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
452cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        public void reset() {
453cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            txPkts = -1;
454cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            rxPkts = -1;
455cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
456cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
457cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        @Override
458cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        public String toString() {
459cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return "{txSum=" + txPkts + " rxSum=" + rxPkts + "}";
460cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
461cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
462cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        public void updateTxRxSum() {
463cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            this.txPkts = TrafficStats.getMobileTcpTxPackets();
464cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            this.rxPkts = TrafficStats.getMobileTcpRxPackets();
465cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
466cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
467cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
468cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void onActionIntentReconnectAlarm(Intent intent) {
469cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        String reason = intent.getStringExtra(INTENT_RECONNECT_ALARM_EXTRA_REASON);
470ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        String apnType = intent.getStringExtra(INTENT_RECONNECT_ALARM_EXTRA_TYPE);
471ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
472ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        ApnContext apnContext = mApnContexts.get(apnType);
473ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
474ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (DBG) {
475ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            log("onActionIntentReconnectAlarm: mState=" + mState + " reason=" + reason +
476ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                    " apnType=" + apnType + " apnContext=" + apnContext +
477ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                    " mDataConnectionAsyncChannels=" + mDataConnectionAcHashMap);
478ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        }
479ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
480ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if ((apnContext != null) && (apnContext.isEnabled())) {
481ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            apnContext.setReason(reason);
482ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            DctConstants.State apnContextState = apnContext.getState();
483ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (DBG) {
484ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                log("onActionIntentReconnectAlarm: apnContext state=" + apnContextState);
485ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            }
486ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if ((apnContextState == DctConstants.State.FAILED)
487ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                    || (apnContextState == DctConstants.State.IDLE)) {
488ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                if (DBG) {
489ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                    log("onActionIntentReconnectAlarm: state is FAILED|IDLE, disassociate");
490ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                }
4914750c8c11836338b024e159f04f0cbd13c7444b9Wink Saville                DcAsyncChannel dcac = apnContext.getDcAc();
4924750c8c11836338b024e159f04f0cbd13c7444b9Wink Saville                if (dcac != null) {
4934750c8c11836338b024e159f04f0cbd13c7444b9Wink Saville                    dcac.tearDown(apnContext, "", null);
4944750c8c11836338b024e159f04f0cbd13c7444b9Wink Saville                }
495ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                apnContext.setDataConnectionAc(null);
496ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                apnContext.setState(DctConstants.State.IDLE);
497ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            } else {
498ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                if (DBG) log("onActionIntentReconnectAlarm: keep associated");
499ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            }
500ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            // TODO: IF already associated should we send the EVENT_TRY_SETUP_DATA???
501ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            sendMessage(obtainMessage(DctConstants.EVENT_TRY_SETUP_DATA, apnContext));
502ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
503ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            apnContext.setReconnectIntent(null);
504ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        }
505ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    }
506ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
507ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    protected void onActionIntentRestartTrySetupAlarm(Intent intent) {
508ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        String apnType = intent.getStringExtra(INTENT_RESTART_TRYSETUP_ALARM_EXTRA_TYPE);
509ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        ApnContext apnContext = mApnContexts.get(apnType);
51074672e8ee972f12406b72551261b4cc7e0651933Wink Saville        if (DBG) {
51174672e8ee972f12406b72551261b4cc7e0651933Wink Saville            log("onActionIntentRestartTrySetupAlarm: mState=" + mState +
51274672e8ee972f12406b72551261b4cc7e0651933Wink Saville                    " apnType=" + apnType + " apnContext=" + apnContext +
51374672e8ee972f12406b72551261b4cc7e0651933Wink Saville                    " mDataConnectionAsyncChannels=" + mDataConnectionAcHashMap);
51474672e8ee972f12406b72551261b4cc7e0651933Wink Saville        }
515ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        sendMessage(obtainMessage(DctConstants.EVENT_TRY_SETUP_DATA, apnContext));
516cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
517cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
518cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void onActionIntentDataStallAlarm(Intent intent) {
519ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (VDBG_STALL) log("onActionIntentDataStallAlarm: action=" + intent.getAction());
520cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        Message msg = obtainMessage(DctConstants.EVENT_DATA_STALL_ALARM,
521cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                intent.getAction());
522cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        msg.arg1 = intent.getIntExtra(DATA_STALL_ALARM_TAG_EXTRA, 0);
523cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        sendMessage(msg);
524cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
525cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
526c9b81a0c05128694c617fcdd67e73821895822feWink Saville    ConnectivityManager mCm;
527c9b81a0c05128694c617fcdd67e73821895822feWink Saville
528cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /**
529cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Default constructor
530cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     */
531454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville    protected DcTrackerBase(PhoneBase phone) {
532cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        super();
533cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("DCT.constructor");
534cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mPhone = phone;
535ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        mResolver = mPhone.getContext().getContentResolver();
536cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mUiccController = UiccController.getInstance();
537cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mUiccController.registerForIccChanged(this, DctConstants.EVENT_ICC_CHANGED, null);
538ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        mAlarmManager =
539ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                (AlarmManager) mPhone.getContext().getSystemService(Context.ALARM_SERVICE);
540c9b81a0c05128694c617fcdd67e73821895822feWink Saville        mCm = (ConnectivityManager) mPhone.getContext().getSystemService(
541c9b81a0c05128694c617fcdd67e73821895822feWink Saville                Context.CONNECTIVITY_SERVICE);
542ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
543cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
544cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        IntentFilter filter = new IntentFilter();
545cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        filter.addAction(Intent.ACTION_SCREEN_ON);
546cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        filter.addAction(Intent.ACTION_SCREEN_OFF);
547cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
548cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
549ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        filter.addAction(INTENT_DATA_STALL_ALARM);
550e9063f6973039d66e12d0d930af03906d377969eWink Saville        filter.addAction(INTENT_PROVISIONING_APN_ALARM);
551cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
552cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mUserDataEnabled = Settings.Global.getInt(
553cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mPhone.getContext().getContentResolver(), Settings.Global.MOBILE_DATA, 1) == 1;
554cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
555cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mPhone.getContext().registerReceiver(mIntentReceiver, filter, null, mPhone);
556cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
557cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // This preference tells us 1) initial condition for "dataEnabled",
558cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // and 2) whether the RIL will setup the baseband to auto-PS attach.
559cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
56022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mDataEnabled[DctConstants.APN_DEFAULT_ID] =
561cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                SystemProperties.getBoolean(DEFALUT_DATA_ON_BOOT_PROP,true);
56222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mDataEnabled[DctConstants.APN_DEFAULT_ID]) {
56322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mEnabledCount++;
564cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
565cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
566cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mPhone.getContext());
567cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mAutoAttachOnCreation = sp.getBoolean(PhoneBase.DATA_DISABLED_ON_BOOT_KEY, false);
568cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
569ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        // Watch for changes to Settings.Global.DATA_ROAMING
570ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        mDataRoamingSettingObserver = new DataRoamingSettingObserver(mPhone, mPhone.getContext());
571ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        mDataRoamingSettingObserver.register();
572cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
573ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        HandlerThread dcHandlerThread = new HandlerThread("DcHandlerThread");
574ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        dcHandlerThread.start();
575ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        Handler dcHandler = new Handler(dcHandlerThread.getLooper());
576ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        mDcc = DcController.makeDcc(mPhone, this, dcHandler);
577ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        mDcTesterFailBringUpAll = new DcTesterFailBringUpAll(mPhone, dcHandler);
578cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
579cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
580cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public void dispose() {
581cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("DCT.dispose");
582454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville        for (DcAsyncChannel dcac : mDataConnectionAcHashMap.values()) {
583cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            dcac.disconnect();
584cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
585ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        mDataConnectionAcHashMap.clear();
586cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mIsDisposed = true;
58722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mPhone.getContext().unregisterReceiver(mIntentReceiver);
588cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mUiccController.unregisterForIccChanged(this);
589ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        mDataRoamingSettingObserver.unregister();
590ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        mDcc.dispose();
591ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        mDcTesterFailBringUpAll.dispose();
592cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
593cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
594cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public DctConstants.Activity getActivity() {
595cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return mActivity;
596cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
597cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
598cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public boolean isApnTypeActive(String type) {
599cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // TODO: support simultaneous with List instead
600cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (PhoneConstants.APN_TYPE_DUN.equals(type)) {
601cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            ApnSetting dunApn = fetchDunApn();
602cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (dunApn != null) {
603cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return ((mActiveApn != null) && (dunApn.toString().equals(mActiveApn.toString())));
604cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
605cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
606cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return mActiveApn != null && mActiveApn.canHandleType(type);
607cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
608cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
609cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected ApnSetting fetchDunApn() {
610cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (SystemProperties.getBoolean("net.tethering.noprovisioning", false)) {
611cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("fetchDunApn: net.tethering.noprovisioning=true ret: null");
612cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return null;
613cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
614cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        Context c = mPhone.getContext();
615cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        String apnData = Settings.Global.getString(c.getContentResolver(),
616cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                Settings.Global.TETHER_DUN_APN);
617cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        ApnSetting dunSetting = ApnSetting.fromString(apnData);
618cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (dunSetting != null) {
619ff51a1e0381b303e5bb7e4e0a8a6ad7d124437bdSungmin Choi            IccRecords r = mIccRecords.get();
620ff51a1e0381b303e5bb7e4e0a8a6ad7d124437bdSungmin Choi            String operator = (r != null) ? r.getOperatorNumeric() : "";
621ff51a1e0381b303e5bb7e4e0a8a6ad7d124437bdSungmin Choi            if (dunSetting.numeric.equals(operator)) {
622ff51a1e0381b303e5bb7e4e0a8a6ad7d124437bdSungmin Choi                if (VDBG) log("fetchDunApn: global TETHER_DUN_APN dunSetting=" + dunSetting);
623ff51a1e0381b303e5bb7e4e0a8a6ad7d124437bdSungmin Choi                return dunSetting;
624ff51a1e0381b303e5bb7e4e0a8a6ad7d124437bdSungmin Choi            }
625cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
626cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
627cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        apnData = c.getResources().getString(R.string.config_tether_apndata);
628cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        dunSetting = ApnSetting.fromString(apnData);
629cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (VDBG) log("fetchDunApn: config_tether_apndata dunSetting=" + dunSetting);
630cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return dunSetting;
631cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
632cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
633cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public String[] getActiveApnTypes() {
634cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        String[] result;
635cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (mActiveApn != null) {
636cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            result = mActiveApn.types;
637cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
638cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            result = new String[1];
639cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            result[0] = PhoneConstants.APN_TYPE_DEFAULT;
640cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
641cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return result;
642cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
643cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
644cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /** TODO: See if we can remove */
645cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public String getActiveApnString(String apnType) {
646cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        String result = null;
647cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (mActiveApn != null) {
648cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            result = mActiveApn.apn;
649cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
650cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return result;
651cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
652cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
653cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /**
654cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Modify {@link android.provider.Settings.Global#DATA_ROAMING} value.
655cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     */
656cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public void setDataOnRoamingEnabled(boolean enabled) {
657cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (getDataOnRoamingEnabled() != enabled) {
658cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            final ContentResolver resolver = mPhone.getContext().getContentResolver();
659cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            Settings.Global.putInt(resolver, Settings.Global.DATA_ROAMING, enabled ? 1 : 0);
660cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // will trigger handleDataOnRoamingChange() through observer
661cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
662cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
663cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
664cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /**
665cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Return current {@link android.provider.Settings.Global#DATA_ROAMING} value.
666cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     */
667cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public boolean getDataOnRoamingEnabled() {
668cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        try {
669cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            final ContentResolver resolver = mPhone.getContext().getContentResolver();
670cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return Settings.Global.getInt(resolver, Settings.Global.DATA_ROAMING) != 0;
671cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } catch (SettingNotFoundException snfe) {
672cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return false;
673cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
674cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
675cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
676cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // abstract methods
677cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected abstract void restartRadio();
678cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected abstract void log(String s);
679cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected abstract void loge(String s);
680cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected abstract boolean isDataAllowed();
681cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected abstract boolean isApnTypeAvailable(String type);
682cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public    abstract DctConstants.State getState(String apnType);
683c9b81a0c05128694c617fcdd67e73821895822feWink Saville    protected abstract boolean isProvisioningApn(String apnType);
684cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected abstract void setState(DctConstants.State s);
685cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected abstract void gotoIdleAndNotifyDataConnection(String reason);
686cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
687cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected abstract boolean onTrySetupData(String reason);
688cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected abstract void onRoamingOff();
689cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected abstract void onRoamingOn();
690cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected abstract void onRadioAvailable();
691cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected abstract void onRadioOffOrNotAvailable();
692cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected abstract void onDataSetupComplete(AsyncResult ar);
693ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    protected abstract void onDataSetupCompleteError(AsyncResult ar);
694cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected abstract void onDisconnectDone(int connId, AsyncResult ar);
695ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    protected abstract void onDisconnectDcRetrying(int connId, AsyncResult ar);
696cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected abstract void onVoiceCallStarted();
697cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected abstract void onVoiceCallEnded();
698cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected abstract void onCleanUpConnection(boolean tearDown, int apnId, String reason);
699cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected abstract void onCleanUpAllConnections(String cause);
700cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public abstract boolean isDataPossible(String apnType);
701cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected abstract void onUpdateIcc();
702c9b81a0c05128694c617fcdd67e73821895822feWink Saville    protected abstract void completeConnection(ApnContext apnContext);
703cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
704cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
705cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public void handleMessage(Message msg) {
706cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        switch (msg.what) {
707cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case AsyncChannel.CMD_CHANNEL_DISCONNECTED: {
708cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                log("DISCONNECTED_CONNECTED: msg=" + msg);
709454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville                DcAsyncChannel dcac = (DcAsyncChannel) msg.obj;
710ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                mDataConnectionAcHashMap.remove(dcac.getDataConnectionIdSync());
711cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                dcac.disconnected();
712cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
713cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
714cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_ENABLE_NEW_APN:
715cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                onEnableApn(msg.arg1, msg.arg2);
716cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
717cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
718cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_TRY_SETUP_DATA:
719cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                String reason = null;
720cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (msg.obj instanceof String) {
721cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    reason = (String) msg.obj;
722cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
723cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                onTrySetupData(reason);
724cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
725cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
726cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_DATA_STALL_ALARM:
727cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                onDataStallAlarm(msg.arg1);
728cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
729cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
730cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_ROAMING_OFF:
731cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                onRoamingOff();
732cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
733cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
734cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_ROAMING_ON:
735cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                onRoamingOn();
736cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
737cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
738cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_RADIO_AVAILABLE:
739cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                onRadioAvailable();
740cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
741cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
742cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_RADIO_OFF_OR_NOT_AVAILABLE:
743cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                onRadioOffOrNotAvailable();
744cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
745cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
746cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_DATA_SETUP_COMPLETE:
747cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mCidActive = msg.arg1;
748cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                onDataSetupComplete((AsyncResult) msg.obj);
749cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
750cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
751ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            case DctConstants.EVENT_DATA_SETUP_COMPLETE_ERROR:
752ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                onDataSetupCompleteError((AsyncResult) msg.obj);
753ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                break;
754ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
755cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_DISCONNECT_DONE:
756c6bbea82bf74ebb492508199b6f3e172b7ce860aWink Saville                log("DataConnectionTracker.handleMessage: EVENT_DISCONNECT_DONE msg=" + msg);
757cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                onDisconnectDone(msg.arg1, (AsyncResult) msg.obj);
758cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
759cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
760ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            case DctConstants.EVENT_DISCONNECT_DC_RETRYING:
761c6bbea82bf74ebb492508199b6f3e172b7ce860aWink Saville                log("DataConnectionTracker.handleMessage: EVENT_DISCONNECT_DC_RETRYING msg=" + msg);
762ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                onDisconnectDcRetrying(msg.arg1, (AsyncResult) msg.obj);
763ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                break;
764ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
765cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_VOICE_CALL_STARTED:
766cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                onVoiceCallStarted();
767cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
768cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
769cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_VOICE_CALL_ENDED:
770cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                onVoiceCallEnded();
771cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
772cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
773cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_CLEAN_UP_ALL_CONNECTIONS: {
774cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                onCleanUpAllConnections((String) msg.obj);
775cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
776cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
777cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_CLEAN_UP_CONNECTION: {
778cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                boolean tearDown = (msg.arg1 == 0) ? false : true;
779cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                onCleanUpConnection(tearDown, msg.arg2, (String) msg.obj);
780cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
781cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
782cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_SET_INTERNAL_DATA_ENABLE: {
783cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                boolean enabled = (msg.arg1 == DctConstants.ENABLED) ? true : false;
784cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                onSetInternalDataEnabled(enabled);
785cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
786cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
787cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.EVENT_RESET_DONE: {
788cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) log("EVENT_RESET_DONE");
789cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                onResetDone((AsyncResult) msg.obj);
790cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
791cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
792cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.CMD_SET_USER_DATA_ENABLE: {
793cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                final boolean enabled = (msg.arg1 == DctConstants.ENABLED) ? true : false;
794cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) log("CMD_SET_USER_DATA_ENABLE enabled=" + enabled);
795cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                onSetUserDataEnabled(enabled);
796cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
797cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
798cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.CMD_SET_DEPENDENCY_MET: {
799cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                boolean met = (msg.arg1 == DctConstants.ENABLED) ? true : false;
800cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) log("CMD_SET_DEPENDENCY_MET met=" + met);
801cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                Bundle bundle = msg.getData();
802cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (bundle != null) {
803cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    String apnType = (String)bundle.get(DctConstants.APN_TYPE_KEY);
804cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    if (apnType != null) {
805cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        onSetDependencyMet(apnType, met);
806cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    }
807cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
808cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
809cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
810cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DctConstants.CMD_SET_POLICY_DATA_ENABLE: {
811cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                final boolean enabled = (msg.arg1 == DctConstants.ENABLED) ? true : false;
812cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                onSetPolicyDataEnabled(enabled);
813cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
814cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
815ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville            case DctConstants.CMD_SET_ENABLE_FAIL_FAST_MOBILE_DATA: {
81616a01fe85457587ad5fd02ea06aa2882baf3535bWink Saville                sEnableFailFastRefCounter += (msg.arg1 == DctConstants.ENABLED) ? 1 : -1;
817d54f9906ce6218a0a9e7a274342082901e7d5d18Wink Saville                if (DBG) {
818d54f9906ce6218a0a9e7a274342082901e7d5d18Wink Saville                    log("CMD_SET_ENABLE_FAIL_FAST_MOBILE_DATA: "
81916a01fe85457587ad5fd02ea06aa2882baf3535bWink Saville                            + " sEnableFailFastRefCounter=" + sEnableFailFastRefCounter);
820d54f9906ce6218a0a9e7a274342082901e7d5d18Wink Saville                }
82116a01fe85457587ad5fd02ea06aa2882baf3535bWink Saville                if (sEnableFailFastRefCounter < 0) {
822d54f9906ce6218a0a9e7a274342082901e7d5d18Wink Saville                    final String s = "CMD_SET_ENABLE_FAIL_FAST_MOBILE_DATA: "
82316a01fe85457587ad5fd02ea06aa2882baf3535bWink Saville                            + "sEnableFailFastRefCounter:" + sEnableFailFastRefCounter + " < 0";
82416a01fe85457587ad5fd02ea06aa2882baf3535bWink Saville                    loge(s);
82516a01fe85457587ad5fd02ea06aa2882baf3535bWink Saville                    sEnableFailFastRefCounter = 0;
826d54f9906ce6218a0a9e7a274342082901e7d5d18Wink Saville                }
82716a01fe85457587ad5fd02ea06aa2882baf3535bWink Saville                final boolean enabled = sEnableFailFastRefCounter > 0;
828d54f9906ce6218a0a9e7a274342082901e7d5d18Wink Saville                if (DBG) {
829d54f9906ce6218a0a9e7a274342082901e7d5d18Wink Saville                    log("CMD_SET_ENABLE_FAIL_FAST_MOBILE_DATA: enabled=" + enabled
83016a01fe85457587ad5fd02ea06aa2882baf3535bWink Saville                            + " sEnableFailFastRefCounter=" + sEnableFailFastRefCounter);
831d54f9906ce6218a0a9e7a274342082901e7d5d18Wink Saville                }
832ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville                if (mFailFast != enabled) {
833ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville                    mFailFast = enabled;
834ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville                    mDataStallDetectionEnabled = !enabled;
835ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville                    if (mDataStallDetectionEnabled
836ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville                            && (getOverallState() == DctConstants.State.CONNECTED)
837ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville                            && (!mInVoiceCall ||
838ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville                                    mPhone.getServiceStateTracker()
839ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville                                        .isConcurrentVoiceAndDataAllowed())) {
840ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville                        if (DBG) log("CMD_SET_ENABLE_FAIL_FAST_MOBILE_DATA: start data stall");
841ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville                        stopDataStallAlarm();
842ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville                        startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
843ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville                    } else {
844ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville                        if (DBG) log("CMD_SET_ENABLE_FAIL_FAST_MOBILE_DATA: stop data stall");
845ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville                        stopDataStallAlarm();
846ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville                    }
847ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville                }
848ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville
849ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville                break;
850ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville            }
851c9b81a0c05128694c617fcdd67e73821895822feWink Saville            case DctConstants.CMD_ENABLE_MOBILE_PROVISIONING: {
852c9b81a0c05128694c617fcdd67e73821895822feWink Saville                Bundle bundle = msg.getData();
853c9b81a0c05128694c617fcdd67e73821895822feWink Saville                if (bundle != null) {
854c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    try {
855c9b81a0c05128694c617fcdd67e73821895822feWink Saville                        mProvisioningUrl = (String)bundle.get(DctConstants.PROVISIONING_URL_KEY);
856c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    } catch(ClassCastException e) {
857c9b81a0c05128694c617fcdd67e73821895822feWink Saville                        loge("CMD_ENABLE_MOBILE_PROVISIONING: provisioning url not a string" + e);
858c9b81a0c05128694c617fcdd67e73821895822feWink Saville                        mProvisioningUrl = null;
859c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    }
860c9b81a0c05128694c617fcdd67e73821895822feWink Saville                }
861c9b81a0c05128694c617fcdd67e73821895822feWink Saville                if (TextUtils.isEmpty(mProvisioningUrl)) {
862c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    loge("CMD_ENABLE_MOBILE_PROVISIONING: provisioning url is empty, ignoring");
863c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    mIsProvisioning = false;
864c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    mProvisioningUrl = null;
865c9b81a0c05128694c617fcdd67e73821895822feWink Saville                } else {
866c187f0e9bfb897405d6c41f669fc2aadacb0ee1eWink Saville                    loge("CMD_ENABLE_MOBILE_PROVISIONING: provisioningUrl=" + mProvisioningUrl);
867c187f0e9bfb897405d6c41f669fc2aadacb0ee1eWink Saville                    mIsProvisioning = true;
868c187f0e9bfb897405d6c41f669fc2aadacb0ee1eWink Saville                    startProvisioningApnAlarm();
869c187f0e9bfb897405d6c41f669fc2aadacb0ee1eWink Saville                    onSetInternalDataEnabled(true);
870c187f0e9bfb897405d6c41f669fc2aadacb0ee1eWink Saville                    enableApnType("default");
871c9b81a0c05128694c617fcdd67e73821895822feWink Saville                }
872c9b81a0c05128694c617fcdd67e73821895822feWink Saville                break;
873c9b81a0c05128694c617fcdd67e73821895822feWink Saville            }
874e9063f6973039d66e12d0d930af03906d377969eWink Saville            case DctConstants.EVENT_PROVISIONING_APN_ALARM: {
875e9063f6973039d66e12d0d930af03906d377969eWink Saville                if (DBG) log("EVENT_PROVISIONING_APN_ALARM");
876e9063f6973039d66e12d0d930af03906d377969eWink Saville                ApnContext apnCtx = mApnContexts.get("default");
877e9063f6973039d66e12d0d930af03906d377969eWink Saville                if (apnCtx.isProvisioningApn() && apnCtx.isConnectedOrConnecting()) {
878e9063f6973039d66e12d0d930af03906d377969eWink Saville                    if (mProvisioningApnAlarmTag == msg.arg1) {
879e9063f6973039d66e12d0d930af03906d377969eWink Saville                        if (DBG) log("EVENT_PROVISIONING_APN_ALARM: Disconnecting");
880e9063f6973039d66e12d0d930af03906d377969eWink Saville                        mIsProvisioning = false;
881e9063f6973039d66e12d0d930af03906d377969eWink Saville                        mProvisioningUrl = null;
882e9063f6973039d66e12d0d930af03906d377969eWink Saville                        stopProvisioningApnAlarm();
883e9063f6973039d66e12d0d930af03906d377969eWink Saville                        sendCleanUpConnection(true, apnCtx);
884e9063f6973039d66e12d0d930af03906d377969eWink Saville                    } else {
885e9063f6973039d66e12d0d930af03906d377969eWink Saville                        if (DBG) {
886e9063f6973039d66e12d0d930af03906d377969eWink Saville                            log("EVENT_PROVISIONING_APN_ALARM: ignore stale tag,"
887e9063f6973039d66e12d0d930af03906d377969eWink Saville                                    + " mProvisioningApnAlarmTag:" + mProvisioningApnAlarmTag
888e9063f6973039d66e12d0d930af03906d377969eWink Saville                                    + " != arg1:" + msg.arg1);
889e9063f6973039d66e12d0d930af03906d377969eWink Saville                        }
890e9063f6973039d66e12d0d930af03906d377969eWink Saville                    }
891e9063f6973039d66e12d0d930af03906d377969eWink Saville                } else {
892e9063f6973039d66e12d0d930af03906d377969eWink Saville                    if (DBG) log("EVENT_PROVISIONING_APN_ALARM: Not connected ignore");
893e9063f6973039d66e12d0d930af03906d377969eWink Saville                }
894e9063f6973039d66e12d0d930af03906d377969eWink Saville                break;
895e9063f6973039d66e12d0d930af03906d377969eWink Saville            }
896c9b81a0c05128694c617fcdd67e73821895822feWink Saville            case DctConstants.CMD_IS_PROVISIONING_APN: {
897c9b81a0c05128694c617fcdd67e73821895822feWink Saville                if (DBG) log("CMD_IS_PROVISIONING_APN");
898c9b81a0c05128694c617fcdd67e73821895822feWink Saville                boolean isProvApn;
899c9b81a0c05128694c617fcdd67e73821895822feWink Saville                try {
900c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    String apnType = null;
901c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    Bundle bundle = msg.getData();
902c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    if (bundle != null) {
903c9b81a0c05128694c617fcdd67e73821895822feWink Saville                        apnType = (String)bundle.get(DctConstants.APN_TYPE_KEY);
904c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    }
905c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    if (TextUtils.isEmpty(apnType)) {
906c9b81a0c05128694c617fcdd67e73821895822feWink Saville                        loge("CMD_IS_PROVISIONING_APN: apnType is empty");
907c9b81a0c05128694c617fcdd67e73821895822feWink Saville                        isProvApn = false;
908c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    } else {
909c9b81a0c05128694c617fcdd67e73821895822feWink Saville                        isProvApn = isProvisioningApn(apnType);
910c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    }
911c9b81a0c05128694c617fcdd67e73821895822feWink Saville                } catch (ClassCastException e) {
912c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    loge("CMD_IS_PROVISIONING_APN: NO provisioning url ignoring");
913c9b81a0c05128694c617fcdd67e73821895822feWink Saville                    isProvApn = false;
914c9b81a0c05128694c617fcdd67e73821895822feWink Saville                }
915c9b81a0c05128694c617fcdd67e73821895822feWink Saville                if (DBG) log("CMD_IS_PROVISIONING_APN: ret=" + isProvApn);
916c9b81a0c05128694c617fcdd67e73821895822feWink Saville                mReplyAc.replyToMessage(msg, DctConstants.CMD_IS_PROVISIONING_APN,
917c9b81a0c05128694c617fcdd67e73821895822feWink Saville                        isProvApn ? DctConstants.ENABLED : DctConstants.DISABLED);
918c9b81a0c05128694c617fcdd67e73821895822feWink Saville                break;
919c9b81a0c05128694c617fcdd67e73821895822feWink Saville            }
920ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            case DctConstants.EVENT_ICC_CHANGED: {
921cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                onUpdateIcc();
922cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
923ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            }
924979786625e7ceacf4a545a25704ef8a15338a854Wink Saville            case DctConstants.EVENT_RESTART_RADIO: {
925979786625e7ceacf4a545a25704ef8a15338a854Wink Saville                restartRadio();
926979786625e7ceacf4a545a25704ef8a15338a854Wink Saville                break;
927979786625e7ceacf4a545a25704ef8a15338a854Wink Saville            }
928cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            default:
929cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                Rlog.e("DATA", "Unidentified event msg=" + msg);
930cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
931cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
932cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
933cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
934cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /**
935cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Report on whether data connectivity is enabled
936cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *
937cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @return {@code false} if data connectivity has been explicitly disabled,
938cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *         {@code true} otherwise.
939cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     */
940cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public boolean getAnyDataEnabled() {
941cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        final boolean result;
942cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        synchronized (mDataEnabledLock) {
943cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            result = (mInternalDataEnabled && mUserDataEnabled && sPolicyDataEnabled
94422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    && (mEnabledCount != 0));
945cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
946cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (!result && DBG) log("getAnyDataEnabled " + result);
947cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return result;
948cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
949cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
950cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected boolean isEmergency() {
951cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        final boolean result;
952cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        synchronized (mDataEnabledLock) {
953cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            result = mPhone.isInEcm() || mPhone.isInEmergencyCall();
954cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
955cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        log("isEmergency: result=" + result);
956cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return result;
957cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
958cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
959cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected int apnTypeToId(String type) {
960cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (TextUtils.equals(type, PhoneConstants.APN_TYPE_DEFAULT)) {
961cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return DctConstants.APN_DEFAULT_ID;
962cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else if (TextUtils.equals(type, PhoneConstants.APN_TYPE_MMS)) {
963cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return DctConstants.APN_MMS_ID;
964cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else if (TextUtils.equals(type, PhoneConstants.APN_TYPE_SUPL)) {
965cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return DctConstants.APN_SUPL_ID;
966cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else if (TextUtils.equals(type, PhoneConstants.APN_TYPE_DUN)) {
967cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return DctConstants.APN_DUN_ID;
968cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else if (TextUtils.equals(type, PhoneConstants.APN_TYPE_HIPRI)) {
969cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return DctConstants.APN_HIPRI_ID;
970cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else if (TextUtils.equals(type, PhoneConstants.APN_TYPE_IMS)) {
971cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return DctConstants.APN_IMS_ID;
972cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else if (TextUtils.equals(type, PhoneConstants.APN_TYPE_FOTA)) {
973cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return DctConstants.APN_FOTA_ID;
974cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else if (TextUtils.equals(type, PhoneConstants.APN_TYPE_CBS)) {
975cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return DctConstants.APN_CBS_ID;
9761b5fe200e47f40f82f0e28502a5f40bce64a82e6Wink Saville        } else if (TextUtils.equals(type, PhoneConstants.APN_TYPE_IA)) {
9771b5fe200e47f40f82f0e28502a5f40bce64a82e6Wink Saville            return DctConstants.APN_IA_ID;
978cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
979cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return DctConstants.APN_INVALID_ID;
980cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
981cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
982cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
983cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected String apnIdToType(int id) {
984cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        switch (id) {
985cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        case DctConstants.APN_DEFAULT_ID:
986cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return PhoneConstants.APN_TYPE_DEFAULT;
987cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        case DctConstants.APN_MMS_ID:
988cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return PhoneConstants.APN_TYPE_MMS;
989cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        case DctConstants.APN_SUPL_ID:
990cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return PhoneConstants.APN_TYPE_SUPL;
991cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        case DctConstants.APN_DUN_ID:
992cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return PhoneConstants.APN_TYPE_DUN;
993cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        case DctConstants.APN_HIPRI_ID:
994cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return PhoneConstants.APN_TYPE_HIPRI;
995cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        case DctConstants.APN_IMS_ID:
996cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return PhoneConstants.APN_TYPE_IMS;
997cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        case DctConstants.APN_FOTA_ID:
998cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return PhoneConstants.APN_TYPE_FOTA;
999cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        case DctConstants.APN_CBS_ID:
1000cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return PhoneConstants.APN_TYPE_CBS;
10011b5fe200e47f40f82f0e28502a5f40bce64a82e6Wink Saville        case DctConstants.APN_IA_ID:
10021b5fe200e47f40f82f0e28502a5f40bce64a82e6Wink Saville            return PhoneConstants.APN_TYPE_IA;
1003cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        default:
1004cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("Unknown id (" + id + ") in apnIdToType");
1005cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return PhoneConstants.APN_TYPE_DEFAULT;
1006cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1007cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1008cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1009cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public LinkProperties getLinkProperties(String apnType) {
1010cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        int id = apnTypeToId(apnType);
1011cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1012cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (isApnIdEnabled(id)) {
1013454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville            DcAsyncChannel dcac = mDataConnectionAcHashMap.get(0);
1014cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return dcac.getLinkPropertiesSync();
1015cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
1016cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return new LinkProperties();
1017cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1018cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1019cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1020cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public LinkCapabilities getLinkCapabilities(String apnType) {
1021cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        int id = apnTypeToId(apnType);
1022cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (isApnIdEnabled(id)) {
1023454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville            DcAsyncChannel dcac = mDataConnectionAcHashMap.get(0);
1024cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return dcac.getLinkCapabilitiesSync();
1025cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
1026cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return new LinkCapabilities();
1027cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1028cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1029cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1030cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // tell all active apns of the current condition
1031cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void notifyDataConnection(String reason) {
1032cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (int id = 0; id < DctConstants.APN_NUM_TYPES; id++) {
103322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            if (mDataEnabled[id]) {
1034cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mPhone.notifyDataConnection(reason, apnIdToType(id));
1035cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1036cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1037cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        notifyOffApnsOfAvailability(reason);
1038cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1039cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1040cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // a new APN has gone active and needs to send events to catch up with the
1041cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // current condition
1042cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private void notifyApnIdUpToCurrent(String reason, int apnId) {
1043cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        switch (mState) {
1044cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case IDLE:
1045cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
1046ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            case RETRYING:
1047cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case CONNECTING:
1048cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case SCANNING:
1049cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mPhone.notifyDataConnection(reason, apnIdToType(apnId),
1050cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        PhoneConstants.DataState.CONNECTING);
1051cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
1052cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case CONNECTED:
1053cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case DISCONNECTING:
1054cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mPhone.notifyDataConnection(reason, apnIdToType(apnId),
1055cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        PhoneConstants.DataState.CONNECTING);
1056cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mPhone.notifyDataConnection(reason, apnIdToType(apnId),
1057cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        PhoneConstants.DataState.CONNECTED);
1058cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
1059cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            default:
1060ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                // Ignore
1061cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
1062cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1063cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1064cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1065cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // since we normally don't send info to a disconnected APN, we need to do this specially
1066cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private void notifyApnIdDisconnected(String reason, int apnId) {
1067cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mPhone.notifyDataConnection(reason, apnIdToType(apnId),
1068cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                PhoneConstants.DataState.DISCONNECTED);
1069cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1070cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1071cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // disabled apn's still need avail/unavail notificiations - send them out
1072cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void notifyOffApnsOfAvailability(String reason) {
1073cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("notifyOffApnsOfAvailability - reason= " + reason);
1074cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        for (int id = 0; id < DctConstants.APN_NUM_TYPES; id++) {
1075cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (!isApnIdEnabled(id)) {
1076cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                notifyApnIdDisconnected(reason, id);
1077cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1078cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1079cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1080cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1081cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public boolean isApnTypeEnabled(String apnType) {
1082cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (apnType == null) {
1083cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return false;
1084cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
1085cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return isApnIdEnabled(apnTypeToId(apnType));
1086cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1087cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1088cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1089cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected synchronized boolean isApnIdEnabled(int id) {
1090cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (id != DctConstants.APN_INVALID_ID) {
109122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            return mDataEnabled[id];
1092cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1093cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return false;
1094cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1095cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1096cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /**
1097cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Ensure that we are connected to an APN of the specified type.
1098cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *
1099cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @param type the APN type (currently the only valid values are
1100cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *            {@link PhoneConstants#APN_TYPE_MMS} and {@link PhoneConstants#APN_TYPE_SUPL})
1101cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @return Success is indicated by {@code Phone.APN_ALREADY_ACTIVE} or
1102cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *         {@code Phone.APN_REQUEST_STARTED}. In the latter case, a
1103cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *         broadcast will be sent by the ConnectivityManager when a
1104cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *         connection to the APN has been established.
1105cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     */
1106cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public synchronized int enableApnType(String type) {
1107cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        int id = apnTypeToId(type);
1108cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (id == DctConstants.APN_INVALID_ID) {
1109cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return PhoneConstants.APN_REQUEST_FAILED;
1110cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1111cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1112cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) {
1113cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("enableApnType(" + type + "), isApnTypeActive = " + isApnTypeActive(type)
1114cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    + ", isApnIdEnabled =" + isApnIdEnabled(id) + " and state = " + mState);
1115cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1116cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1117cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (!isApnTypeAvailable(type)) {
1118c9b81a0c05128694c617fcdd67e73821895822feWink Saville            if (DBG) log("enableApnType: not available, type=" + type);
1119cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return PhoneConstants.APN_TYPE_NOT_AVAILABLE;
1120cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1121cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1122cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (isApnIdEnabled(id)) {
1123c9b81a0c05128694c617fcdd67e73821895822feWink Saville            if (DBG) log("enableApnType: already active, type=" + type);
1124cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return PhoneConstants.APN_ALREADY_ACTIVE;
1125cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
1126cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            setEnabled(id, true);
1127cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1128cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return PhoneConstants.APN_REQUEST_STARTED;
1129cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1130cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1131cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /**
1132cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * The APN of the specified type is no longer needed. Ensure that if use of
1133cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * the default APN has not been explicitly disabled, we are connected to the
1134cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * default APN.
1135cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *
1136cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @param type the APN type. The only valid values are currently
1137cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *            {@link PhoneConstants#APN_TYPE_MMS} and {@link PhoneConstants#APN_TYPE_SUPL}.
1138cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @return Success is indicated by {@code PhoneConstants.APN_ALREADY_ACTIVE} or
1139cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *         {@code PhoneConstants.APN_REQUEST_STARTED}. In the latter case, a
1140cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *         broadcast will be sent by the ConnectivityManager when a
1141cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *         connection to the APN has been disconnected. A {@code
1142cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *         PhoneConstants.APN_REQUEST_FAILED} is returned if the type parameter is
1143cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *         invalid or if the apn wasn't enabled.
1144cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     */
1145cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public synchronized int disableApnType(String type) {
1146cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("disableApnType(" + type + ")");
1147cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        int id = apnTypeToId(type);
1148cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (id == DctConstants.APN_INVALID_ID) {
1149cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return PhoneConstants.APN_REQUEST_FAILED;
1150cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1151cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (isApnIdEnabled(id)) {
1152cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            setEnabled(id, false);
1153cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (isApnTypeActive(PhoneConstants.APN_TYPE_DEFAULT)) {
115422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                if (mDataEnabled[DctConstants.APN_DEFAULT_ID]) {
1155cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    return PhoneConstants.APN_ALREADY_ACTIVE;
1156cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } else {
1157cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    return PhoneConstants.APN_REQUEST_STARTED;
1158cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
1159cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } else {
1160cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return PhoneConstants.APN_REQUEST_STARTED;
1161cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1162cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
1163cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return PhoneConstants.APN_REQUEST_FAILED;
1164cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1165cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1166cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1167cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void setEnabled(int id, boolean enable) {
1168cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) {
116922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            log("setEnabled(" + id + ", " + enable + ") with old state = " + mDataEnabled[id]
117022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    + " and enabledCount = " + mEnabledCount);
1171cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1172cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        Message msg = obtainMessage(DctConstants.EVENT_ENABLE_NEW_APN);
1173cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        msg.arg1 = id;
1174cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        msg.arg2 = (enable ? DctConstants.ENABLED : DctConstants.DISABLED);
1175cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        sendMessage(msg);
1176cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1177cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1178cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void onEnableApn(int apnId, int enabled) {
1179cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) {
1180cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("EVENT_APN_ENABLE_REQUEST apnId=" + apnId + ", apnType=" + apnIdToType(apnId) +
118122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    ", enabled=" + enabled + ", dataEnabled = " + mDataEnabled[apnId] +
118222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    ", enabledCount = " + mEnabledCount + ", isApnTypeActive = " +
1183cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    isApnTypeActive(apnIdToType(apnId)));
1184cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1185cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (enabled == DctConstants.ENABLED) {
1186cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            synchronized (this) {
118722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                if (!mDataEnabled[apnId]) {
118822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mDataEnabled[apnId] = true;
118922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mEnabledCount++;
1190cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
1191cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1192cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            String type = apnIdToType(apnId);
1193cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (!isApnTypeActive(type)) {
1194cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mRequestedApnType = type;
1195cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                onEnableNewApn();
1196cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } else {
1197cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                notifyApnIdUpToCurrent(Phone.REASON_APN_SWITCHED, apnId);
1198cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1199cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
1200cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // disable
1201cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            boolean didDisable = false;
1202cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            synchronized (this) {
120322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                if (mDataEnabled[apnId]) {
120422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mDataEnabled[apnId] = false;
120522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mEnabledCount--;
1206cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    didDisable = true;
1207cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
1208cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1209cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (didDisable) {
121022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                if ((mEnabledCount == 0) || (apnId == DctConstants.APN_DUN_ID)) {
1211cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    mRequestedApnType = PhoneConstants.APN_TYPE_DEFAULT;
1212cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    onCleanUpConnection(true, apnId, Phone.REASON_DATA_DISABLED);
1213cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
1214cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1215cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // send the disconnect msg manually, since the normal route wont send
1216cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // it (it's not enabled)
1217cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                notifyApnIdDisconnected(Phone.REASON_DATA_DISABLED, apnId);
121822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                if (mDataEnabled[DctConstants.APN_DEFAULT_ID] == true
1219cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        && !isApnTypeActive(PhoneConstants.APN_TYPE_DEFAULT)) {
1220cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    // TODO - this is an ugly way to restore the default conn - should be done
1221cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    // by a real contention manager and policy that disconnects the lower pri
1222cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    // stuff as enable requests come in and pops them back on as we disable back
1223cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    // down to the lower pri stuff
1224cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    mRequestedApnType = PhoneConstants.APN_TYPE_DEFAULT;
1225cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    onEnableNewApn();
1226cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
1227cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1228cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1229cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1230cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1231cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /**
1232cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Called when we switch APNs.
1233cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *
1234cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * mRequestedApnType is set prior to call
1235cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * To be overridden.
1236cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     */
1237cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void onEnableNewApn() {
1238cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1239cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1240cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /**
1241cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Called when EVENT_RESET_DONE is received so goto
1242cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * IDLE state and send notifications to those interested.
1243cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *
1244cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * TODO - currently unused.  Needs to be hooked into DataConnection cleanup
1245cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * TODO - needs to pass some notion of which connection is reset..
1246cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     */
1247cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void onResetDone(AsyncResult ar) {
1248cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("EVENT_RESET_DONE");
1249cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        String reason = null;
1250cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (ar.userObj instanceof String) {
1251cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            reason = (String) ar.userObj;
1252cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1253cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        gotoIdleAndNotifyDataConnection(reason);
1254cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1255cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1256cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    /**
1257cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * Prevent mobile data connections from being established, or once again
1258cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * allow mobile data connections. If the state toggles, then either tear
1259cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * down or set up data, as appropriate to match the new state.
1260cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *
1261cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @param enable indicates whether to enable ({@code true}) or disable (
1262cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     *            {@code false}) data
1263cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @return {@code true} if the operation succeeded
1264cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     */
1265cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public boolean setInternalDataEnabled(boolean enable) {
1266cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG)
1267cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("setInternalDataEnabled(" + enable + ")");
1268cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1269cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        Message msg = obtainMessage(DctConstants.EVENT_SET_INTERNAL_DATA_ENABLE);
1270cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        msg.arg1 = (enable ? DctConstants.ENABLED : DctConstants.DISABLED);
1271cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        sendMessage(msg);
1272cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return true;
1273cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1274cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1275cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void onSetInternalDataEnabled(boolean enabled) {
1276cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        synchronized (mDataEnabledLock) {
1277cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            mInternalDataEnabled = enabled;
1278cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (enabled) {
1279cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                log("onSetInternalDataEnabled: changed to enabled, try to setup data call");
1280cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                onTrySetupData(Phone.REASON_DATA_ENABLED);
1281cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } else {
1282cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                log("onSetInternalDataEnabled: changed to disabled, cleanUpAllConnections");
1283cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                cleanUpAllConnections(null);
1284cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1285cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1286cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1287cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1288cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public void cleanUpAllConnections(String cause) {
1289cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        Message msg = obtainMessage(DctConstants.EVENT_CLEAN_UP_ALL_CONNECTIONS);
1290cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        msg.obj = cause;
1291cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        sendMessage(msg);
1292cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1293cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1294cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public abstract boolean isDisconnected();
1295cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1296cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void onSetUserDataEnabled(boolean enabled) {
1297cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        synchronized (mDataEnabledLock) {
1298cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            final boolean prevEnabled = getAnyDataEnabled();
1299cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (mUserDataEnabled != enabled) {
1300cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mUserDataEnabled = enabled;
1301cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                Settings.Global.putInt(mPhone.getContext().getContentResolver(),
1302cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        Settings.Global.MOBILE_DATA, enabled ? 1 : 0);
1303cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (getDataOnRoamingEnabled() == false &&
1304cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        mPhone.getServiceState().getRoaming() == true) {
1305cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    if (enabled) {
1306cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        notifyOffApnsOfAvailability(Phone.REASON_ROAMING_ON);
1307cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    } else {
1308cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        notifyOffApnsOfAvailability(Phone.REASON_DATA_DISABLED);
1309cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    }
1310cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
1311cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (prevEnabled != getAnyDataEnabled()) {
1312cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    if (!prevEnabled) {
1313cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        onTrySetupData(Phone.REASON_DATA_ENABLED);
1314cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    } else {
1315cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        onCleanUpAllConnections(Phone.REASON_DATA_DISABLED);
1316cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    }
1317cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
1318cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1319cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1320cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1321cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1322cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void onSetDependencyMet(String apnType, boolean met) {
1323cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1324cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1325cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void onSetPolicyDataEnabled(boolean enabled) {
1326cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        synchronized (mDataEnabledLock) {
1327cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            final boolean prevEnabled = getAnyDataEnabled();
1328cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (sPolicyDataEnabled != enabled) {
1329cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                sPolicyDataEnabled = enabled;
1330cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (prevEnabled != getAnyDataEnabled()) {
1331cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    if (!prevEnabled) {
1332cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        onTrySetupData(Phone.REASON_DATA_ENABLED);
1333cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    } else {
1334cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        onCleanUpAllConnections(Phone.REASON_DATA_DISABLED);
1335cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    }
1336cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                }
1337cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1338cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1339cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1340cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1341cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected String getReryConfig(boolean forDefault) {
1342cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        int nt = mPhone.getServiceState().getNetworkType();
1343cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1344cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if ((nt == TelephonyManager.NETWORK_TYPE_CDMA) ||
1345cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            (nt == TelephonyManager.NETWORK_TYPE_1xRTT) ||
1346cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            (nt == TelephonyManager.NETWORK_TYPE_EVDO_0) ||
1347cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            (nt == TelephonyManager.NETWORK_TYPE_EVDO_A) ||
1348cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            (nt == TelephonyManager.NETWORK_TYPE_EVDO_B) ||
1349cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            (nt == TelephonyManager.NETWORK_TYPE_EHRPD)) {
1350cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // CDMA variant
1351cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return SystemProperties.get("ro.cdma.data_retry_config");
1352cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
1353cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // Use GSM varient for all others.
1354cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (forDefault) {
1355cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return SystemProperties.get("ro.gsm.data_retry_config");
1356cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } else {
1357cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                return SystemProperties.get("ro.gsm.2nd_data_retry_config");
1358cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1359cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1360cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1361cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1362cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void resetPollStats() {
1363cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mTxPkts = -1;
1364cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mRxPkts = -1;
1365cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mNetStatPollPeriod = POLL_NETSTAT_MILLIS;
1366cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1367cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1368cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected abstract DctConstants.State getOverallState();
1369cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1370cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void startNetStatPoll() {
1371ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville        if (getOverallState() == DctConstants.State.CONNECTED
1372ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville                && mNetStatPollEnabled == false) {
1373cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) log("startNetStatPoll");
1374cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            resetPollStats();
1375cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            mNetStatPollEnabled = true;
1376cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            mPollNetStat.run();
1377cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1378cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1379cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1380cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void stopNetStatPoll() {
1381cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mNetStatPollEnabled = false;
1382cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        removeCallbacks(mPollNetStat);
1383cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (DBG) log("stopNetStatPoll");
1384cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1385cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1386cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public void updateDataActivity() {
1387cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        long sent, received;
1388cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1389cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        DctConstants.Activity newActivity;
1390cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1391cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        TxRxSum preTxRxSum = new TxRxSum(mTxPkts, mRxPkts);
1392cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        TxRxSum curTxRxSum = new TxRxSum();
1393cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        curTxRxSum.updateTxRxSum();
1394cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mTxPkts = curTxRxSum.txPkts;
1395cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mRxPkts = curTxRxSum.rxPkts;
1396cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1397cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (VDBG) {
1398cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("updateDataActivity: curTxRxSum=" + curTxRxSum + " preTxRxSum=" + preTxRxSum);
1399cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1400cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1401cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (mNetStatPollEnabled && (preTxRxSum.txPkts > 0 || preTxRxSum.rxPkts > 0)) {
1402cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            sent = mTxPkts - preTxRxSum.txPkts;
1403cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            received = mRxPkts - preTxRxSum.rxPkts;
1404cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1405cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (VDBG)
1406cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                log("updateDataActivity: sent=" + sent + " received=" + received);
1407cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (sent > 0 && received > 0) {
1408cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                newActivity = DctConstants.Activity.DATAINANDOUT;
1409cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } else if (sent > 0 && received == 0) {
1410cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                newActivity = DctConstants.Activity.DATAOUT;
1411cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } else if (sent == 0 && received > 0) {
1412cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                newActivity = DctConstants.Activity.DATAIN;
1413cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } else {
1414cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                newActivity = (mActivity == DctConstants.Activity.DORMANT) ?
1415cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        mActivity : DctConstants.Activity.NONE;
1416cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1417cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1418cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (mActivity != newActivity && mIsScreenOn) {
1419cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (VDBG)
1420cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    log("updateDataActivity: newActivity=" + newActivity);
1421cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mActivity = newActivity;
1422cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mPhone.notifyDataActivity();
1423cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1424cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1425cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1426cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1427cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // Recovery action taken in case of data stall
1428cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected static class RecoveryAction {
1429cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        public static final int GET_DATA_CALL_LIST      = 0;
1430cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        public static final int CLEANUP                 = 1;
1431cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        public static final int REREGISTER              = 2;
1432cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        public static final int RADIO_RESTART           = 3;
1433cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        public static final int RADIO_RESTART_WITH_PROP = 4;
1434cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1435cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        private static boolean isAggressiveRecovery(int value) {
1436cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return ((value == RecoveryAction.CLEANUP) ||
1437cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    (value == RecoveryAction.REREGISTER) ||
1438cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    (value == RecoveryAction.RADIO_RESTART) ||
1439cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    (value == RecoveryAction.RADIO_RESTART_WITH_PROP));
1440cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1441cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1442cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1443cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public int getRecoveryAction() {
1444cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        int action = Settings.System.getInt(mPhone.getContext().getContentResolver(),
1445cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                "radio.data.stall.recovery.action", RecoveryAction.GET_DATA_CALL_LIST);
1446ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (VDBG_STALL) log("getRecoveryAction: " + action);
1447cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return action;
1448cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1449cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public void putRecoveryAction(int action) {
1450cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        Settings.System.putInt(mPhone.getContext().getContentResolver(),
1451cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                "radio.data.stall.recovery.action", action);
1452ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (VDBG_STALL) log("putRecoveryAction: " + action);
1453cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1454cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1455cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected boolean isConnected() {
1456cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        return false;
1457cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1458cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1459cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void doRecovery() {
1460cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (getOverallState() == DctConstants.State.CONNECTED) {
1461cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // Go through a series of recovery steps, each action transitions to the next action
1462cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            int recoveryAction = getRecoveryAction();
1463cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            switch (recoveryAction) {
1464cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case RecoveryAction.GET_DATA_CALL_LIST:
1465cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                EventLog.writeEvent(EventLogTags.DATA_STALL_RECOVERY_GET_DATA_CALL_LIST,
1466cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        mSentSinceLastRecv);
1467cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) log("doRecovery() get data call list");
146822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mPhone.mCi.getDataCallList(obtainMessage(DctConstants.EVENT_DATA_STATE_CHANGED));
1469cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                putRecoveryAction(RecoveryAction.CLEANUP);
1470cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
1471cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case RecoveryAction.CLEANUP:
1472cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                EventLog.writeEvent(EventLogTags.DATA_STALL_RECOVERY_CLEANUP, mSentSinceLastRecv);
1473cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) log("doRecovery() cleanup all connections");
1474cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                cleanUpAllConnections(Phone.REASON_PDP_RESET);
1475cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                putRecoveryAction(RecoveryAction.REREGISTER);
1476cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
1477cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case RecoveryAction.REREGISTER:
1478cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                EventLog.writeEvent(EventLogTags.DATA_STALL_RECOVERY_REREGISTER,
1479cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        mSentSinceLastRecv);
1480cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) log("doRecovery() re-register");
1481cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mPhone.getServiceStateTracker().reRegisterNetwork(null);
1482cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                putRecoveryAction(RecoveryAction.RADIO_RESTART);
1483cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
1484cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case RecoveryAction.RADIO_RESTART:
1485cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                EventLog.writeEvent(EventLogTags.DATA_STALL_RECOVERY_RADIO_RESTART,
1486cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        mSentSinceLastRecv);
1487cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) log("restarting radio");
1488cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                putRecoveryAction(RecoveryAction.RADIO_RESTART_WITH_PROP);
1489cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                restartRadio();
1490cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
1491cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            case RecoveryAction.RADIO_RESTART_WITH_PROP:
1492cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // This is in case radio restart has not recovered the data.
1493cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // It will set an additional "gsm.radioreset" property to tell
1494cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // RIL or system to take further action.
1495cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // The implementation of hard reset recovery action is up to OEM product.
1496cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // Once RADIO_RESET property is consumed, it is expected to set back
1497cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // to false by RIL.
1498cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                EventLog.writeEvent(EventLogTags.DATA_STALL_RECOVERY_RADIO_RESTART_WITH_PROP, -1);
1499cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (DBG) log("restarting radio with gsm.radioreset to true");
1500cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                SystemProperties.set(RADIO_RESET_PROPERTY, "true");
1501cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                // give 1 sec so property change can be notified.
1502cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                try {
1503cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    Thread.sleep(1000);
1504cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                } catch (InterruptedException e) {}
1505cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                restartRadio();
1506cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                putRecoveryAction(RecoveryAction.GET_DATA_CALL_LIST);
1507cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                break;
1508cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            default:
1509cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                throw new RuntimeException("doRecovery: Invalid recoveryAction=" +
1510cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    recoveryAction);
1511cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1512cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            mSentSinceLastRecv = 0;
1513cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1514cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1515cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1516cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private void updateDataStallInfo() {
1517cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        long sent, received;
1518cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1519cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        TxRxSum preTxRxSum = new TxRxSum(mDataStallTxRxSum);
1520cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mDataStallTxRxSum.updateTxRxSum();
1521cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1522ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (VDBG_STALL) {
1523cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("updateDataStallInfo: mDataStallTxRxSum=" + mDataStallTxRxSum +
1524cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    " preTxRxSum=" + preTxRxSum);
1525cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1526cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1527cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        sent = mDataStallTxRxSum.txPkts - preTxRxSum.txPkts;
1528cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        received = mDataStallTxRxSum.rxPkts - preTxRxSum.rxPkts;
1529cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1530cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (RADIO_TESTS) {
1531cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (SystemProperties.getBoolean("radio.test.data.stall", false)) {
1532cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                log("updateDataStallInfo: radio.test.data.stall true received = 0;");
1533cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                received = 0;
1534cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1535cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1536cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if ( sent > 0 && received > 0 ) {
1537ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (VDBG_STALL) log("updateDataStallInfo: IN/OUT");
1538cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            mSentSinceLastRecv = 0;
1539cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            putRecoveryAction(RecoveryAction.GET_DATA_CALL_LIST);
1540cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else if (sent > 0 && received == 0) {
1541cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (mPhone.getState() == PhoneConstants.State.IDLE) {
1542cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mSentSinceLastRecv += sent;
1543cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } else {
1544cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                mSentSinceLastRecv = 0;
1545cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1546cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) {
1547cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                log("updateDataStallInfo: OUT sent=" + sent +
1548cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        " mSentSinceLastRecv=" + mSentSinceLastRecv);
1549cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1550cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else if (sent == 0 && received > 0) {
1551ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (VDBG_STALL) log("updateDataStallInfo: IN");
1552cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            mSentSinceLastRecv = 0;
1553cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            putRecoveryAction(RecoveryAction.GET_DATA_CALL_LIST);
1554cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
1555ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (VDBG_STALL) log("updateDataStallInfo: NONE");
1556cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1557cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1558cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1559cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void onDataStallAlarm(int tag) {
1560cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (mDataStallAlarmTag != tag) {
1561cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) {
1562cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                log("onDataStallAlarm: ignore, tag=" + tag + " expecting " + mDataStallAlarmTag);
1563cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1564cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return;
1565cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1566cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        updateDataStallInfo();
1567cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1568cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        int hangWatchdogTrigger = Settings.Global.getInt(mResolver,
1569cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                Settings.Global.PDP_WATCHDOG_TRIGGER_PACKET_COUNT,
1570cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                NUMBER_SENT_PACKETS_OF_HANG);
1571cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1572cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        boolean suspectedStall = DATA_STALL_NOT_SUSPECTED;
1573cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (mSentSinceLastRecv >= hangWatchdogTrigger) {
1574cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (DBG) {
1575cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                log("onDataStallAlarm: tag=" + tag + " do recovery action=" + getRecoveryAction());
1576cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1577cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            suspectedStall = DATA_STALL_SUSPECTED;
1578cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            sendMessage(obtainMessage(DctConstants.EVENT_DO_RECOVERY));
1579cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
1580ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (VDBG_STALL) {
1581cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                log("onDataStallAlarm: tag=" + tag + " Sent " + String.valueOf(mSentSinceLastRecv) +
1582cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    " pkts since last received, < watchdogTrigger=" + hangWatchdogTrigger);
1583cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1584cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1585cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        startDataStallAlarm(suspectedStall);
1586cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1587cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1588cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void startDataStallAlarm(boolean suspectedStall) {
1589cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        int nextAction = getRecoveryAction();
1590cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        int delayInMs;
1591cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1592ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville        if (mDataStallDetectionEnabled && getOverallState() == DctConstants.State.CONNECTED) {
1593cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // If screen is on or data stall is currently suspected, set the alarm
1594cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            // with an aggresive timeout.
1595cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            if (mIsScreenOn || suspectedStall || RecoveryAction.isAggressiveRecovery(nextAction)) {
1596cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                delayInMs = Settings.Global.getInt(mResolver,
1597cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        Settings.Global.DATA_STALL_ALARM_AGGRESSIVE_DELAY_IN_MS,
1598cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        DATA_STALL_ALARM_AGGRESSIVE_DELAY_IN_MS_DEFAULT);
1599cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            } else {
1600cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                delayInMs = Settings.Global.getInt(mResolver,
1601cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        Settings.Global.DATA_STALL_ALARM_NON_AGGRESSIVE_DELAY_IN_MS,
1602cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        DATA_STALL_ALARM_NON_AGGRESSIVE_DELAY_IN_MS_DEFAULT);
1603cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1604cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1605cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            mDataStallAlarmTag += 1;
1606ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (VDBG_STALL) {
1607cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                log("startDataStallAlarm: tag=" + mDataStallAlarmTag +
1608cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                        " delay=" + (delayInMs / 1000) + "s");
1609cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1610ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            Intent intent = new Intent(INTENT_DATA_STALL_ALARM);
1611cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            intent.putExtra(DATA_STALL_ALARM_TAG_EXTRA, mDataStallAlarmTag);
1612cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            mDataStallAlarmIntent = PendingIntent.getBroadcast(mPhone.getContext(), 0, intent,
1613cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    PendingIntent.FLAG_UPDATE_CURRENT);
1614ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
1615cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    SystemClock.elapsedRealtime() + delayInMs, mDataStallAlarmIntent);
1616ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        } else {
1617ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (VDBG_STALL) {
1618ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                log("startDataStallAlarm: NOT started, no connection tag=" + mDataStallAlarmTag);
1619ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            }
1620cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1621cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1622cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1623cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void stopDataStallAlarm() {
1624ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (VDBG_STALL) {
1625cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            log("stopDataStallAlarm: current tag=" + mDataStallAlarmTag +
1626cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    " mDataStallAlarmIntent=" + mDataStallAlarmIntent);
1627cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1628cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        mDataStallAlarmTag += 1;
1629cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (mDataStallAlarmIntent != null) {
1630ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            mAlarmManager.cancel(mDataStallAlarmIntent);
1631cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            mDataStallAlarmIntent = null;
1632cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1633cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1634cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1635cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected void restartDataStallAlarm() {
1636cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (isConnected() == false) return;
1637cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // To be called on screen status change.
1638cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        // Do not cancel the alarm if it is set with aggressive timeout.
1639cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        int nextAction = getRecoveryAction();
1640cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
1641cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        if (RecoveryAction.isAggressiveRecovery(nextAction)) {
1642ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            if (DBG) log("restartDataStallAlarm: action is pending. not resetting the alarm.");
1643cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            return;
1644cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1645ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (VDBG_STALL) log("restartDataStallAlarm: stop then start.");
1646cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        stopDataStallAlarm();
1647cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
1648cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1649cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
16505d5eea6ed231163c225144316b0d1913d48678a4Sungmin Choi    protected void setInitialAttachApn() {
16511b5fe200e47f40f82f0e28502a5f40bce64a82e6Wink Saville        ApnSetting iaApnSetting = null;
16521b5fe200e47f40f82f0e28502a5f40bce64a82e6Wink Saville        ApnSetting defaultApnSetting = null;
16531b5fe200e47f40f82f0e28502a5f40bce64a82e6Wink Saville        ApnSetting firstApnSetting = null;
16545d5eea6ed231163c225144316b0d1913d48678a4Sungmin Choi
16551b5fe200e47f40f82f0e28502a5f40bce64a82e6Wink Saville        log("setInitialApn: E mPreferredApn=" + mPreferredApn);
16561b5fe200e47f40f82f0e28502a5f40bce64a82e6Wink Saville
16571b5fe200e47f40f82f0e28502a5f40bce64a82e6Wink Saville        if (mAllApnSettings != null && !mAllApnSettings.isEmpty()) {
16581b5fe200e47f40f82f0e28502a5f40bce64a82e6Wink Saville            firstApnSetting = mAllApnSettings.get(0);
16591b5fe200e47f40f82f0e28502a5f40bce64a82e6Wink Saville            log("setInitialApn: firstApnSetting=" + firstApnSetting);
16601b5fe200e47f40f82f0e28502a5f40bce64a82e6Wink Saville
16611b5fe200e47f40f82f0e28502a5f40bce64a82e6Wink Saville            // Search for Initial APN setting and the first apn that can handle default
16625d5eea6ed231163c225144316b0d1913d48678a4Sungmin Choi            for (ApnSetting apn : mAllApnSettings) {
1663dd6e67fb45fa3ce0d43f8d874cd7ffaeddf0926fLorenzo Colitti                // Can't use apn.canHandleType(), as that returns true for APNs that have no type.
1664dd6e67fb45fa3ce0d43f8d874cd7ffaeddf0926fLorenzo Colitti                if (ArrayUtils.contains(apn.types, PhoneConstants.APN_TYPE_IA)) {
16651b5fe200e47f40f82f0e28502a5f40bce64a82e6Wink Saville                    // The Initial Attach APN is highest priority so use it if there is one
16661b5fe200e47f40f82f0e28502a5f40bce64a82e6Wink Saville                    log("setInitialApn: iaApnSetting=" + apn);
16671b5fe200e47f40f82f0e28502a5f40bce64a82e6Wink Saville                    iaApnSetting = apn;
16685d5eea6ed231163c225144316b0d1913d48678a4Sungmin Choi                    break;
16691b5fe200e47f40f82f0e28502a5f40bce64a82e6Wink Saville                } else if ((defaultApnSetting == null)
16701b5fe200e47f40f82f0e28502a5f40bce64a82e6Wink Saville                        && (apn.canHandleType(PhoneConstants.APN_TYPE_DEFAULT))) {
16711b5fe200e47f40f82f0e28502a5f40bce64a82e6Wink Saville                    // Use the first default apn if no better choice
16721b5fe200e47f40f82f0e28502a5f40bce64a82e6Wink Saville                    log("setInitialApn: defaultApnSetting=" + apn);
16731b5fe200e47f40f82f0e28502a5f40bce64a82e6Wink Saville                    defaultApnSetting = apn;
16745d5eea6ed231163c225144316b0d1913d48678a4Sungmin Choi                }
16755d5eea6ed231163c225144316b0d1913d48678a4Sungmin Choi            }
16765d5eea6ed231163c225144316b0d1913d48678a4Sungmin Choi        }
16775d5eea6ed231163c225144316b0d1913d48678a4Sungmin Choi
16781b5fe200e47f40f82f0e28502a5f40bce64a82e6Wink Saville        // The priority of apn candidates from highest to lowest is:
16791b5fe200e47f40f82f0e28502a5f40bce64a82e6Wink Saville        //   1) APN_TYPE_IA (Inital Attach)
16801b5fe200e47f40f82f0e28502a5f40bce64a82e6Wink Saville        //   2) mPreferredApn, i.e. the current preferred apn
16811b5fe200e47f40f82f0e28502a5f40bce64a82e6Wink Saville        //   3) The first apn that than handle APN_TYPE_DEFAULT
16821b5fe200e47f40f82f0e28502a5f40bce64a82e6Wink Saville        //   4) The first APN we can find.
16831b5fe200e47f40f82f0e28502a5f40bce64a82e6Wink Saville
16841b5fe200e47f40f82f0e28502a5f40bce64a82e6Wink Saville        ApnSetting initialAttachApnSetting = null;
16851b5fe200e47f40f82f0e28502a5f40bce64a82e6Wink Saville        if (iaApnSetting != null) {
16861b5fe200e47f40f82f0e28502a5f40bce64a82e6Wink Saville            if (DBG) log("setInitialAttachApn: using iaApnSetting");
16871b5fe200e47f40f82f0e28502a5f40bce64a82e6Wink Saville            initialAttachApnSetting = iaApnSetting;
16881b5fe200e47f40f82f0e28502a5f40bce64a82e6Wink Saville        } else if (mPreferredApn != null) {
16891b5fe200e47f40f82f0e28502a5f40bce64a82e6Wink Saville            if (DBG) log("setInitialAttachApn: using mPreferredApn");
16901b5fe200e47f40f82f0e28502a5f40bce64a82e6Wink Saville            initialAttachApnSetting = mPreferredApn;
16911b5fe200e47f40f82f0e28502a5f40bce64a82e6Wink Saville        } else if (defaultApnSetting != null) {
16921b5fe200e47f40f82f0e28502a5f40bce64a82e6Wink Saville            if (DBG) log("setInitialAttachApn: using defaultApnSetting");
16931b5fe200e47f40f82f0e28502a5f40bce64a82e6Wink Saville            initialAttachApnSetting = defaultApnSetting;
16941b5fe200e47f40f82f0e28502a5f40bce64a82e6Wink Saville        } else if (firstApnSetting != null) {
16951b5fe200e47f40f82f0e28502a5f40bce64a82e6Wink Saville            if (DBG) log("setInitialAttachApn: using firstApnSetting");
16961b5fe200e47f40f82f0e28502a5f40bce64a82e6Wink Saville            initialAttachApnSetting = firstApnSetting;
16971b5fe200e47f40f82f0e28502a5f40bce64a82e6Wink Saville        }
16981b5fe200e47f40f82f0e28502a5f40bce64a82e6Wink Saville
16991b5fe200e47f40f82f0e28502a5f40bce64a82e6Wink Saville        if (initialAttachApnSetting == null) {
17001b5fe200e47f40f82f0e28502a5f40bce64a82e6Wink Saville            if (DBG) log("setInitialAttachApn: X There in no available apn");
17011b5fe200e47f40f82f0e28502a5f40bce64a82e6Wink Saville        } else {
17021b5fe200e47f40f82f0e28502a5f40bce64a82e6Wink Saville            if (DBG) log("setInitialAttachApn: X selected Apn=" + initialAttachApnSetting);
17035d5eea6ed231163c225144316b0d1913d48678a4Sungmin Choi
17041b5fe200e47f40f82f0e28502a5f40bce64a82e6Wink Saville            mPhone.mCi.setInitialAttachApn(initialAttachApnSetting.apn,
17051b5fe200e47f40f82f0e28502a5f40bce64a82e6Wink Saville                    initialAttachApnSetting.protocol, initialAttachApnSetting.authType,
17061b5fe200e47f40f82f0e28502a5f40bce64a82e6Wink Saville                    initialAttachApnSetting.user, initialAttachApnSetting.password, null);
17071b5fe200e47f40f82f0e28502a5f40bce64a82e6Wink Saville        }
17085d5eea6ed231163c225144316b0d1913d48678a4Sungmin Choi    }
17095d5eea6ed231163c225144316b0d1913d48678a4Sungmin Choi
1710e9063f6973039d66e12d0d930af03906d377969eWink Saville    protected void onActionIntentProvisioningApnAlarm(Intent intent) {
1711e9063f6973039d66e12d0d930af03906d377969eWink Saville        if (DBG) log("onActionIntentProvisioningApnAlarm: action=" + intent.getAction());
1712e9063f6973039d66e12d0d930af03906d377969eWink Saville        Message msg = obtainMessage(DctConstants.EVENT_PROVISIONING_APN_ALARM,
1713e9063f6973039d66e12d0d930af03906d377969eWink Saville                intent.getAction());
1714e9063f6973039d66e12d0d930af03906d377969eWink Saville        msg.arg1 = intent.getIntExtra(PROVISIONING_APN_ALARM_TAG_EXTRA, 0);
1715e9063f6973039d66e12d0d930af03906d377969eWink Saville        sendMessage(msg);
1716e9063f6973039d66e12d0d930af03906d377969eWink Saville    }
1717e9063f6973039d66e12d0d930af03906d377969eWink Saville
1718e9063f6973039d66e12d0d930af03906d377969eWink Saville    protected void startProvisioningApnAlarm() {
1719e9063f6973039d66e12d0d930af03906d377969eWink Saville        int delayInMs = Settings.Global.getInt(mResolver,
1720e9063f6973039d66e12d0d930af03906d377969eWink Saville                                Settings.Global.PROVISIONING_APN_ALARM_DELAY_IN_MS,
1721e9063f6973039d66e12d0d930af03906d377969eWink Saville                                PROVISIONING_APN_ALARM_DELAY_IN_MS_DEFAULT);
1722e9063f6973039d66e12d0d930af03906d377969eWink Saville        if (Build.IS_DEBUGGABLE) {
1723e9063f6973039d66e12d0d930af03906d377969eWink Saville            // Allow debug code to use a system property to provide another value
1724e9063f6973039d66e12d0d930af03906d377969eWink Saville            String delayInMsStrg = Integer.toString(delayInMs);
1725e9063f6973039d66e12d0d930af03906d377969eWink Saville            delayInMsStrg = System.getProperty(DEBUG_PROV_APN_ALARM, delayInMsStrg);
1726e9063f6973039d66e12d0d930af03906d377969eWink Saville            try {
1727e9063f6973039d66e12d0d930af03906d377969eWink Saville                delayInMs = Integer.parseInt(delayInMsStrg);
1728e9063f6973039d66e12d0d930af03906d377969eWink Saville            } catch (NumberFormatException e) {
1729e9063f6973039d66e12d0d930af03906d377969eWink Saville                loge("startProvisioningApnAlarm: e=" + e);
1730e9063f6973039d66e12d0d930af03906d377969eWink Saville            }
1731e9063f6973039d66e12d0d930af03906d377969eWink Saville        }
1732e9063f6973039d66e12d0d930af03906d377969eWink Saville        mProvisioningApnAlarmTag += 1;
1733e9063f6973039d66e12d0d930af03906d377969eWink Saville        if (DBG) {
1734e9063f6973039d66e12d0d930af03906d377969eWink Saville            log("startProvisioningApnAlarm: tag=" + mProvisioningApnAlarmTag +
1735e9063f6973039d66e12d0d930af03906d377969eWink Saville                    " delay=" + (delayInMs / 1000) + "s");
1736e9063f6973039d66e12d0d930af03906d377969eWink Saville        }
1737e9063f6973039d66e12d0d930af03906d377969eWink Saville        Intent intent = new Intent(INTENT_PROVISIONING_APN_ALARM);
1738e9063f6973039d66e12d0d930af03906d377969eWink Saville        intent.putExtra(PROVISIONING_APN_ALARM_TAG_EXTRA, mProvisioningApnAlarmTag);
1739e9063f6973039d66e12d0d930af03906d377969eWink Saville        mProvisioningApnAlarmIntent = PendingIntent.getBroadcast(mPhone.getContext(), 0, intent,
1740e9063f6973039d66e12d0d930af03906d377969eWink Saville                PendingIntent.FLAG_UPDATE_CURRENT);
1741e9063f6973039d66e12d0d930af03906d377969eWink Saville        mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
1742e9063f6973039d66e12d0d930af03906d377969eWink Saville                SystemClock.elapsedRealtime() + delayInMs, mProvisioningApnAlarmIntent);
1743e9063f6973039d66e12d0d930af03906d377969eWink Saville    }
1744e9063f6973039d66e12d0d930af03906d377969eWink Saville
1745e9063f6973039d66e12d0d930af03906d377969eWink Saville    protected void stopProvisioningApnAlarm() {
1746e9063f6973039d66e12d0d930af03906d377969eWink Saville        if (DBG) {
1747e9063f6973039d66e12d0d930af03906d377969eWink Saville            log("stopProvisioningApnAlarm: current tag=" + mProvisioningApnAlarmTag +
1748e9063f6973039d66e12d0d930af03906d377969eWink Saville                    " mProvsioningApnAlarmIntent=" + mProvisioningApnAlarmIntent);
1749e9063f6973039d66e12d0d930af03906d377969eWink Saville        }
1750e9063f6973039d66e12d0d930af03906d377969eWink Saville        mProvisioningApnAlarmTag += 1;
1751e9063f6973039d66e12d0d930af03906d377969eWink Saville        if (mProvisioningApnAlarmIntent != null) {
1752e9063f6973039d66e12d0d930af03906d377969eWink Saville            mAlarmManager.cancel(mProvisioningApnAlarmIntent);
1753e9063f6973039d66e12d0d930af03906d377969eWink Saville            mProvisioningApnAlarmIntent = null;
1754e9063f6973039d66e12d0d930af03906d377969eWink Saville        }
1755e9063f6973039d66e12d0d930af03906d377969eWink Saville    }
1756e9063f6973039d66e12d0d930af03906d377969eWink Saville
1757ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    void sendCleanUpConnection(boolean tearDown, ApnContext apnContext) {
1758ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (DBG)log("sendCleanUpConnection: tearDown=" + tearDown + " apnContext=" + apnContext);
1759ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        Message msg = obtainMessage(DctConstants.EVENT_CLEAN_UP_CONNECTION);
1760ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        msg.arg1 = tearDown ? 1 : 0;
1761ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        msg.arg2 = 0;
1762ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        msg.obj = apnContext;
1763ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        sendMessage(msg);
1764ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville    }
1765ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville
1766979786625e7ceacf4a545a25704ef8a15338a854Wink Saville    void sendRestartRadio() {
1767979786625e7ceacf4a545a25704ef8a15338a854Wink Saville        if (DBG)log("sendRestartRadio:");
1768979786625e7ceacf4a545a25704ef8a15338a854Wink Saville        Message msg = obtainMessage(DctConstants.EVENT_RESTART_RADIO);
1769979786625e7ceacf4a545a25704ef8a15338a854Wink Saville        sendMessage(msg);
1770979786625e7ceacf4a545a25704ef8a15338a854Wink Saville    }
1771979786625e7ceacf4a545a25704ef8a15338a854Wink Saville
1772cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1773cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        pw.println("DataConnectionTrackerBase:");
1774cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        pw.println(" RADIO_TESTS=" + RADIO_TESTS);
1775cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        pw.println(" mInternalDataEnabled=" + mInternalDataEnabled);
1776cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        pw.println(" mUserDataEnabled=" + mUserDataEnabled);
1777cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        pw.println(" sPolicyDataEnabed=" + sPolicyDataEnabled);
177822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mDataEnabled:");
177922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        for(int i=0; i < mDataEnabled.length; i++) {
178022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            pw.printf("  mDataEnabled[%d]=%b\n", i, mDataEnabled[i]);
1781cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1782cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        pw.flush();
178322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mEnabledCount=" + mEnabledCount);
1784cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        pw.println(" mRequestedApnType=" + mRequestedApnType);
1785cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        pw.println(" mPhone=" + mPhone.getPhoneName());
1786cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        pw.println(" mActivity=" + mActivity);
1787cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        pw.println(" mState=" + mState);
1788cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        pw.println(" mTxPkts=" + mTxPkts);
1789cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        pw.println(" mRxPkts=" + mRxPkts);
1790cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        pw.println(" mNetStatPollPeriod=" + mNetStatPollPeriod);
1791cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        pw.println(" mNetStatPollEnabled=" + mNetStatPollEnabled);
1792cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        pw.println(" mDataStallTxRxSum=" + mDataStallTxRxSum);
1793cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        pw.println(" mDataStallAlarmTag=" + mDataStallAlarmTag);
1794ec107cb8a36181fa26e61ab51f423ba862deb0faWink Saville        pw.println(" mDataStallDetectionEanbled=" + mDataStallDetectionEnabled);
1795cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        pw.println(" mSentSinceLastRecv=" + mSentSinceLastRecv);
1796cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        pw.println(" mNoRecvPollCount=" + mNoRecvPollCount);
1797cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        pw.println(" mResolver=" + mResolver);
1798cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        pw.println(" mIsWifiConnected=" + mIsWifiConnected);
1799cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        pw.println(" mReconnectIntent=" + mReconnectIntent);
1800cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        pw.println(" mCidActive=" + mCidActive);
1801cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        pw.println(" mAutoAttachOnCreation=" + mAutoAttachOnCreation);
1802cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        pw.println(" mIsScreenOn=" + mIsScreenOn);
1803cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        pw.println(" mUniqueIdGenerator=" + mUniqueIdGenerator);
1804cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        pw.flush();
1805cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        pw.println(" ***************************************");
1806ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        DcController dcc = mDcc;
1807ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (dcc != null) {
1808ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            dcc.dump(fd, pw, args);
1809ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        } else {
1810ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            pw.println(" mDcc=null");
1811ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        }
1812ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        pw.println(" ***************************************");
1813ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        HashMap<Integer, DataConnection> dcs = mDataConnections;
1814ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (dcs != null) {
1815ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            Set<Entry<Integer, DataConnection> > mDcSet = mDataConnections.entrySet();
1816ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            pw.println(" mDataConnections: count=" + mDcSet.size());
1817ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            for (Entry<Integer, DataConnection> entry : mDcSet) {
1818ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                pw.printf(" *** mDataConnection[%d] \n", entry.getKey());
1819ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                entry.getValue().dump(fd, pw, args);
1820ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            }
1821ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        } else {
1822ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            pw.println("mDataConnections=null");
1823cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1824cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        pw.println(" ***************************************");
1825cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        pw.flush();
1826ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        HashMap<String, Integer> apnToDcId = mApnToDataConnectionId;
1827ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (apnToDcId != null) {
1828ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            Set<Entry<String, Integer>> apnToDcIdSet = apnToDcId.entrySet();
1829ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            pw.println(" mApnToDataConnectonId size=" + apnToDcIdSet.size());
1830ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            for (Entry<String, Integer> entry : apnToDcIdSet) {
1831ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                pw.printf(" mApnToDataConnectonId[%s]=%d\n", entry.getKey(), entry.getValue());
1832ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            }
1833ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        } else {
1834ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            pw.println("mApnToDataConnectionId=null");
1835cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1836cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        pw.println(" ***************************************");
1837cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        pw.flush();
1838ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        ConcurrentHashMap<String, ApnContext> apnCtxs = mApnContexts;
1839ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (apnCtxs != null) {
1840ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            Set<Entry<String, ApnContext>> apnCtxsSet = apnCtxs.entrySet();
1841ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            pw.println(" mApnContexts size=" + apnCtxsSet.size());
1842ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            for (Entry<String, ApnContext> entry : apnCtxsSet) {
1843cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                entry.getValue().dump(fd, pw, args);
1844cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1845cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            pw.println(" ***************************************");
1846cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
1847cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            pw.println(" mApnContexts=null");
1848cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1849cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        pw.flush();
1850cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        pw.println(" mActiveApn=" + mActiveApn);
1851ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        ArrayList<ApnSetting> apnSettings = mAllApnSettings;
1852ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville        if (apnSettings != null) {
1853ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            pw.println(" mAllApnSettings size=" + apnSettings.size());
1854ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            for (int i=0; i < apnSettings.size(); i++) {
1855ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville                pw.printf(" mAllApnSettings[%d]: %s\n", i, apnSettings.get(i));
1856cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            }
1857cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            pw.flush();
1858cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        } else {
1859ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6aWink Saville            pw.println(" mAllApnSettings=null");
1860cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        }
1861cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        pw.println(" mPreferredApn=" + mPreferredApn);
1862cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        pw.println(" mIsPsRestricted=" + mIsPsRestricted);
1863cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        pw.println(" mIsDisposed=" + mIsDisposed);
1864cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        pw.println(" mIntentReceiver=" + mIntentReceiver);
1865cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        pw.println(" mDataRoamingSettingObserver=" + mDataRoamingSettingObserver);
1866cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        pw.flush();
1867cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
1868cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville}
1869