1c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville/*
2c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * Copyright (C) 2006 The Android Open Source Project
3c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville *
4c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * Licensed under the Apache License, Version 2.0 (the "License");
5c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * you may not use this file except in compliance with the License.
6c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * You may obtain a copy of the License at
7c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville *
8c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville *      http://www.apache.org/licenses/LICENSE-2.0
9c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville *
10c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * Unless required by applicable law or agreed to in writing, software
11c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * distributed under the License is distributed on an "AS IS" BASIS,
12c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * See the License for the specific language governing permissions and
14c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * limitations under the License.
15c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville */
16c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
17c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savillepackage com.android.internal.telephony;
18c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
19cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kallaimport android.app.AlarmManager;
20c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.app.PendingIntent;
21c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.content.BroadcastReceiver;
22c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.content.ContentResolver;
23c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.content.Context;
24c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.content.Intent;
25c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.content.IntentFilter;
26c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.content.SharedPreferences;
27c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.database.ContentObserver;
28c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.net.LinkCapabilities;
29c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.net.LinkProperties;
30c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.net.NetworkInfo;
31c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.net.TrafficStats;
32c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.net.wifi.WifiManager;
33c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.os.AsyncResult;
34c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.os.Bundle;
35c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.os.Handler;
36c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.os.Message;
37c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.os.Messenger;
38c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.os.SystemClock;
39c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.os.SystemProperties;
40c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.preference.PreferenceManager;
41c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.provider.Settings;
42c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.provider.Settings.SettingNotFoundException;
43c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.telephony.ServiceState;
44c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.telephony.TelephonyManager;
45c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.text.TextUtils;
46cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kallaimport android.util.EventLog;
47c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.util.Log;
48c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
49c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport com.android.internal.R;
50c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport com.android.internal.telephony.DataConnection.FailCause;
51c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport com.android.internal.telephony.DctConstants;
52bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenkaimport com.android.internal.telephony.uicc.UiccController;
53c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport com.android.internal.util.AsyncChannel;
54c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
55c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport java.io.FileDescriptor;
56c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport java.io.PrintWriter;
57c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport java.util.ArrayList;
58c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport java.util.HashMap;
59c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport java.util.Map.Entry;
60c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport java.util.Set;
61c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport java.util.concurrent.ConcurrentHashMap;
62c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport java.util.concurrent.atomic.AtomicInteger;
63bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenkaimport java.util.concurrent.atomic.AtomicReference;
64c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
65c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville/**
66c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * {@hide}
67c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville */
68c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savillepublic abstract class DataConnectionTracker extends Handler {
69c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected static final boolean DBG = true;
70c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected static final boolean VDBG = false;
71cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    protected static final boolean RADIO_TESTS = false;
72c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
73b3a03455be44a2a0ffbeb757b193d860c1878599Naveen Kalla    /**
74b3a03455be44a2a0ffbeb757b193d860c1878599Naveen Kalla     * Constants for the data connection activity:
75b3a03455be44a2a0ffbeb757b193d860c1878599Naveen Kalla     * physical link down/up
76b3a03455be44a2a0ffbeb757b193d860c1878599Naveen Kalla     */
77b3a03455be44a2a0ffbeb757b193d860c1878599Naveen Kalla    protected static final int DATA_CONNECTION_ACTIVE_PH_LINK_INACTIVE = 0;
78b3a03455be44a2a0ffbeb757b193d860c1878599Naveen Kalla    protected static final int DATA_CONNECTION_ACTIVE_PH_LINK_DOWN = 1;
79b3a03455be44a2a0ffbeb757b193d860c1878599Naveen Kalla    protected static final int DATA_CONNECTION_ACTIVE_PH_LINK_UP = 2;
80c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
81c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /** Delay between APN attempts.
82c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        Note the property override mechanism is there just for testing purpose only. */
83c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected static final int APN_DELAY_MILLIS =
84c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                                SystemProperties.getInt("persist.radio.apn_delay", 5000);
85c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
86c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected Object mDataEnabledLock = new Object();
87c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
88c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    // responds to the setInternalDataEnabled call - used internally to turn off data
89c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    // for example during emergency calls
90c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected boolean mInternalDataEnabled = true;
91c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
92c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    // responds to public (user) API to enable/disable data use
93c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    // independent of mInternalDataEnabled and requests for APN access
94c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    // persisted
95c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected boolean mUserDataEnabled = true;
96c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
97c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    // TODO: move away from static state once 5587429 is fixed.
98c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected static boolean sPolicyDataEnabled = true;
99c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
100c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private boolean[] dataEnabled = new boolean[DctConstants.APN_NUM_TYPES];
101c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
102c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private int enabledCount = 0;
103c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
104c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /* Currently requested APN type (TODO: This should probably be a parameter not a member) */
105c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected String mRequestedApnType = PhoneConstants.APN_TYPE_DEFAULT;
106c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
107c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /** Retry configuration: A doubling of retry times from 5secs to 30minutes */
108c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected static final String DEFAULT_DATA_RETRY_CONFIG = "default_randomization=2000,"
109c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        + "5000,10000,20000,40000,80000:5000,160000:5000,"
110c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        + "320000:5000,640000:5000,1280000:5000,1800000:5000";
111c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
112c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /** Retry configuration for secondary networks: 4 tries in 20 sec */
113c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected static final String SECONDARY_DATA_RETRY_CONFIG =
114c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            "max_retries=3, 5000, 5000, 5000";
115c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
116c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /** Slow poll when attempting connection recovery. */
117c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected static final int POLL_NETSTAT_SLOW_MILLIS = 5000;
118c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /** Default max failure count before attempting to network re-registration. */
119c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected static final int DEFAULT_MAX_PDP_RESET_FAIL = 3;
120c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
121c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
122c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * After detecting a potential connection problem, this is the max number
123c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * of subsequent polls before attempting recovery.
124c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
125c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected static final int NO_RECV_POLL_LIMIT = 24;
126c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    // 1 sec. default polling interval when screen is on.
127c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected static final int POLL_NETSTAT_MILLIS = 1000;
128c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    // 10 min. default polling interval when screen is off.
129c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected static final int POLL_NETSTAT_SCREEN_OFF_MILLIS = 1000*60*10;
130c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    // 2 min for round trip time
131c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected static final int POLL_LONGEST_RTT = 120 * 1000;
132c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    // Default sent packets without ack which triggers initial recovery steps
133c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected static final int NUMBER_SENT_PACKETS_OF_HANG = 10;
134c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    // how long to wait before switching back to default APN
135c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected static final int RESTORE_DEFAULT_APN_DELAY = 1 * 60 * 1000;
136c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    // system property that can override the above value
137c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected static final String APN_RESTORE_DELAY_PROP_NAME = "android.telephony.apn-restore";
138c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    // represents an invalid IP address
139c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected static final String NULL_IP = "0.0.0.0";
140c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
141c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    // Default for the data stall alarm while non-aggressive stall detection
142c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected static final int DATA_STALL_ALARM_NON_AGGRESSIVE_DELAY_IN_MS_DEFAULT = 1000 * 60 * 6;
143c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    // Default for the data stall alarm for aggressive stall detection
144c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected static final int DATA_STALL_ALARM_AGGRESSIVE_DELAY_IN_MS_DEFAULT = 1000 * 60;
145c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    // If attempt is less than this value we're doing first level recovery
146c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected static final int DATA_STALL_NO_RECV_POLL_LIMIT = 1;
147c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    // Tag for tracking stale alarms
148c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected static final String DATA_STALL_ALARM_TAG_EXTRA = "data.stall.alram.tag";
149c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
150cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    protected static final boolean DATA_STALL_SUSPECTED = true;
151cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    protected static final boolean DATA_STALL_NOT_SUSPECTED = false;
152cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
153cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    protected String RADIO_RESET_PROPERTY = "gsm.radioreset";
154cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
155cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
156c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    // TODO: See if we can remove INTENT_RECONNECT_ALARM
157c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    //       having to have different values for GSM and
158c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    //       CDMA. If so we can then remove the need for
159c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    //       getActionIntentReconnectAlarm.
160c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected static final String INTENT_RECONNECT_ALARM_EXTRA_REASON =
161c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        "reconnect_alarm_extra_reason";
162c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
163c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    // Used for debugging. Send the INTENT with an optional counter value with the number
164c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    // of times the setup is to fail before succeeding. If the counter isn't passed the
165c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    // setup will fail once. Example fail two times with FailCause.SIGNAL_LOST(-3)
166c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    // adb shell am broadcast \
167c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    //  -a com.android.internal.telephony.dataconnectiontracker.intent_set_fail_data_setup_counter \
168c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    //  --ei fail_data_setup_counter 3 --ei fail_data_setup_fail_cause -3
169c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected static final String INTENT_SET_FAIL_DATA_SETUP_COUNTER =
170c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        "com.android.internal.telephony.dataconnectiontracker.intent_set_fail_data_setup_counter";
171c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected static final String FAIL_DATA_SETUP_COUNTER = "fail_data_setup_counter";
172c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected int mFailDataSetupCounter = 0;
173c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected static final String FAIL_DATA_SETUP_FAIL_CAUSE = "fail_data_setup_fail_cause";
174c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected FailCause mFailDataSetupFailCause = FailCause.ERROR_UNSPECIFIED;
175c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
176c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected static final String DEFALUT_DATA_ON_BOOT_PROP = "net.def_data_on_boot";
177c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
178c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    // member variables
179c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected PhoneBase mPhone;
180bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka    protected UiccController mUiccController;
181bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka    protected AtomicReference<IccRecords> mIccRecords = new AtomicReference<IccRecords>();
182c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected DctConstants.Activity mActivity = DctConstants.Activity.NONE;
183c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected DctConstants.State mState = DctConstants.State.IDLE;
184c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected Handler mDataConnectionTracker = null;
185c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
186c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected long mTxPkts;
187c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected long mRxPkts;
188c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected int mNetStatPollPeriod;
189c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected boolean mNetStatPollEnabled = false;
190c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
191c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected TxRxSum mDataStallTxRxSum = new TxRxSum(0, 0);
192c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    // Used to track stale data stall alarms.
193c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected int mDataStallAlarmTag = (int) SystemClock.elapsedRealtime();
194c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    // The current data stall alarm intent
195c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected PendingIntent mDataStallAlarmIntent = null;
196c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    // Number of packets sent since the last received packet
197c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected long mSentSinceLastRecv;
198c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    // Controls when a simple recovery attempt it to be tried
199c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected int mNoRecvPollCount = 0;
200c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
201c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    // wifi connection status will be updated by sticky intent
202c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected boolean mIsWifiConnected = false;
203c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
204c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /** Intent sent when the reconnect alarm fires. */
205c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected PendingIntent mReconnectIntent = null;
206c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
207c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /** CID of active data connection */
208c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected int mCidActive;
209c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
210c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    // When false we will not auto attach and manually attaching is required.
211c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected boolean mAutoAttachOnCreation = false;
212c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
213c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    // State of screen
214c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    // (TODO: Reconsider tying directly to screen, maybe this is
215c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    //        really a lower power mode")
216c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected boolean mIsScreenOn = true;
217c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
218c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /** Allows the generation of unique Id's for DataConnection objects */
219c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected AtomicInteger mUniqueIdGenerator = new AtomicInteger(0);
220c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
221c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /** The data connections. */
222c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected HashMap<Integer, DataConnection> mDataConnections =
223c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        new HashMap<Integer, DataConnection>();
224c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
225c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /** The data connection async channels */
226c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected HashMap<Integer, DataConnectionAc> mDataConnectionAsyncChannels =
227c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        new HashMap<Integer, DataConnectionAc>();
228c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
229c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /** Convert an ApnType string to Id (TODO: Use "enumeration" instead of String for ApnType) */
230c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected HashMap<String, Integer> mApnToDataConnectionId =
231c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                                    new HashMap<String, Integer>();
232c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
233c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /** Phone.APN_TYPE_* ===> ApnContext */
234c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected ConcurrentHashMap<String, ApnContext> mApnContexts =
235c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                                    new ConcurrentHashMap<String, ApnContext>();
236c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
237c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /* Currently active APN */
238c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected ApnSetting mActiveApn;
239c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
240c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /** allApns holds all apns */
241c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected ArrayList<ApnSetting> mAllApns = null;
242c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
243c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /** preferred apn */
244c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected ApnSetting mPreferredApn = null;
245c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
246c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /** Is packet service restricted by network */
247c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected boolean mIsPsRestricted = false;
248c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
249c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /* Once disposed dont handle any messages */
250c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected boolean mIsDisposed = false;
251c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
252cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    protected ContentResolver mResolver;
253cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
254c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected BroadcastReceiver mIntentReceiver = new BroadcastReceiver ()
255c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    {
256c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        @Override
257c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        public void onReceive(Context context, Intent intent)
258c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        {
259c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            String action = intent.getAction();
260c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            if (DBG) log("onReceive: action=" + action);
261c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            if (action.equals(Intent.ACTION_SCREEN_ON)) {
262c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                mIsScreenOn = true;
263c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                stopNetStatPoll();
264c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                startNetStatPoll();
265c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                restartDataStallAlarm();
266c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            } else if (action.equals(Intent.ACTION_SCREEN_OFF)) {
267c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                mIsScreenOn = false;
268c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                stopNetStatPoll();
269c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                startNetStatPoll();
270c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                restartDataStallAlarm();
271c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            } else if (action.startsWith(getActionIntentReconnectAlarm())) {
272c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                log("Reconnect alarm. Previous state was " + mState);
273c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                onActionIntentReconnectAlarm(intent);
274c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            } else if (action.equals(getActionIntentDataStallAlarm())) {
275c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                onActionIntentDataStallAlarm(intent);
276c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            } else if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
277c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                final android.net.NetworkInfo networkInfo = (NetworkInfo)
278c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
279c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                mIsWifiConnected = (networkInfo != null && networkInfo.isConnected());
280c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            } else if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) {
281c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                final boolean enabled = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,
282c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        WifiManager.WIFI_STATE_UNKNOWN) == WifiManager.WIFI_STATE_ENABLED;
283c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
284c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (!enabled) {
285c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    // when WiFi got disabled, the NETWORK_STATE_CHANGED_ACTION
286c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    // quit and won't report disconnected until next enabling.
287c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    mIsWifiConnected = false;
288c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
289c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            } else if (action.equals(INTENT_SET_FAIL_DATA_SETUP_COUNTER)) {
290c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                mFailDataSetupCounter = intent.getIntExtra(FAIL_DATA_SETUP_COUNTER, 1);
291c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                mFailDataSetupFailCause = FailCause.fromInt(
292c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        intent.getIntExtra(FAIL_DATA_SETUP_FAIL_CAUSE,
293c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                                                    FailCause.ERROR_UNSPECIFIED.getErrorCode()));
294c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (DBG) log("set mFailDataSetupCounter=" + mFailDataSetupCounter +
295c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        " mFailDataSetupFailCause=" + mFailDataSetupFailCause);
296c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
297c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
298c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    };
299c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
300c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private final DataRoamingSettingObserver mDataRoamingSettingObserver;
301cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    private Runnable mPollNetStat = new Runnable()
302cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    {
303cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        @Override
304cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        public void run() {
305cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            updateDataActivity();
306cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
307cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            if (mIsScreenOn) {
308b840987a39e7149c1364739696977089cd53814dWink Saville                mNetStatPollPeriod = Settings.Global.getInt(mResolver,
309b840987a39e7149c1364739696977089cd53814dWink Saville                        Settings.Global.PDP_WATCHDOG_POLL_INTERVAL_MS, POLL_NETSTAT_MILLIS);
310cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            } else {
311b840987a39e7149c1364739696977089cd53814dWink Saville                mNetStatPollPeriod = Settings.Global.getInt(mResolver,
312b840987a39e7149c1364739696977089cd53814dWink Saville                        Settings.Global.PDP_WATCHDOG_LONG_POLL_INTERVAL_MS,
313cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                        POLL_NETSTAT_SCREEN_OFF_MILLIS);
314cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            }
315cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
316cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            if (mNetStatPollEnabled) {
317cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                mDataConnectionTracker.postDelayed(this, mNetStatPollPeriod);
318cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            }
319cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
320cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    };
321c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
322c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private class DataRoamingSettingObserver extends ContentObserver {
323c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        public DataRoamingSettingObserver(Handler handler) {
324c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            super(handler);
325c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
326c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
327c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        public void register(Context context) {
328c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            final ContentResolver resolver = context.getContentResolver();
329c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            resolver.registerContentObserver(
330b840987a39e7149c1364739696977089cd53814dWink Saville                    Settings.Global.getUriFor(Settings.Global.DATA_ROAMING), false, this);
331c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
332c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
333c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        public void unregister(Context context) {
334c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            final ContentResolver resolver = context.getContentResolver();
335c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            resolver.unregisterContentObserver(this);
336c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
337c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
338c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        @Override
339c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        public void onChange(boolean selfChange) {
340c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            // already running on mPhone handler thread
341c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            handleDataOnRoamingChange();
342c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
343c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
344c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
345c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
346c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * Maintian the sum of transmit and receive packets.
347c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
348c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * The packet counts are initizlied and reset to -1 and
349c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * remain -1 until they can be updated.
350c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
351c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public class TxRxSum {
352c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        public long txPkts;
353c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        public long rxPkts;
354c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
355c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        public TxRxSum() {
356c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            reset();
357c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
358c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
359c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        public TxRxSum(long txPkts, long rxPkts) {
360c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            this.txPkts = txPkts;
361c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            this.rxPkts = rxPkts;
362c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
363c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
364c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        public TxRxSum(TxRxSum sum) {
365c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            txPkts = sum.txPkts;
366c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            rxPkts = sum.rxPkts;
367c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
368c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
369c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        public void reset() {
370c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            txPkts = -1;
371c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            rxPkts = -1;
372c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
373c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
374c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        public String toString() {
375c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            return "{txSum=" + txPkts + " rxSum=" + rxPkts + "}";
376c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
377c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
378c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        public void updateTxRxSum() {
379cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            this.txPkts = TrafficStats.getMobileTxPackets();
380cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            this.rxPkts = TrafficStats.getMobileRxPackets();
381c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
382c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
383c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
384c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected boolean isDataSetupCompleteOk(AsyncResult ar) {
385c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (ar.exception != null) {
386c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            if (DBG) log("isDataSetupCompleteOk return false, ar.result=" + ar.result);
387c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            return false;
388c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
389c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (mFailDataSetupCounter <= 0) {
390c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            if (DBG) log("isDataSetupCompleteOk return true");
391c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            return true;
392c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
393c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        ar.result = mFailDataSetupFailCause;
394c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (DBG) {
395c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            log("isDataSetupCompleteOk return false" +
396c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    " mFailDataSetupCounter=" + mFailDataSetupCounter +
397c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    " mFailDataSetupFailCause=" + mFailDataSetupFailCause);
398c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
399c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        mFailDataSetupCounter -= 1;
400c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        return false;
401c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
402c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
403c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected void onActionIntentReconnectAlarm(Intent intent) {
404c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        String reason = intent.getStringExtra(INTENT_RECONNECT_ALARM_EXTRA_REASON);
405c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (mState == DctConstants.State.FAILED) {
406c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            Message msg = obtainMessage(DctConstants.EVENT_CLEAN_UP_CONNECTION);
407c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            msg.arg1 = 0; // tearDown is false
408c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            msg.arg2 = 0;
409c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            msg.obj = reason;
410c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            sendMessage(msg);
411c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
412c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        sendMessage(obtainMessage(DctConstants.EVENT_TRY_SETUP_DATA));
413c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
414c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
415c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected void onActionIntentDataStallAlarm(Intent intent) {
416c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (VDBG) log("onActionIntentDataStallAlarm: action=" + intent.getAction());
417c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        Message msg = obtainMessage(DctConstants.EVENT_DATA_STALL_ALARM,
418c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                intent.getAction());
419c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        msg.arg1 = intent.getIntExtra(DATA_STALL_ALARM_TAG_EXTRA, 0);
420c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        sendMessage(msg);
421c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
422c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
423c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
424c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * Default constructor
425c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
426c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected DataConnectionTracker(PhoneBase phone) {
427c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        super();
428c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (DBG) log("DCT.constructor");
429c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        mPhone = phone;
430bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka        mUiccController = UiccController.getInstance();
431bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka        mUiccController.registerForIccChanged(this, DctConstants.EVENT_ICC_CHANGED, null);
432c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
433c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        IntentFilter filter = new IntentFilter();
434c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        filter.addAction(getActionIntentReconnectAlarm());
435c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        filter.addAction(Intent.ACTION_SCREEN_ON);
436c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        filter.addAction(Intent.ACTION_SCREEN_OFF);
437c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
438c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
439c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        filter.addAction(INTENT_SET_FAIL_DATA_SETUP_COUNTER);
440cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        filter.addAction(getActionIntentDataStallAlarm());
441c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
442b840987a39e7149c1364739696977089cd53814dWink Saville        mUserDataEnabled = Settings.Global.getInt(
443b840987a39e7149c1364739696977089cd53814dWink Saville                mPhone.getContext().getContentResolver(), Settings.Global.MOBILE_DATA, 1) == 1;
444c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
445c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // TODO: Why is this registering the phone as the receiver of the intent
446c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        //       and not its own handler?
447c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        mPhone.getContext().registerReceiver(mIntentReceiver, filter, null, mPhone);
448c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
449c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // This preference tells us 1) initial condition for "dataEnabled",
450c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // and 2) whether the RIL will setup the baseband to auto-PS attach.
451c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
452c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        dataEnabled[DctConstants.APN_DEFAULT_ID] =
453c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                SystemProperties.getBoolean(DEFALUT_DATA_ON_BOOT_PROP,true);
454c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (dataEnabled[DctConstants.APN_DEFAULT_ID]) {
455c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            enabledCount++;
456c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
457c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
458c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mPhone.getContext());
459c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        mAutoAttachOnCreation = sp.getBoolean(PhoneBase.DATA_DISABLED_ON_BOOT_KEY, false);
460c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
461b840987a39e7149c1364739696977089cd53814dWink Saville        // watch for changes to Settings.Global.DATA_ROAMING
462c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        mDataRoamingSettingObserver = new DataRoamingSettingObserver(mPhone);
463c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        mDataRoamingSettingObserver.register(mPhone.getContext());
464cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
465cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        mResolver = mPhone.getContext().getContentResolver();
466c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
467c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
468c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public void dispose() {
469c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (DBG) log("DCT.dispose");
470c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        for (DataConnectionAc dcac : mDataConnectionAsyncChannels.values()) {
471c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            dcac.disconnect();
472c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
473c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        mDataConnectionAsyncChannels.clear();
474c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        mIsDisposed = true;
475c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        mPhone.getContext().unregisterReceiver(this.mIntentReceiver);
476c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        mDataRoamingSettingObserver.unregister(mPhone.getContext());
477bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka        mUiccController.unregisterForIccChanged(this);
478c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
479c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
480c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected void broadcastMessenger() {
481c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        Intent intent = new Intent(DctConstants.ACTION_DATA_CONNECTION_TRACKER_MESSENGER);
482c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        intent.putExtra(DctConstants.EXTRA_MESSENGER, new Messenger(this));
483c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        mPhone.getContext().sendBroadcast(intent);
484c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
485c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
486c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public DctConstants.Activity getActivity() {
487c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        return mActivity;
488c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
489c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
490c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public boolean isApnTypeActive(String type) {
491c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // TODO: support simultaneous with List instead
492c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (PhoneConstants.APN_TYPE_DUN.equals(type)) {
493c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            ApnSetting dunApn = fetchDunApn();
494c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            if (dunApn != null) {
495c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                return ((mActiveApn != null) && (dunApn.toString().equals(mActiveApn.toString())));
496c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
497c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
498c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        return mActiveApn != null && mActiveApn.canHandleType(type);
499c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
500c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
501c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected ApnSetting fetchDunApn() {
502c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (SystemProperties.getBoolean("net.tethering.noprovisioning", false)) {
503c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            log("fetchDunApn: net.tethering.noprovisioning=true ret: null");
504c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            return null;
505c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
506c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        Context c = mPhone.getContext();
507b840987a39e7149c1364739696977089cd53814dWink Saville        String apnData = Settings.Global.getString(c.getContentResolver(),
508b840987a39e7149c1364739696977089cd53814dWink Saville                Settings.Global.TETHER_DUN_APN);
509c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        ApnSetting dunSetting = ApnSetting.fromString(apnData);
510c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (dunSetting != null) {
511b840987a39e7149c1364739696977089cd53814dWink Saville            if (VDBG) log("fetchDunApn: global TETHER_DUN_APN dunSetting=" + dunSetting);
512c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            return dunSetting;
513c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
514c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
515c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        apnData = c.getResources().getString(R.string.config_tether_apndata);
516c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        dunSetting = ApnSetting.fromString(apnData);
517c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (VDBG) log("fetchDunApn: config_tether_apndata dunSetting=" + dunSetting);
518c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        return dunSetting;
519c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
520c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
521c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public String[] getActiveApnTypes() {
522c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        String[] result;
523c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (mActiveApn != null) {
524c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            result = mActiveApn.types;
525c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } else {
526c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            result = new String[1];
527c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            result[0] = PhoneConstants.APN_TYPE_DEFAULT;
528c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
529c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        return result;
530c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
531c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
532c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /** TODO: See if we can remove */
533c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public String getActiveApnString(String apnType) {
534c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        String result = null;
535c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (mActiveApn != null) {
536c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            result = mActiveApn.apn;
537c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
538c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        return result;
539c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
540c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
541c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
542b840987a39e7149c1364739696977089cd53814dWink Saville     * Modify {@link Settings.Global#DATA_ROAMING} value.
543c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
544c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public void setDataOnRoamingEnabled(boolean enabled) {
545c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (getDataOnRoamingEnabled() != enabled) {
546c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            final ContentResolver resolver = mPhone.getContext().getContentResolver();
547b840987a39e7149c1364739696977089cd53814dWink Saville            Settings.Global.putInt(resolver, Settings.Global.DATA_ROAMING, enabled ? 1 : 0);
548c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            // will trigger handleDataOnRoamingChange() through observer
549c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
550c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
551c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
552c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
553b840987a39e7149c1364739696977089cd53814dWink Saville     * Return current {@link Settings.Global#DATA_ROAMING} value.
554c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
555c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public boolean getDataOnRoamingEnabled() {
556c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        try {
557c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            final ContentResolver resolver = mPhone.getContext().getContentResolver();
558b840987a39e7149c1364739696977089cd53814dWink Saville            return Settings.Global.getInt(resolver, Settings.Global.DATA_ROAMING) != 0;
559c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } catch (SettingNotFoundException snfe) {
560c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            return false;
561c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
562c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
563c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
564c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private void handleDataOnRoamingChange() {
565c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (mPhone.getServiceState().getRoaming()) {
566c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            if (getDataOnRoamingEnabled()) {
567c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                resetAllRetryCounts();
568c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
569c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            sendMessage(obtainMessage(DctConstants.EVENT_ROAMING_ON));
570c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
571c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
572c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
573c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    // abstract methods
574c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected abstract String getActionIntentReconnectAlarm();
575c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected abstract String getActionIntentDataStallAlarm();
576c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected abstract void restartRadio();
577c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected abstract void log(String s);
578c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected abstract void loge(String s);
579c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected abstract boolean isDataAllowed();
580c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected abstract boolean isApnTypeAvailable(String type);
581c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public    abstract DctConstants.State getState(String apnType);
582c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected abstract void setState(DctConstants.State s);
583c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected abstract void gotoIdleAndNotifyDataConnection(String reason);
584c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
585c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected abstract boolean onTrySetupData(String reason);
586c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected abstract void onRoamingOff();
587c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected abstract void onRoamingOn();
588c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected abstract void onRadioAvailable();
589c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected abstract void onRadioOffOrNotAvailable();
590c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected abstract void onDataSetupComplete(AsyncResult ar);
591c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected abstract void onDisconnectDone(int connId, AsyncResult ar);
592c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected abstract void onVoiceCallStarted();
593c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected abstract void onVoiceCallEnded();
594c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected abstract void onCleanUpConnection(boolean tearDown, int apnId, String reason);
595c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected abstract void onCleanUpAllConnections(String cause);
596c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected abstract boolean isDataPossible(String apnType);
597bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka    protected abstract void onUpdateIcc();
598c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
599c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    @Override
600c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public void handleMessage(Message msg) {
601c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        switch (msg.what) {
602c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case AsyncChannel.CMD_CHANNEL_DISCONNECTED: {
603c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                log("DISCONNECTED_CONNECTED: msg=" + msg);
604c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                DataConnectionAc dcac = (DataConnectionAc) msg.obj;
605c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                mDataConnectionAsyncChannels.remove(dcac.dataConnection.getDataConnectionId());
606c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                dcac.disconnected();
607c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
608c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
609c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case DctConstants.EVENT_ENABLE_NEW_APN:
610c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                onEnableApn(msg.arg1, msg.arg2);
611c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
612c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
613c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case DctConstants.EVENT_TRY_SETUP_DATA:
614c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                String reason = null;
615c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (msg.obj instanceof String) {
616c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    reason = (String) msg.obj;
617c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
618c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                onTrySetupData(reason);
619c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
620c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
621c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case DctConstants.EVENT_DATA_STALL_ALARM:
622c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                onDataStallAlarm(msg.arg1);
623c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
624c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
625c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case DctConstants.EVENT_ROAMING_OFF:
626c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (getDataOnRoamingEnabled() == false) {
627c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    resetAllRetryCounts();
628c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
629c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                onRoamingOff();
630c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
631c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
632c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case DctConstants.EVENT_ROAMING_ON:
633c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                onRoamingOn();
634c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
635c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
636c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case DctConstants.EVENT_RADIO_AVAILABLE:
637c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                onRadioAvailable();
638c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
639c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
640c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case DctConstants.EVENT_RADIO_OFF_OR_NOT_AVAILABLE:
641c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                onRadioOffOrNotAvailable();
642c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
643c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
644c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case DctConstants.EVENT_DATA_SETUP_COMPLETE:
645c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                mCidActive = msg.arg1;
646c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                onDataSetupComplete((AsyncResult) msg.obj);
647c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
648c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
649c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case DctConstants.EVENT_DISCONNECT_DONE:
650c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                log("DataConnectoinTracker.handleMessage: EVENT_DISCONNECT_DONE msg=" + msg);
651c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                onDisconnectDone(msg.arg1, (AsyncResult) msg.obj);
652c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
653c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
654c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case DctConstants.EVENT_VOICE_CALL_STARTED:
655c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                onVoiceCallStarted();
656c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
657c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
658c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case DctConstants.EVENT_VOICE_CALL_ENDED:
659c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                onVoiceCallEnded();
660c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
661c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
662c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case DctConstants.EVENT_CLEAN_UP_ALL_CONNECTIONS: {
663c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                onCleanUpAllConnections((String) msg.obj);
664c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
665c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
666c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case DctConstants.EVENT_CLEAN_UP_CONNECTION: {
667c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                boolean tearDown = (msg.arg1 == 0) ? false : true;
668c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                onCleanUpConnection(tearDown, msg.arg2, (String) msg.obj);
669c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
670c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
671c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case DctConstants.EVENT_SET_INTERNAL_DATA_ENABLE: {
672c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                boolean enabled = (msg.arg1 == DctConstants.ENABLED) ? true : false;
673c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                onSetInternalDataEnabled(enabled);
674c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
675c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
676c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case DctConstants.EVENT_RESET_DONE: {
677c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (DBG) log("EVENT_RESET_DONE");
678c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                onResetDone((AsyncResult) msg.obj);
679c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
680c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
681c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case DctConstants.CMD_SET_USER_DATA_ENABLE: {
682c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                final boolean enabled = (msg.arg1 == DctConstants.ENABLED) ? true : false;
683c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (DBG) log("CMD_SET_USER_DATA_ENABLE enabled=" + enabled);
684c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                onSetUserDataEnabled(enabled);
685c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
686c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
687c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case DctConstants.CMD_SET_DEPENDENCY_MET: {
688c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                boolean met = (msg.arg1 == DctConstants.ENABLED) ? true : false;
689c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (DBG) log("CMD_SET_DEPENDENCY_MET met=" + met);
690c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                Bundle bundle = msg.getData();
691c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (bundle != null) {
692c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    String apnType = (String)bundle.get(DctConstants.APN_TYPE_KEY);
693c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    if (apnType != null) {
694c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        onSetDependencyMet(apnType, met);
695c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    }
696c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
697c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
698c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
699c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case DctConstants.CMD_SET_POLICY_DATA_ENABLE: {
700c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                final boolean enabled = (msg.arg1 == DctConstants.ENABLED) ? true : false;
701c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                onSetPolicyDataEnabled(enabled);
702c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
703c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
704bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka            case DctConstants.EVENT_ICC_CHANGED:
705bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka                onUpdateIcc();
706bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka                break;
707bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka
708c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            default:
709c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                Log.e("DATA", "Unidentified event msg=" + msg);
710c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
711c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
712c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
713c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
714c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
715c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * Report on whether data connectivity is enabled
716c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
717c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @return {@code false} if data connectivity has been explicitly disabled,
718c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *         {@code true} otherwise.
719c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
720c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public boolean getAnyDataEnabled() {
721c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        final boolean result;
722c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        synchronized (mDataEnabledLock) {
723c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            result = (mInternalDataEnabled && mUserDataEnabled && sPolicyDataEnabled
724c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    && (enabledCount != 0));
725c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
726c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (!result && DBG) log("getAnyDataEnabled " + result);
727c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        return result;
728c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
729c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
730c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected boolean isEmergency() {
731c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        final boolean result;
732c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        synchronized (mDataEnabledLock) {
733c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            result = mPhone.isInEcm() || mPhone.isInEmergencyCall();
734c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
735c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        log("isEmergency: result=" + result);
736c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        return result;
737c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
738c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
739c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected int apnTypeToId(String type) {
740c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (TextUtils.equals(type, PhoneConstants.APN_TYPE_DEFAULT)) {
741c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            return DctConstants.APN_DEFAULT_ID;
742c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } else if (TextUtils.equals(type, PhoneConstants.APN_TYPE_MMS)) {
743c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            return DctConstants.APN_MMS_ID;
744c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } else if (TextUtils.equals(type, PhoneConstants.APN_TYPE_SUPL)) {
745c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            return DctConstants.APN_SUPL_ID;
746c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } else if (TextUtils.equals(type, PhoneConstants.APN_TYPE_DUN)) {
747c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            return DctConstants.APN_DUN_ID;
748c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } else if (TextUtils.equals(type, PhoneConstants.APN_TYPE_HIPRI)) {
749c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            return DctConstants.APN_HIPRI_ID;
750c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } else if (TextUtils.equals(type, PhoneConstants.APN_TYPE_IMS)) {
751c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            return DctConstants.APN_IMS_ID;
752c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } else if (TextUtils.equals(type, PhoneConstants.APN_TYPE_FOTA)) {
753c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            return DctConstants.APN_FOTA_ID;
754c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } else if (TextUtils.equals(type, PhoneConstants.APN_TYPE_CBS)) {
755c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            return DctConstants.APN_CBS_ID;
756c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } else {
757c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            return DctConstants.APN_INVALID_ID;
758c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
759c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
760c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
761c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected String apnIdToType(int id) {
762c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        switch (id) {
763c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        case DctConstants.APN_DEFAULT_ID:
764c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            return PhoneConstants.APN_TYPE_DEFAULT;
765c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        case DctConstants.APN_MMS_ID:
766c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            return PhoneConstants.APN_TYPE_MMS;
767c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        case DctConstants.APN_SUPL_ID:
768c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            return PhoneConstants.APN_TYPE_SUPL;
769c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        case DctConstants.APN_DUN_ID:
770c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            return PhoneConstants.APN_TYPE_DUN;
771c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        case DctConstants.APN_HIPRI_ID:
772c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            return PhoneConstants.APN_TYPE_HIPRI;
773c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        case DctConstants.APN_IMS_ID:
774c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            return PhoneConstants.APN_TYPE_IMS;
775c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        case DctConstants.APN_FOTA_ID:
776c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            return PhoneConstants.APN_TYPE_FOTA;
777c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        case DctConstants.APN_CBS_ID:
778c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            return PhoneConstants.APN_TYPE_CBS;
779c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        default:
780c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            log("Unknown id (" + id + ") in apnIdToType");
781c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            return PhoneConstants.APN_TYPE_DEFAULT;
782c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
783c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
784c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
785c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected LinkProperties getLinkProperties(String apnType) {
786c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        int id = apnTypeToId(apnType);
787c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
788c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (isApnIdEnabled(id)) {
789c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            // TODO - remove this cdma-only hack and support multiple DCs.
790c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            DataConnectionAc dcac = mDataConnectionAsyncChannels.get(0);
791c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            return dcac.getLinkPropertiesSync();
792c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } else {
793c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            return new LinkProperties();
794c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
795c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
796c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
797c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected LinkCapabilities getLinkCapabilities(String apnType) {
798c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        int id = apnTypeToId(apnType);
799c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (isApnIdEnabled(id)) {
800c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            // TODO - remove this cdma-only hack and support multiple DCs.
801c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            DataConnectionAc dcac = mDataConnectionAsyncChannels.get(0);
802c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            return dcac.getLinkCapabilitiesSync();
803c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } else {
804c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            return new LinkCapabilities();
805c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
806c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
807c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
808c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    // tell all active apns of the current condition
809c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected void notifyDataConnection(String reason) {
810c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        for (int id = 0; id < DctConstants.APN_NUM_TYPES; id++) {
811c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            if (dataEnabled[id]) {
812c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                mPhone.notifyDataConnection(reason, apnIdToType(id));
813c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
814c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
815c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        notifyOffApnsOfAvailability(reason);
816c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
817c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
818c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    // a new APN has gone active and needs to send events to catch up with the
819c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    // current condition
820c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private void notifyApnIdUpToCurrent(String reason, int apnId) {
821c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        switch (mState) {
822c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case IDLE:
823c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case INITING:
824c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
825c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case CONNECTING:
826c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case SCANNING:
827c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                mPhone.notifyDataConnection(reason, apnIdToType(apnId),
828c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        PhoneConstants.DataState.CONNECTING);
829c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
830c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case CONNECTED:
831c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case DISCONNECTING:
832c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                mPhone.notifyDataConnection(reason, apnIdToType(apnId),
833c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        PhoneConstants.DataState.CONNECTING);
834c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                mPhone.notifyDataConnection(reason, apnIdToType(apnId),
835c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        PhoneConstants.DataState.CONNECTED);
836c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
837c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
838c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
839c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
840c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    // since we normally don't send info to a disconnected APN, we need to do this specially
841c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private void notifyApnIdDisconnected(String reason, int apnId) {
842c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        mPhone.notifyDataConnection(reason, apnIdToType(apnId),
843c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                PhoneConstants.DataState.DISCONNECTED);
844c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
845c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
846c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    // disabled apn's still need avail/unavail notificiations - send them out
847c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected void notifyOffApnsOfAvailability(String reason) {
848c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (DBG) log("notifyOffApnsOfAvailability - reason= " + reason);
849c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        for (int id = 0; id < DctConstants.APN_NUM_TYPES; id++) {
850c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            if (!isApnIdEnabled(id)) {
851c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                notifyApnIdDisconnected(reason, id);
852c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
853c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
854c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
855c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
856c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public boolean isApnTypeEnabled(String apnType) {
857c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (apnType == null) {
858c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            return false;
859c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } else {
860c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            return isApnIdEnabled(apnTypeToId(apnType));
861c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
862c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
863c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
864c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected synchronized boolean isApnIdEnabled(int id) {
865c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (id != DctConstants.APN_INVALID_ID) {
866c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            return dataEnabled[id];
867c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
868c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        return false;
869c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
870c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
871c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
872c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * Ensure that we are connected to an APN of the specified type.
873c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
874c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param type the APN type (currently the only valid values are
875c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *            {@link Phone#APN_TYPE_MMS} and {@link Phone#APN_TYPE_SUPL})
876c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @return Success is indicated by {@code Phone.APN_ALREADY_ACTIVE} or
877c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *         {@code Phone.APN_REQUEST_STARTED}. In the latter case, a
878c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *         broadcast will be sent by the ConnectivityManager when a
879c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *         connection to the APN has been established.
880c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
881c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public synchronized int enableApnType(String type) {
882c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        int id = apnTypeToId(type);
883c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (id == DctConstants.APN_INVALID_ID) {
884c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            return PhoneConstants.APN_REQUEST_FAILED;
885c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
886c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
887c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (DBG) {
888c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            log("enableApnType(" + type + "), isApnTypeActive = " + isApnTypeActive(type)
889c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    + ", isApnIdEnabled =" + isApnIdEnabled(id) + " and state = " + mState);
890c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
891c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
892c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (!isApnTypeAvailable(type)) {
893c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            if (DBG) log("type not available");
894c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            return PhoneConstants.APN_TYPE_NOT_AVAILABLE;
895c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
896c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
897c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (isApnIdEnabled(id)) {
898c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            return PhoneConstants.APN_ALREADY_ACTIVE;
899c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } else {
900c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            setEnabled(id, true);
901c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
902c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        return PhoneConstants.APN_REQUEST_STARTED;
903c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
904c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
905c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
906c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * The APN of the specified type is no longer needed. Ensure that if use of
907c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * the default APN has not been explicitly disabled, we are connected to the
908c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * default APN.
909c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
910c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param type the APN type. The only valid values are currently
911c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *            {@link Phone#APN_TYPE_MMS} and {@link Phone#APN_TYPE_SUPL}.
912c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @return Success is indicated by {@code PhoneConstants.APN_ALREADY_ACTIVE} or
913c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *         {@code PhoneConstants.APN_REQUEST_STARTED}. In the latter case, a
914c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *         broadcast will be sent by the ConnectivityManager when a
915c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *         connection to the APN has been disconnected. A {@code
916c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *         PhoneConstants.APN_REQUEST_FAILED} is returned if the type parameter is
917c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *         invalid or if the apn wasn't enabled.
918c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
919c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public synchronized int disableApnType(String type) {
920c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (DBG) log("disableApnType(" + type + ")");
921c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        int id = apnTypeToId(type);
922c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (id == DctConstants.APN_INVALID_ID) {
923c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            return PhoneConstants.APN_REQUEST_FAILED;
924c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
925c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (isApnIdEnabled(id)) {
926c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            setEnabled(id, false);
927c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            if (isApnTypeActive(PhoneConstants.APN_TYPE_DEFAULT)) {
928c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (dataEnabled[DctConstants.APN_DEFAULT_ID]) {
929c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    return PhoneConstants.APN_ALREADY_ACTIVE;
930c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                } else {
931c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    return PhoneConstants.APN_REQUEST_STARTED;
932c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
933c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            } else {
934c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                return PhoneConstants.APN_REQUEST_STARTED;
935c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
936c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } else {
937c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            return PhoneConstants.APN_REQUEST_FAILED;
938c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
939c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
940c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
941c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected void setEnabled(int id, boolean enable) {
942c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (DBG) {
943c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            log("setEnabled(" + id + ", " + enable + ") with old state = " + dataEnabled[id]
944c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    + " and enabledCount = " + enabledCount);
945c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
946c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        Message msg = obtainMessage(DctConstants.EVENT_ENABLE_NEW_APN);
947c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        msg.arg1 = id;
948c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        msg.arg2 = (enable ? DctConstants.ENABLED : DctConstants.DISABLED);
949c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        sendMessage(msg);
950c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
951c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
952c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected void onEnableApn(int apnId, int enabled) {
953c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (DBG) {
954c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            log("EVENT_APN_ENABLE_REQUEST apnId=" + apnId + ", apnType=" + apnIdToType(apnId) +
955c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    ", enabled=" + enabled + ", dataEnabled = " + dataEnabled[apnId] +
956c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    ", enabledCount = " + enabledCount + ", isApnTypeActive = " +
957c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    isApnTypeActive(apnIdToType(apnId)));
958c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
959c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (enabled == DctConstants.ENABLED) {
960c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            synchronized (this) {
961c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (!dataEnabled[apnId]) {
962c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    dataEnabled[apnId] = true;
963c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    enabledCount++;
964c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
965c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
966c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            String type = apnIdToType(apnId);
967c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            if (!isApnTypeActive(type)) {
968c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                mRequestedApnType = type;
969c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                onEnableNewApn();
970c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            } else {
971c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                notifyApnIdUpToCurrent(Phone.REASON_APN_SWITCHED, apnId);
972c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
973c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } else {
974c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            // disable
975c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            boolean didDisable = false;
976c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            synchronized (this) {
977c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (dataEnabled[apnId]) {
978c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    dataEnabled[apnId] = false;
979c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    enabledCount--;
980c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    didDisable = true;
981c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
982c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
983c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            if (didDisable) {
984c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if ((enabledCount == 0) || (apnId == DctConstants.APN_DUN_ID)) {
985c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    mRequestedApnType = PhoneConstants.APN_TYPE_DEFAULT;
986c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    onCleanUpConnection(true, apnId, Phone.REASON_DATA_DISABLED);
987c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
988c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
989c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // send the disconnect msg manually, since the normal route wont send
990c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // it (it's not enabled)
991c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                notifyApnIdDisconnected(Phone.REASON_DATA_DISABLED, apnId);
992c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (dataEnabled[DctConstants.APN_DEFAULT_ID] == true
993c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        && !isApnTypeActive(PhoneConstants.APN_TYPE_DEFAULT)) {
994c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    // TODO - this is an ugly way to restore the default conn - should be done
995c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    // by a real contention manager and policy that disconnects the lower pri
996c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    // stuff as enable requests come in and pops them back on as we disable back
997c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    // down to the lower pri stuff
998c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    mRequestedApnType = PhoneConstants.APN_TYPE_DEFAULT;
999c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    onEnableNewApn();
1000c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
1001c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
1002c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1003c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1004c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1005c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
1006c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * Called when we switch APNs.
1007c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
1008c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * mRequestedApnType is set prior to call
1009c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * To be overridden.
1010c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
1011c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected void onEnableNewApn() {
1012c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1013c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1014c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
1015c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * Called when EVENT_RESET_DONE is received so goto
1016c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * IDLE state and send notifications to those interested.
1017c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
1018c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * TODO - currently unused.  Needs to be hooked into DataConnection cleanup
1019c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * TODO - needs to pass some notion of which connection is reset..
1020c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
1021c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected void onResetDone(AsyncResult ar) {
1022c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (DBG) log("EVENT_RESET_DONE");
1023c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        String reason = null;
1024c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (ar.userObj instanceof String) {
1025c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            reason = (String) ar.userObj;
1026c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1027c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        gotoIdleAndNotifyDataConnection(reason);
1028c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1029c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1030c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
1031c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * Prevent mobile data connections from being established, or once again
1032c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * allow mobile data connections. If the state toggles, then either tear
1033c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * down or set up data, as appropriate to match the new state.
1034c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
1035c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param enable indicates whether to enable ({@code true}) or disable (
1036c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *            {@code false}) data
1037c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @return {@code true} if the operation succeeded
1038c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
1039c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public boolean setInternalDataEnabled(boolean enable) {
1040c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (DBG)
1041c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            log("setInternalDataEnabled(" + enable + ")");
1042c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1043c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        Message msg = obtainMessage(DctConstants.EVENT_SET_INTERNAL_DATA_ENABLE);
1044c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        msg.arg1 = (enable ? DctConstants.ENABLED : DctConstants.DISABLED);
1045c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        sendMessage(msg);
1046c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        return true;
1047c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1048c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1049c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected void onSetInternalDataEnabled(boolean enabled) {
1050c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        synchronized (mDataEnabledLock) {
1051c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            mInternalDataEnabled = enabled;
1052c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            if (enabled) {
1053c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                log("onSetInternalDataEnabled: changed to enabled, try to setup data call");
1054c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                resetAllRetryCounts();
1055c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                onTrySetupData(Phone.REASON_DATA_ENABLED);
1056c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            } else {
1057c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                log("onSetInternalDataEnabled: changed to disabled, cleanUpAllConnections");
1058c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                cleanUpAllConnections(null);
1059c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
1060c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1061c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1062c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1063c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public void cleanUpAllConnections(String cause) {
1064c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        Message msg = obtainMessage(DctConstants.EVENT_CLEAN_UP_ALL_CONNECTIONS);
1065c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        msg.obj = cause;
1066c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        sendMessage(msg);
1067c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1068c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1069c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public abstract boolean isDisconnected();
1070c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1071c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected void onSetUserDataEnabled(boolean enabled) {
1072c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        synchronized (mDataEnabledLock) {
1073c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            final boolean prevEnabled = getAnyDataEnabled();
1074c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            if (mUserDataEnabled != enabled) {
1075c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                mUserDataEnabled = enabled;
1076b840987a39e7149c1364739696977089cd53814dWink Saville                Settings.Global.putInt(mPhone.getContext().getContentResolver(),
1077b840987a39e7149c1364739696977089cd53814dWink Saville                        Settings.Global.MOBILE_DATA, enabled ? 1 : 0);
1078c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (getDataOnRoamingEnabled() == false &&
1079c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        mPhone.getServiceState().getRoaming() == true) {
1080c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    if (enabled) {
1081c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        notifyOffApnsOfAvailability(Phone.REASON_ROAMING_ON);
1082c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    } else {
1083c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        notifyOffApnsOfAvailability(Phone.REASON_DATA_DISABLED);
1084c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    }
1085c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
1086c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (prevEnabled != getAnyDataEnabled()) {
1087c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    if (!prevEnabled) {
1088c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        resetAllRetryCounts();
1089c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        onTrySetupData(Phone.REASON_DATA_ENABLED);
1090c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    } else {
1091c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        onCleanUpAllConnections(Phone.REASON_DATA_DISABLED);
1092c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    }
1093c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
1094c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
1095c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1096c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1097c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1098c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected void onSetDependencyMet(String apnType, boolean met) {
1099c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1100c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1101c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected void onSetPolicyDataEnabled(boolean enabled) {
1102c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        synchronized (mDataEnabledLock) {
1103c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            final boolean prevEnabled = getAnyDataEnabled();
1104c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            if (sPolicyDataEnabled != enabled) {
1105c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                sPolicyDataEnabled = enabled;
1106c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (prevEnabled != getAnyDataEnabled()) {
1107c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    if (!prevEnabled) {
1108c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        resetAllRetryCounts();
1109c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        onTrySetupData(Phone.REASON_DATA_ENABLED);
1110c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    } else {
1111c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        onCleanUpAllConnections(Phone.REASON_DATA_DISABLED);
1112c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    }
1113c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
1114c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
1115c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1116c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1117c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1118c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected String getReryConfig(boolean forDefault) {
1119c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        int nt = mPhone.getServiceState().getNetworkType();
1120c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1121c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if ((nt == TelephonyManager.NETWORK_TYPE_CDMA) ||
1122c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            (nt == TelephonyManager.NETWORK_TYPE_1xRTT) ||
1123c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            (nt == TelephonyManager.NETWORK_TYPE_EVDO_0) ||
1124c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            (nt == TelephonyManager.NETWORK_TYPE_EVDO_A) ||
1125c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            (nt == TelephonyManager.NETWORK_TYPE_EVDO_B) ||
1126c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            (nt == TelephonyManager.NETWORK_TYPE_EHRPD)) {
1127c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            // CDMA variant
1128c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            return SystemProperties.get("ro.cdma.data_retry_config");
1129c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } else {
1130c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            // Use GSM varient for all others.
1131c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            if (forDefault) {
1132c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                return SystemProperties.get("ro.gsm.data_retry_config");
1133c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            } else {
1134c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                return SystemProperties.get("ro.gsm.2nd_data_retry_config");
1135c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
1136c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1137c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1138c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1139c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected void resetAllRetryCounts() {
1140c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        for (ApnContext ac : mApnContexts.values()) {
1141c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            ac.setRetryCount(0);
1142c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1143c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        for (DataConnection dc : mDataConnections.values()) {
1144c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            dc.resetRetryCount();
1145c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1146c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1147c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1148cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    protected void resetPollStats() {
1149cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        mTxPkts = -1;
1150cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        mRxPkts = -1;
1151cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        mNetStatPollPeriod = POLL_NETSTAT_MILLIS;
1152cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    }
1153cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
1154cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    protected abstract DctConstants.State getOverallState();
1155cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
1156cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    protected void startNetStatPoll() {
1157cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        if (getOverallState() == DctConstants.State.CONNECTED && mNetStatPollEnabled == false) {
1158cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            if (DBG) log("startNetStatPoll");
1159cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            resetPollStats();
1160cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            mNetStatPollEnabled = true;
1161cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            mPollNetStat.run();
1162cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
1163cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    }
1164cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
1165cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    protected void stopNetStatPoll() {
1166cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        mNetStatPollEnabled = false;
1167cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        removeCallbacks(mPollNetStat);
1168cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        if (DBG) log("stopNetStatPoll");
1169cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    }
1170cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
1171cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    public void updateDataActivity() {
1172cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        long sent, received;
1173cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
1174cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        DctConstants.Activity newActivity;
1175cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
1176cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        TxRxSum preTxRxSum = new TxRxSum(mTxPkts, mRxPkts);
1177cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        TxRxSum curTxRxSum = new TxRxSum();
1178cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        curTxRxSum.updateTxRxSum();
1179cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        mTxPkts = curTxRxSum.txPkts;
1180cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        mRxPkts = curTxRxSum.rxPkts;
1181cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
1182cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        if (VDBG) {
1183cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            log("updateDataActivity: curTxRxSum=" + curTxRxSum + " preTxRxSum=" + preTxRxSum);
1184cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
1185cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
1186cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        if (mNetStatPollEnabled && (preTxRxSum.txPkts > 0 || preTxRxSum.rxPkts > 0)) {
1187cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            sent = mTxPkts - preTxRxSum.txPkts;
1188cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            received = mRxPkts - preTxRxSum.rxPkts;
1189cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
1190cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            if (VDBG)
1191cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                log("updateDataActivity: sent=" + sent + " received=" + received);
1192cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            if (sent > 0 && received > 0) {
1193cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                newActivity = DctConstants.Activity.DATAINANDOUT;
1194cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            } else if (sent > 0 && received == 0) {
1195cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                newActivity = DctConstants.Activity.DATAOUT;
1196cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            } else if (sent == 0 && received > 0) {
1197cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                newActivity = DctConstants.Activity.DATAIN;
1198cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            } else {
1199cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                newActivity = (mActivity == DctConstants.Activity.DORMANT) ?
1200cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                        mActivity : DctConstants.Activity.NONE;
1201cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            }
1202cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
1203cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            if (mActivity != newActivity && mIsScreenOn) {
1204cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                if (VDBG)
1205cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                    log("updateDataActivity: newActivity=" + newActivity);
1206cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                mActivity = newActivity;
1207cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                mPhone.notifyDataActivity();
1208cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            }
1209cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
1210cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    }
1211cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
1212cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    // Recovery action taken in case of data stall
1213cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    protected static class RecoveryAction {
1214cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        public static final int GET_DATA_CALL_LIST      = 0;
1215cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        public static final int CLEANUP                 = 1;
1216cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        public static final int REREGISTER              = 2;
1217cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        public static final int RADIO_RESTART           = 3;
1218cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        public static final int RADIO_RESTART_WITH_PROP = 4;
1219cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
1220cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        private static boolean isAggressiveRecovery(int value) {
1221cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            return ((value == RecoveryAction.CLEANUP) ||
1222cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                    (value == RecoveryAction.REREGISTER) ||
1223cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                    (value == RecoveryAction.RADIO_RESTART) ||
1224cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                    (value == RecoveryAction.RADIO_RESTART_WITH_PROP));
1225cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
1226cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    }
1227cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
1228cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    public int getRecoveryAction() {
1229cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        int action = Settings.System.getInt(mPhone.getContext().getContentResolver(),
1230cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                "radio.data.stall.recovery.action", RecoveryAction.GET_DATA_CALL_LIST);
1231cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        if (VDBG) log("getRecoveryAction: " + action);
1232cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        return action;
1233cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    }
1234cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    public void putRecoveryAction(int action) {
1235cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        Settings.System.putInt(mPhone.getContext().getContentResolver(),
1236cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                "radio.data.stall.recovery.action", action);
1237cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        if (VDBG) log("putRecoveryAction: " + action);
1238cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    }
1239cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
1240cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    protected boolean isConnected() {
1241cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        return false;
1242cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    }
1243cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
1244cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    protected void doRecovery() {
1245cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        if (getOverallState() == DctConstants.State.CONNECTED) {
1246cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            // Go through a series of recovery steps, each action transitions to the next action
1247cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            int recoveryAction = getRecoveryAction();
1248cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            switch (recoveryAction) {
1249cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            case RecoveryAction.GET_DATA_CALL_LIST:
1250cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                EventLog.writeEvent(EventLogTags.DATA_STALL_RECOVERY_GET_DATA_CALL_LIST,
1251cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                        mSentSinceLastRecv);
1252cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                if (DBG) log("doRecovery() get data call list");
1253cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                mPhone.mCM.getDataCallList(obtainMessage(DctConstants.EVENT_DATA_STATE_CHANGED));
1254cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                putRecoveryAction(RecoveryAction.CLEANUP);
1255cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                break;
1256cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            case RecoveryAction.CLEANUP:
1257cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                EventLog.writeEvent(EventLogTags.DATA_STALL_RECOVERY_CLEANUP, mSentSinceLastRecv);
1258cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                if (DBG) log("doRecovery() cleanup all connections");
1259cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                cleanUpAllConnections(Phone.REASON_PDP_RESET);
1260cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                putRecoveryAction(RecoveryAction.REREGISTER);
1261cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                break;
1262cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            case RecoveryAction.REREGISTER:
1263cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                EventLog.writeEvent(EventLogTags.DATA_STALL_RECOVERY_REREGISTER,
1264cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                        mSentSinceLastRecv);
1265cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                if (DBG) log("doRecovery() re-register");
1266cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                mPhone.getServiceStateTracker().reRegisterNetwork(null);
1267cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                putRecoveryAction(RecoveryAction.RADIO_RESTART);
1268cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                break;
1269cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            case RecoveryAction.RADIO_RESTART:
1270cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                EventLog.writeEvent(EventLogTags.DATA_STALL_RECOVERY_RADIO_RESTART,
1271cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                        mSentSinceLastRecv);
1272cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                if (DBG) log("restarting radio");
1273cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                putRecoveryAction(RecoveryAction.RADIO_RESTART_WITH_PROP);
1274cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                restartRadio();
1275cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                break;
1276cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            case RecoveryAction.RADIO_RESTART_WITH_PROP:
1277cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                // This is in case radio restart has not recovered the data.
1278cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                // It will set an additional "gsm.radioreset" property to tell
1279cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                // RIL or system to take further action.
1280cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                // The implementation of hard reset recovery action is up to OEM product.
1281cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                // Once RADIO_RESET property is consumed, it is expected to set back
1282cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                // to false by RIL.
1283cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                EventLog.writeEvent(EventLogTags.DATA_STALL_RECOVERY_RADIO_RESTART_WITH_PROP, -1);
1284cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                if (DBG) log("restarting radio with gsm.radioreset to true");
1285cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                SystemProperties.set(RADIO_RESET_PROPERTY, "true");
1286cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                // give 1 sec so property change can be notified.
1287cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                try {
1288cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                    Thread.sleep(1000);
1289cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                } catch (InterruptedException e) {}
1290cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                restartRadio();
1291cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                putRecoveryAction(RecoveryAction.GET_DATA_CALL_LIST);
1292cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                break;
1293cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            default:
1294cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                throw new RuntimeException("doRecovery: Invalid recoveryAction=" +
1295cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                    recoveryAction);
1296cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            }
1297cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
1298cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    }
1299cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
1300cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    private void updateDataStallInfo() {
1301cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        long sent, received;
1302cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
1303cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        TxRxSum preTxRxSum = new TxRxSum(mDataStallTxRxSum);
1304cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        mDataStallTxRxSum.updateTxRxSum();
1305cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
1306cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        if (VDBG) {
1307cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            log("updateDataStallInfo: mDataStallTxRxSum=" + mDataStallTxRxSum +
1308cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                    " preTxRxSum=" + preTxRxSum);
1309cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
1310cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
1311cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        sent = mDataStallTxRxSum.txPkts - preTxRxSum.txPkts;
1312cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        received = mDataStallTxRxSum.rxPkts - preTxRxSum.rxPkts;
1313cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
1314cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        if (RADIO_TESTS) {
1315cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            if (SystemProperties.getBoolean("radio.test.data.stall", false)) {
1316cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                log("updateDataStallInfo: radio.test.data.stall true received = 0;");
1317cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                received = 0;
1318cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            }
1319cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
1320cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        if ( sent > 0 && received > 0 ) {
1321cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            if (VDBG) log("updateDataStallInfo: IN/OUT");
1322cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            mSentSinceLastRecv = 0;
1323cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            putRecoveryAction(RecoveryAction.GET_DATA_CALL_LIST);
1324cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        } else if (sent > 0 && received == 0) {
1325cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            if (mPhone.getState() == PhoneConstants.State.IDLE) {
1326cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                mSentSinceLastRecv += sent;
1327cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            } else {
1328cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                mSentSinceLastRecv = 0;
1329cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            }
1330cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            if (DBG) {
1331cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                log("updateDataStallInfo: OUT sent=" + sent +
1332cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                        " mSentSinceLastRecv=" + mSentSinceLastRecv);
1333cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            }
1334cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        } else if (sent == 0 && received > 0) {
1335cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            if (VDBG) log("updateDataStallInfo: IN");
1336cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            mSentSinceLastRecv = 0;
1337cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            putRecoveryAction(RecoveryAction.GET_DATA_CALL_LIST);
1338cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        } else {
1339cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            if (VDBG) log("updateDataStallInfo: NONE");
1340cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
1341cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    }
1342cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
1343cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    protected void onDataStallAlarm(int tag) {
1344cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        if (mDataStallAlarmTag != tag) {
1345cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            if (DBG) {
1346cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                log("onDataStallAlarm: ignore, tag=" + tag + " expecting " + mDataStallAlarmTag);
1347cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            }
1348cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            return;
1349cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
1350cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        updateDataStallInfo();
1351cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
1352b840987a39e7149c1364739696977089cd53814dWink Saville        int hangWatchdogTrigger = Settings.Global.getInt(mResolver,
1353b840987a39e7149c1364739696977089cd53814dWink Saville                Settings.Global.PDP_WATCHDOG_TRIGGER_PACKET_COUNT,
1354cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                NUMBER_SENT_PACKETS_OF_HANG);
1355cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
1356cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        boolean suspectedStall = DATA_STALL_NOT_SUSPECTED;
1357cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        if (mSentSinceLastRecv >= hangWatchdogTrigger) {
1358cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            if (DBG) {
1359cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                log("onDataStallAlarm: tag=" + tag + " do recovery action=" + getRecoveryAction());
1360cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            }
1361cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            suspectedStall = DATA_STALL_SUSPECTED;
1362cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            sendMessage(obtainMessage(DctConstants.EVENT_DO_RECOVERY));
1363cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        } else {
1364cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            if (VDBG) {
1365cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                log("onDataStallAlarm: tag=" + tag + " Sent " + String.valueOf(mSentSinceLastRecv) +
1366cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                    " pkts since last received, < watchdogTrigger=" + hangWatchdogTrigger);
1367cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            }
1368cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
1369cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        startDataStallAlarm(suspectedStall);
1370cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    }
1371cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
1372cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    protected void startDataStallAlarm(boolean suspectedStall) {
1373cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        int nextAction = getRecoveryAction();
1374cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        int delayInMs;
1375cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
1376cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        // If screen is on or data stall is currently suspected, set the alarm
1377cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        // with an aggresive timeout.
1378cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        if (mIsScreenOn || suspectedStall || RecoveryAction.isAggressiveRecovery(nextAction)) {
1379b840987a39e7149c1364739696977089cd53814dWink Saville            delayInMs = Settings.Global.getInt(mResolver,
1380b840987a39e7149c1364739696977089cd53814dWink Saville                                       Settings.Global.DATA_STALL_ALARM_AGGRESSIVE_DELAY_IN_MS,
1381cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                                       DATA_STALL_ALARM_AGGRESSIVE_DELAY_IN_MS_DEFAULT);
1382cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        } else {
1383b840987a39e7149c1364739696977089cd53814dWink Saville            delayInMs = Settings.Global.getInt(mResolver,
1384b840987a39e7149c1364739696977089cd53814dWink Saville                                       Settings.Global.DATA_STALL_ALARM_NON_AGGRESSIVE_DELAY_IN_MS,
1385cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                                       DATA_STALL_ALARM_NON_AGGRESSIVE_DELAY_IN_MS_DEFAULT);
1386cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
1387cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
1388cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        mDataStallAlarmTag += 1;
1389cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        if (VDBG) {
1390cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            log("startDataStallAlarm: tag=" + mDataStallAlarmTag +
1391cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                    " delay=" + (delayInMs / 1000) + "s");
1392cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
1393cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        AlarmManager am =
1394cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            (AlarmManager) mPhone.getContext().getSystemService(Context.ALARM_SERVICE);
1395cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
1396cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        Intent intent = new Intent(getActionIntentDataStallAlarm());
1397cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        intent.putExtra(DATA_STALL_ALARM_TAG_EXTRA, mDataStallAlarmTag);
1398cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        mDataStallAlarmIntent = PendingIntent.getBroadcast(mPhone.getContext(), 0, intent,
1399cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                PendingIntent.FLAG_UPDATE_CURRENT);
1400cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        am.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
1401cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                SystemClock.elapsedRealtime() + delayInMs, mDataStallAlarmIntent);
1402cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    }
1403cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
1404cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    protected void stopDataStallAlarm() {
1405cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        AlarmManager am =
1406cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            (AlarmManager) mPhone.getContext().getSystemService(Context.ALARM_SERVICE);
1407cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
1408cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        if (VDBG) {
1409cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            log("stopDataStallAlarm: current tag=" + mDataStallAlarmTag +
1410cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla                    " mDataStallAlarmIntent=" + mDataStallAlarmIntent);
1411cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
1412cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        mDataStallAlarmTag += 1;
1413cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        if (mDataStallAlarmIntent != null) {
1414cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            am.cancel(mDataStallAlarmIntent);
1415cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            mDataStallAlarmIntent = null;
1416cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
1417cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    }
1418cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
1419cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    protected void restartDataStallAlarm() {
1420cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        if (isConnected() == false) return;
1421cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        // To be called on screen status change.
1422cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        // Do not cancel the alarm if it is set with aggressive timeout.
1423cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        int nextAction = getRecoveryAction();
1424cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
1425cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        if (RecoveryAction.isAggressiveRecovery(nextAction)) {
1426cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            if (DBG) log("data stall recovery action is pending. not resetting the alarm.");
1427cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla            return;
1428cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        }
1429cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        stopDataStallAlarm();
1430cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
1431cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    }
1432cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla
1433c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1434c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        pw.println("DataConnectionTracker:");
1435cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        pw.println(" RADIO_TESTS=" + RADIO_TESTS);
1436c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        pw.println(" mInternalDataEnabled=" + mInternalDataEnabled);
1437c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        pw.println(" mUserDataEnabled=" + mUserDataEnabled);
1438c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        pw.println(" sPolicyDataEnabed=" + sPolicyDataEnabled);
1439c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        pw.println(" dataEnabled:");
1440c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        for(int i=0; i < dataEnabled.length; i++) {
1441c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            pw.printf("  dataEnabled[%d]=%b\n", i, dataEnabled[i]);
1442c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1443c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        pw.flush();
1444c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        pw.println(" enabledCount=" + enabledCount);
1445c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        pw.println(" mRequestedApnType=" + mRequestedApnType);
1446c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        pw.println(" mPhone=" + mPhone.getPhoneName());
1447c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        pw.println(" mActivity=" + mActivity);
1448c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        pw.println(" mState=" + mState);
1449c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        pw.println(" mTxPkts=" + mTxPkts);
1450c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        pw.println(" mRxPkts=" + mRxPkts);
1451c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        pw.println(" mNetStatPollPeriod=" + mNetStatPollPeriod);
1452c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        pw.println(" mNetStatPollEnabled=" + mNetStatPollEnabled);
1453c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        pw.println(" mDataStallTxRxSum=" + mDataStallTxRxSum);
1454c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        pw.println(" mDataStallAlarmTag=" + mDataStallAlarmTag);
1455c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        pw.println(" mSentSinceLastRecv=" + mSentSinceLastRecv);
1456c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        pw.println(" mNoRecvPollCount=" + mNoRecvPollCount);
1457cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla        pw.println(" mResolver=" + mResolver);
1458c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        pw.println(" mIsWifiConnected=" + mIsWifiConnected);
1459c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        pw.println(" mReconnectIntent=" + mReconnectIntent);
1460c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        pw.println(" mCidActive=" + mCidActive);
1461c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        pw.println(" mAutoAttachOnCreation=" + mAutoAttachOnCreation);
1462c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        pw.println(" mIsScreenOn=" + mIsScreenOn);
1463c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        pw.println(" mUniqueIdGenerator=" + mUniqueIdGenerator);
1464c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        pw.flush();
1465c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        pw.println(" ***************************************");
1466c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        Set<Entry<Integer, DataConnection> > mDcSet = mDataConnections.entrySet();
1467c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        pw.println(" mDataConnections: count=" + mDcSet.size());
1468c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        for (Entry<Integer, DataConnection> entry : mDcSet) {
1469c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            pw.printf(" *** mDataConnection[%d] \n", entry.getKey());
1470c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            entry.getValue().dump(fd, pw, args);
1471c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1472c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        pw.println(" ***************************************");
1473c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        pw.flush();
1474c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        Set<Entry<String, Integer>> mApnToDcIdSet = mApnToDataConnectionId.entrySet();
1475c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        pw.println(" mApnToDataConnectonId size=" + mApnToDcIdSet.size());
1476c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        for (Entry<String, Integer> entry : mApnToDcIdSet) {
1477c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            pw.printf(" mApnToDataConnectonId[%s]=%d\n", entry.getKey(), entry.getValue());
1478c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1479c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        pw.println(" ***************************************");
1480c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        pw.flush();
1481c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (mApnContexts != null) {
1482c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            Set<Entry<String, ApnContext>> mApnContextsSet = mApnContexts.entrySet();
1483c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            pw.println(" mApnContexts size=" + mApnContextsSet.size());
1484c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            for (Entry<String, ApnContext> entry : mApnContextsSet) {
1485c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                entry.getValue().dump(fd, pw, args);
1486c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
1487c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            pw.println(" ***************************************");
1488c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } else {
1489c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            pw.println(" mApnContexts=null");
1490c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1491c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        pw.flush();
1492c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        pw.println(" mActiveApn=" + mActiveApn);
1493c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (mAllApns != null) {
1494c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            pw.println(" mAllApns size=" + mAllApns.size());
1495c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            for (int i=0; i < mAllApns.size(); i++) {
1496c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                pw.printf(" mAllApns[%d]: %s\n", i, mAllApns.get(i));
1497c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
1498c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            pw.flush();
1499c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } else {
1500c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            pw.println(" mAllApns=null");
1501c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1502c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        pw.println(" mPreferredApn=" + mPreferredApn);
1503c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        pw.println(" mIsPsRestricted=" + mIsPsRestricted);
1504c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        pw.println(" mIsDisposed=" + mIsDisposed);
1505c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        pw.println(" mIntentReceiver=" + mIntentReceiver);
1506c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        pw.println(" mDataRoamingSettingObserver=" + mDataRoamingSettingObserver);
1507c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        pw.flush();
1508c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1509c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville}
1510