Add external dependency API.
An APN will not be connected to if some external dependency is not met.
bug:3486704
Change-Id: I7d94df343b260013efd11faa978deb13f07f1389
diff --git a/core/java/android/bluetooth/BluetoothTetheringDataTracker.java b/core/java/android/bluetooth/BluetoothTetheringDataTracker.java
index c08f14f..a7b0037 100644
--- a/core/java/android/bluetooth/BluetoothTetheringDataTracker.java
+++ b/core/java/android/bluetooth/BluetoothTetheringDataTracker.java
@@ -300,4 +300,8 @@
msg = mCsHandler.obtainMessage(EVENT_STATE_CHANGED, mNetworkInfo);
msg.sendToTarget();
}
+
+ public void setDependencyMet(boolean met) {
+ // not supported on this network
+ }
}
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index 26f375d..b541ec3 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -690,4 +690,16 @@
return null;
}
}
+
+ /**
+ * @param networkType The network who's dependence has changed
+ * @param met Boolean - true if network use is ok, false if not
+ * {@hide}
+ */
+ public void setDataDependency(int networkType, boolean met) {
+ try {
+ mService.setDataDependency(networkType, met);
+ } catch (RemoteException e) {
+ }
+ }
}
diff --git a/core/java/android/net/DummyDataStateTracker.java b/core/java/android/net/DummyDataStateTracker.java
index d0c77cf..e39725a 100644
--- a/core/java/android/net/DummyDataStateTracker.java
+++ b/core/java/android/net/DummyDataStateTracker.java
@@ -191,6 +191,10 @@
return new LinkCapabilities(mLinkCapabilities);
}
+ public void setDependencyMet(boolean met) {
+ // not supported on this network
+ }
+
static private void log(String s) {
Slog.d(TAG, s);
}
diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl
index 70ab4f1..8be492c 100644
--- a/core/java/android/net/IConnectivityManager.aidl
+++ b/core/java/android/net/IConnectivityManager.aidl
@@ -92,4 +92,6 @@
void setGlobalProxy(in ProxyProperties p);
ProxyProperties getProxy();
+
+ void setDataDependency(int networkType, boolean met);
}
diff --git a/core/java/android/net/MobileDataStateTracker.java b/core/java/android/net/MobileDataStateTracker.java
index 5b4da66..bb6ee0f 100644
--- a/core/java/android/net/MobileDataStateTracker.java
+++ b/core/java/android/net/MobileDataStateTracker.java
@@ -20,6 +20,7 @@
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.os.Bundle;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Messenger;
@@ -493,6 +494,25 @@
}
}
+ /**
+ * carrier dependency is met/unmet
+ * @param met
+ */
+ public void setDependencyMet(boolean met) {
+ Bundle bundle = Bundle.forPair(DataConnectionTracker.APN_TYPE_KEY, mApnType);
+ try {
+ log("setDependencyMet: E met=" + met);
+ Message msg = Message.obtain();
+ msg.what = DataConnectionTracker.CMD_SET_DEPENDENCY_MET;
+ msg.arg1 = (met ? DataConnectionTracker.ENABLED : DataConnectionTracker.DISABLED);
+ msg.setData(bundle);
+ mDataConnectionTrackerAc.sendMessage(msg);
+ log("setDependencyMet: X met=" + met);
+ } catch (NullPointerException e) {
+ log("setDependencyMet: X mAc was null" + e);
+ }
+ }
+
@Override
public String toString() {
StringBuffer sb = new StringBuffer("Mobile data state: ");
diff --git a/core/java/android/net/NetworkConfig.java b/core/java/android/net/NetworkConfig.java
new file mode 100644
index 0000000..4adb76b
--- /dev/null
+++ b/core/java/android/net/NetworkConfig.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net;
+
+import android.util.Log;
+
+/**
+ * Describes the buildtime configuration of a network.
+ * Holds settings read from resources.
+ * @hide
+ */
+public class NetworkConfig {
+ /**
+ * Human readable string
+ */
+ public String name;
+
+ /**
+ * Type from ConnectivityManager
+ */
+ public int type;
+
+ /**
+ * the radio number from radio attributes config
+ */
+ public int radio;
+
+ /**
+ * higher number == higher priority when turning off connections
+ */
+ public int priority;
+
+ /**
+ * indicates the boot time dependencyMet setting
+ */
+ public boolean dependencyMet;
+
+ /**
+ * input string from config.xml resource. Uses the form:
+ * [Connection name],[ConnectivityManager connection type],
+ * [associated radio-type],[priority],[dependencyMet]
+ */
+ public NetworkConfig(String init) {
+ String fragments[] = init.split(",");
+ name = fragments[0].trim().toLowerCase();
+ type = Integer.parseInt(fragments[1]);
+ radio = Integer.parseInt(fragments[2]);
+ priority = Integer.parseInt(fragments[3]);
+ if (fragments.length > 4) {
+ dependencyMet = Boolean.parseBoolean(fragments[4]);
+ } else {
+ dependencyMet = true;
+ }
+ }
+
+ /**
+ * Indicates if this network is supposed to be default-routable
+ */
+ public boolean isDefault() {
+ return (type == radio);
+ }
+}
diff --git a/core/java/android/net/NetworkStateTracker.java b/core/java/android/net/NetworkStateTracker.java
index eb97d77..f53063d 100644
--- a/core/java/android/net/NetworkStateTracker.java
+++ b/core/java/android/net/NetworkStateTracker.java
@@ -176,4 +176,9 @@
* Indicate tear down requested from connectivity
*/
public void setTeardownRequested(boolean isRequested);
+
+ /**
+ * An external dependency has been met/unmet
+ */
+ public void setDependencyMet(boolean met);
}
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 2037191..6695296 100755
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -132,6 +132,7 @@
based on the hardware -->
<!-- An Array of "[Connection name],[ConnectivityManager connection type],
[associated radio-type],[priority] -->
+ <!-- an optional 5th element can be added indicating boot-time dependency-met value. Defaults to true -->
<string-array translatable="false" name="networkAttributes">
<item>"wifi,1,1,1"</item>
<item>"mobile,0,0,0"</item>
diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java
index f170cb7..d3349cc 100644
--- a/services/java/com/android/server/ConnectivityService.java
+++ b/services/java/com/android/server/ConnectivityService.java
@@ -27,6 +27,7 @@
import android.net.IConnectivityManager;
import android.net.LinkProperties;
import android.net.MobileDataStateTracker;
+import android.net.NetworkConfig;
import android.net.NetworkInfo;
import android.net.NetworkStateTracker;
import android.net.NetworkUtils;
@@ -188,6 +189,14 @@
private static final int EVENT_APPLY_GLOBAL_HTTP_PROXY =
MAX_NETWORK_STATE_TRACKER_EVENT + 9;
+ /**
+ * used internally to set external dependency met/unmet
+ * arg1 = ENABLED (met) or DISABLED (unmet)
+ * arg2 = NetworkType
+ */
+ private static final int EVENT_SET_DEPENDENCY_MET =
+ MAX_NETWORK_STATE_TRACKER_EVENT + 10;
+
private Handler mHandler;
// list of DeathRecipients used to make sure features are turned off when
@@ -216,28 +225,7 @@
private SettingsObserver mSettingsObserver;
- private static class NetworkAttributes {
- /**
- * Class for holding settings read from resources.
- */
- public String mName;
- public int mType;
- public int mRadio;
- public int mPriority;
- public NetworkInfo.State mLastState;
- public NetworkAttributes(String init) {
- String fragments[] = init.split(",");
- mName = fragments[0].toLowerCase();
- mType = Integer.parseInt(fragments[1]);
- mRadio = Integer.parseInt(fragments[2]);
- mPriority = Integer.parseInt(fragments[3]);
- mLastState = NetworkInfo.State.UNKNOWN;
- }
- public boolean isDefault() {
- return (mType == mRadio);
- }
- }
- NetworkAttributes[] mNetAttributes;
+ NetworkConfig[] mNetConfigs;
int mNetworksDefined;
private static class RadioAttributes {
@@ -304,7 +292,7 @@
mNetworkPreference = getPersistedNetworkPreference();
mRadioAttributes = new RadioAttributes[ConnectivityManager.MAX_RADIO_TYPE+1];
- mNetAttributes = new NetworkAttributes[ConnectivityManager.MAX_NETWORK_TYPE+1];
+ mNetConfigs = new NetworkConfig[ConnectivityManager.MAX_NETWORK_TYPE+1];
// Load device network attributes from resources
String[] raStrings = context.getResources().getStringArray(
@@ -327,13 +315,13 @@
com.android.internal.R.array.networkAttributes);
for (String naString : naStrings) {
try {
- NetworkAttributes n = new NetworkAttributes(naString);
+ NetworkConfig n = new NetworkConfig(naString);
if (n.mType > ConnectivityManager.MAX_NETWORK_TYPE) {
loge("Error in networkAttributes - ignoring attempt to define type " +
n.mType);
continue;
}
- if (mNetAttributes[n.mType] != null) {
+ if (mNetConfigs[n.mType] != null) {
loge("Error in networkAttributes - ignoring attempt to redefine type " +
n.mType);
continue;
@@ -343,7 +331,7 @@
"radio " + n.mRadio + " in network type " + n.mType);
continue;
}
- mNetAttributes[n.mType] = n;
+ mNetConfigs[n.mType] = n;
mNetworksDefined++;
} catch(Exception e) {
// ignore it - leave the entry null
@@ -357,7 +345,7 @@
int currentLowest = 0;
int nextLowest = 0;
while (insertionPoint > -1) {
- for (NetworkAttributes na : mNetAttributes) {
+ for (NetworkConfig na : mNetConfigs) {
if (na == null) continue;
if (na.mPriority < currentLowest) continue;
if (na.mPriority > currentLowest) {
@@ -392,7 +380,7 @@
* to change very often.
*/
for (int netType : mPriorityList) {
- switch (mNetAttributes[netType].mRadio) {
+ switch (mNetConfigs[netType].mRadio) {
case ConnectivityManager.TYPE_WIFI:
if (DBG) log("Starting Wifi Service.");
WifiStateTracker wst = new WifiStateTracker();
@@ -408,12 +396,12 @@
break;
case ConnectivityManager.TYPE_MOBILE:
mNetTrackers[netType] = new MobileDataStateTracker(netType,
- mNetAttributes[netType].mName);
+ mNetConfigs[netType].mName);
mNetTrackers[netType].startMonitoring(context, mHandler);
break;
case ConnectivityManager.TYPE_DUMMY:
mNetTrackers[netType] = new DummyDataStateTracker(netType,
- mNetAttributes[netType].mName);
+ mNetConfigs[netType].mName);
mNetTrackers[netType].startMonitoring(context, mHandler);
break;
case ConnectivityManager.TYPE_BLUETOOTH:
@@ -422,7 +410,7 @@
break;
default:
loge("Trying to create a DataStateTracker for an unknown radio type " +
- mNetAttributes[netType].mRadio);
+ mNetConfigs[netType].mRadio);
continue;
}
}
@@ -469,8 +457,8 @@
private void handleSetNetworkPreference(int preference) {
if (ConnectivityManager.isNetworkTypeValid(preference) &&
- mNetAttributes[preference] != null &&
- mNetAttributes[preference].isDefault()) {
+ mNetConfigs[preference] != null &&
+ mNetConfigs[preference].isDefault()) {
if (mNetworkPreference != preference) {
final ContentResolver cr = mContext.getContentResolver();
Settings.Secure.putInt(cr, Settings.Secure.NETWORK_PREFERENCE, preference);
@@ -539,7 +527,7 @@
public NetworkInfo getActiveNetworkInfo() {
enforceAccessPermission();
for (int type=0; type <= ConnectivityManager.MAX_NETWORK_TYPE; type++) {
- if (mNetAttributes[type] == null || !mNetAttributes[type].isDefault()) {
+ if (mNetConfigs[type] == null || !mNetConfigs[type].isDefault()) {
continue;
}
NetworkStateTracker t = mNetTrackers[type];
@@ -585,7 +573,7 @@
public LinkProperties getActiveLinkProperties() {
enforceAccessPermission();
for (int type=0; type <= ConnectivityManager.MAX_NETWORK_TYPE; type++) {
- if (mNetAttributes[type] == null || !mNetAttributes[type].isDefault()) {
+ if (mNetConfigs[type] == null || !mNetConfigs[type].isDefault()) {
continue;
}
NetworkStateTracker t = mNetTrackers[type];
@@ -687,7 +675,7 @@
}
enforceChangePermission();
if (!ConnectivityManager.isNetworkTypeValid(networkType) ||
- mNetAttributes[networkType] == null) {
+ mNetConfigs[networkType] == null) {
return Phone.APN_REQUEST_FAILED;
}
@@ -999,6 +987,24 @@
return retVal;
}
+ public void setDataDependency(int networkType, boolean met) {
+ enforceChangePermission();
+ if (DBG) {
+ log("setDataDependency(" + networkType + ", " + met + ")");
+ }
+ mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_DEPENDENCY_MET,
+ (met ? ENABLED : DISABLED), networkType));
+ }
+
+ private void handleSetDependencyMet(int networkType, boolean met) {
+ if (mNetTrackers[networkType] != null) {
+ if (DBG) {
+ log("handleSetDependencyMet(" + networkType + ", " + met + ")");
+ }
+ mNetTrackers[networkType].setDependencyMet(met);
+ }
+ }
+
/**
* @see ConnectivityManager#setMobileDataEnabled(boolean)
*/
@@ -1007,7 +1013,7 @@
if (DBG) log("setMobileDataEnabled(" + enabled + ")");
mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_MOBILE_DATA,
- (enabled ? ENABLED : DISABLED), 0));
+ (enabled ? ENABLED : DISABLED), 0));
}
private void handleSetMobileData(boolean enabled) {
@@ -1068,7 +1074,7 @@
* getting the disconnect for a network that we explicitly disabled
* in accordance with network preference policies.
*/
- if (!mNetAttributes[prevNetType].isDefault()) {
+ if (!mNetConfigs[prevNetType].isDefault()) {
List pids = mNetRequestersPids[prevNetType];
for (int i = 0; i<pids.size(); i++) {
Integer pid = (Integer)pids.get(i);
@@ -1093,7 +1099,7 @@
info.getExtraInfo());
}
- if (mNetAttributes[prevNetType].isDefault()) {
+ if (mNetConfigs[prevNetType].isDefault()) {
tryFailover(prevNetType);
if (mActiveDefaultNetwork != -1) {
NetworkInfo switchTo = mNetTrackers[mActiveDefaultNetwork].getNetworkInfo();
@@ -1123,7 +1129,7 @@
* Try to reconnect on all available and let them hash it out when
* more than one connects.
*/
- if (mNetAttributes[prevNetType].isDefault()) {
+ if (mNetConfigs[prevNetType].isDefault()) {
if (mActiveDefaultNetwork == prevNetType) {
mActiveDefaultNetwork = -1;
}
@@ -1133,12 +1139,12 @@
// TODO - don't filter by priority now - nice optimization but risky
// int currentPriority = -1;
// if (mActiveDefaultNetwork != -1) {
-// currentPriority = mNetAttributes[mActiveDefaultNetwork].mPriority;
+// currentPriority = mNetConfigs[mActiveDefaultNetwork].mPriority;
// }
for (int checkType=0; checkType <= ConnectivityManager.MAX_NETWORK_TYPE; checkType++) {
if (checkType == prevNetType) continue;
- if (mNetAttributes[checkType] == null) continue;
- if (!mNetAttributes[checkType].isDefault()) continue;
+ if (mNetConfigs[checkType] == null) continue;
+ if (!mNetConfigs[checkType].isDefault()) continue;
// Enabling the isAvailable() optimization caused mobile to not get
// selected if it was in the middle of error handling. Specifically
@@ -1150,7 +1156,7 @@
// complete before it is really complete.
// if (!mNetTrackers[checkType].isAvailable()) continue;
-// if (currentPriority >= mNetAttributes[checkType].mPriority) continue;
+// if (currentPriority >= mNetConfigs[checkType].mPriority) continue;
NetworkStateTracker checkTracker = mNetTrackers[checkType];
NetworkInfo checkInfo = checkTracker.getNetworkInfo();
@@ -1223,7 +1229,7 @@
info.setFailover(false);
}
- if (mNetAttributes[info.getType()].isDefault()) {
+ if (mNetConfigs[info.getType()].isDefault()) {
tryFailover(info.getType());
if (mActiveDefaultNetwork != -1) {
NetworkInfo switchTo = mNetTrackers[mActiveDefaultNetwork].getNetworkInfo();
@@ -1276,11 +1282,11 @@
// if this is a default net and other default is running
// kill the one not preferred
- if (mNetAttributes[type].isDefault()) {
+ if (mNetConfigs[type].isDefault()) {
if (mActiveDefaultNetwork != -1 && mActiveDefaultNetwork != type) {
if ((type != mNetworkPreference &&
- mNetAttributes[mActiveDefaultNetwork].mPriority >
- mNetAttributes[type].mPriority) ||
+ mNetConfigs[mActiveDefaultNetwork].mPriority >
+ mNetConfigs[type].mPriority) ||
mNetworkPreference == mActiveDefaultNetwork) {
// don't accept this one
if (DBG) {
@@ -1344,14 +1350,14 @@
handleDnsConfigurationChange(netType);
if (mNetTrackers[netType].getNetworkInfo().isConnected()) {
- if (mNetAttributes[netType].isDefault()) {
+ if (mNetConfigs[netType].isDefault()) {
handleApplyDefaultProxy(netType);
addDefaultRoute(mNetTrackers[netType]);
} else {
addPrivateDnsRoutes(mNetTrackers[netType]);
}
} else {
- if (mNetAttributes[netType].isDefault()) {
+ if (mNetConfigs[netType].isDefault()) {
removeDefaultRoute(mNetTrackers[netType]);
} else {
removePrivateDnsRoutes(mNetTrackers[netType]);
@@ -1512,7 +1518,7 @@
{
if (DBG) log("reassessPidDns for pid " + myPid);
for(int i : mPriorityList) {
- if (mNetAttributes[i].isDefault()) {
+ if (mNetConfigs[i].isDefault()) {
continue;
}
NetworkStateTracker nt = mNetTrackers[i];
@@ -1594,7 +1600,7 @@
if (p == null) return;
Collection<InetAddress> dnses = p.getDnses();
boolean changed = false;
- if (mNetAttributes[netType].isDefault()) {
+ if (mNetConfigs[netType].isDefault()) {
int j = 1;
if (dnses.size() == 0 && mDefaultDns != null) {
String dnsString = mDefaultDns.getHostAddress();
@@ -1725,23 +1731,6 @@
info = (NetworkInfo) msg.obj;
int type = info.getType();
NetworkInfo.State state = info.getState();
- // only do this optimization for wifi. It going into scan mode for location
- // services generates alot of noise. Meanwhile the mms apn won't send out
- // subsequent notifications when on default cellular because it never
- // disconnects.. so only do this to wifi notifications. Fixed better when the
- // APN notifications are standardized.
- if (mNetAttributes[type].mLastState == state &&
- mNetAttributes[type].mRadio == ConnectivityManager.TYPE_WIFI) {
- if (DBG) {
- // TODO - remove this after we validate the dropping doesn't break
- // anything
- log("Dropping ConnectivityChange for " +
- info.getTypeName() + ": " +
- state + "/" + info.getDetailedState());
- }
- return;
- }
- mNetAttributes[type].mLastState = state;
if (DBG) log("ConnectivityChange for " +
info.getTypeName() + ": " +
@@ -1780,8 +1769,7 @@
break;
case NetworkStateTracker.EVENT_CONFIGURATION_CHANGED:
info = (NetworkInfo) msg.obj;
- type = info.getType();
- handleConnectivityChange(type);
+ handleConnectivityChange(info.getType());
break;
case EVENT_CLEAR_NET_TRANSITION_WAKELOCK:
String causedBy = null;
@@ -1835,6 +1823,13 @@
case EVENT_APPLY_GLOBAL_HTTP_PROXY:
{
handleDeprecatedGlobalHttpProxy();
+ break;
+ }
+ case EVENT_SET_DEPENDENCY_MET:
+ {
+ boolean met = (msg.arg1 == ENABLED);
+ handleSetDependencyMet(msg.arg2, met);
+ break;
}
}
}
diff --git a/telephony/java/com/android/internal/telephony/ApnContext.java b/telephony/java/com/android/internal/telephony/ApnContext.java
index a86ea7e..2e7c3a3 100644
--- a/telephony/java/com/android/internal/telephony/ApnContext.java
+++ b/telephony/java/com/android/internal/telephony/ApnContext.java
@@ -20,7 +20,6 @@
import android.util.Log;
import java.util.ArrayList;
-import com.android.internal.telephony.gsm.GsmDataConnection;
/**
* Maintain the Apn context
@@ -30,9 +29,13 @@
public static final int PENDING_ACTION_NONE = 1;
public static final int PENDING_ACTION_RECONNECT = 2;
public static final int PENDING_ACTION_APN_DISABLE = 3;
+
+ public static final int DATA_ENABLED = 1;
+ public static final int DATA_DISABLED = 2;
+
public final String LOG_TAG;
- int pendingAction;
+ int mPendingAction;
protected static final boolean DBG = true;
@@ -47,37 +50,49 @@
ApnSetting mApnSetting;
- GsmDataConnection mDataConnection;
+ DataConnection mDataConnection;
String mReason;
PendingIntent mReconnectIntent;
+ /**
+ * user/app requested connection on this APN
+ */
+ boolean mDataEnabled;
+
+ /**
+ * carrier requirements met
+ */
+ boolean mDependencyMet;
+
public ApnContext(String apnType, String logTag) {
mApnType = apnType;
mState = DataConnectionTracker.State.IDLE;
setReason(Phone.REASON_DATA_ENABLED);
- pendingAction = PENDING_ACTION_NONE;
+ mPendingAction = PENDING_ACTION_NONE;
+ mDataEnabled = false;
+ mDependencyMet = true;
LOG_TAG = logTag;
}
public int getPendingAction() {
- return pendingAction;
+ return mPendingAction;
}
public void setPendingAction(int pa) {
- pendingAction = pa;
+ mPendingAction = pa;
}
public String getApnType() {
return mApnType;
}
- public GsmDataConnection getDataConnection() {
+ public DataConnection getDataConnection() {
return mDataConnection;
}
- public void setDataConnection(GsmDataConnection dataConnection) {
+ public void setDataConnection(DataConnection dataConnection) {
mDataConnection = dataConnection;
}
@@ -160,6 +175,34 @@
return mReconnectIntent;
}
+ public boolean isReady() {
+ return mDataEnabled && mDependencyMet;
+ }
+
+ public void setEnabled(boolean enabled) {
+ if (DBG) {
+ log("set enabled as " + enabled + ", for type " +
+ mApnType + ", current state is " + mDataEnabled);
+ }
+ mDataEnabled = enabled;
+ }
+
+ public boolean isEnabled() {
+ return mDataEnabled;
+ }
+
+ public void setDependencyMet(boolean met) {
+ if (DBG) {
+ log("set mDependencyMet as " + met + ", for type " + mApnType +
+ ", current state is " + mDependencyMet);
+ }
+ mDependencyMet = met;
+ }
+
+ public boolean getDependencyMet() {
+ return mDependencyMet;
+ }
+
protected void log(String s) {
Log.d(LOG_TAG, "[ApnContext] " + s);
}
diff --git a/telephony/java/com/android/internal/telephony/DataConnection.java b/telephony/java/com/android/internal/telephony/DataConnection.java
index e21e951..7214cf6 100644
--- a/telephony/java/com/android/internal/telephony/DataConnection.java
+++ b/telephony/java/com/android/internal/telephony/DataConnection.java
@@ -1097,4 +1097,8 @@
public ApnSetting getApn() {
return mApn;
}
+
+ public int getCid() {
+ return cid;
+ }
}
diff --git a/telephony/java/com/android/internal/telephony/DataConnectionTracker.java b/telephony/java/com/android/internal/telephony/DataConnectionTracker.java
index fba73fb5..d5b65e1 100644
--- a/telephony/java/com/android/internal/telephony/DataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/DataConnectionTracker.java
@@ -28,6 +28,7 @@
import android.net.NetworkInfo;
import android.net.wifi.WifiManager;
import android.os.AsyncResult;
+import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.Messenger;
@@ -122,6 +123,7 @@
protected static final int EVENT_RESET_DONE = 38;
public static final int CMD_SET_DATA_ENABLE = 39;
public static final int EVENT_CLEAN_UP_ALL_CONNECTIONS = 40;
+ public static final int CMD_SET_DEPENDENCY_MET = 41;
/***** Constants *****/
@@ -139,6 +141,8 @@
public static final int DISABLED = 0;
public static final int ENABLED = 1;
+ public static final String APN_TYPE_KEY = "apnType";
+
// responds to the setInternalDataEnabled call - used internally to turn off data
// for example during emergency calls
protected boolean mInternalDataEnabled = true;
@@ -541,6 +545,19 @@
break;
}
+ case CMD_SET_DEPENDENCY_MET: {
+ log("CMD_SET_DEPENDENCY_MET msg=" + msg);
+ boolean met = (msg.arg1 == ENABLED) ? true : false;
+ Bundle bundle = msg.getData();
+ if (bundle != null) {
+ String apnType = (String)bundle.get(APN_TYPE_KEY);
+ if (apnType != null) {
+ onSetDependencyMet(apnType, met);
+ }
+ }
+ break;
+ }
+
default:
Log.e("DATA", "Unidentified event = " + msg.what);
break;
@@ -810,7 +827,7 @@
}
}
- private void setEnabled(int id, boolean enable) {
+ protected void setEnabled(int id, boolean enable) {
if (DBG) {
log("setEnabled(" + id + ", " + enable + ") with old state = " + dataEnabled[id]
+ " and enabledCount = " + enabledCount);
@@ -821,7 +838,7 @@
sendMessage(msg);
}
- protected synchronized void onEnableApn(int apnId, int enabled) {
+ protected void onEnableApn(int apnId, int enabled) {
if (DBG) {
log("EVENT_APN_ENABLE_REQUEST apnId=" + apnId + ", apnType=" + apnIdToType(apnId) +
", enabled=" + enabled + ", dataEnabled = " + dataEnabled[apnId] +
@@ -829,9 +846,11 @@
isApnTypeActive(apnIdToType(apnId)));
}
if (enabled == ENABLED) {
- if (!dataEnabled[apnId]) {
- dataEnabled[apnId] = true;
- enabledCount++;
+ synchronized (this) {
+ if (!dataEnabled[apnId]) {
+ dataEnabled[apnId] = true;
+ enabledCount++;
+ }
}
String type = apnIdToType(apnId);
if (!isApnTypeActive(type)) {
@@ -842,12 +861,16 @@
}
} else {
// disable
- if (dataEnabled[apnId]) {
- dataEnabled[apnId] = false;
- enabledCount--;
- if (enabledCount == 0) {
- onCleanUpConnection(true, apnId, Phone.REASON_DATA_DISABLED);
+ boolean didDisable = false;
+ synchronized (this) {
+ if (dataEnabled[apnId]) {
+ dataEnabled[apnId] = false;
+ enabledCount--;
+ didDisable = true;
}
+ }
+ if (didDisable && enabledCount == 0) {
+ onCleanUpConnection(true, apnId, Phone.REASON_DATA_DISABLED);
// send the disconnect msg manually, since the normal route wont send
// it (it's not enabled)
@@ -961,6 +984,10 @@
}
}
+ protected void onSetDependencyMet(String apnType, boolean met) {
+ }
+
+
protected void resetAllRetryCounts() {
for (DataConnection dc : mDataConnections.values()) {
dc.resetRetryCount();
diff --git a/telephony/java/com/android/internal/telephony/Phone.java b/telephony/java/com/android/internal/telephony/Phone.java
index 7450047..9f16d31 100644
--- a/telephony/java/com/android/internal/telephony/Phone.java
+++ b/telephony/java/com/android/internal/telephony/Phone.java
@@ -175,6 +175,8 @@
static final String REASON_PS_RESTRICT_DISABLED = "psRestrictDisabled";
static final String REASON_SIM_LOADED = "simLoaded";
static final String REASON_NW_TYPE_CHANGED = "nwTypeChanged";
+ static final String REASON_DATA_DEPENDENCY_MET = "dependencyMet";
+ static final String REASON_DATA_DEPENDENCY_UNMET = "dependencyUnmet";
// Used for band mode selection methods
static final int BM_UNSPECIFIED = 0; // selected by baseband automatically
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnection.java b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnection.java
index b0b2ac5..2589de4 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnection.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnection.java
@@ -117,11 +117,6 @@
return mProfileId;
}
- public int getCid() {
- // 'cid' has been defined in parent class
- return cid;
- }
-
public void setActiveApnType(String apnType) {
mActiveApnType = apnType;
}
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
index 891a237..b5dadf6 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
@@ -25,11 +25,13 @@
import android.content.SharedPreferences;
import android.database.ContentObserver;
import android.database.Cursor;
+import android.net.ConnectivityManager;
import android.net.ProxyProperties;
import android.net.TrafficStats;
import android.net.Uri;
import android.net.LinkCapabilities;
import android.net.LinkProperties;
+import android.net.NetworkConfig;
import android.os.AsyncResult;
import android.os.Message;
import android.os.SystemClock;
@@ -164,9 +166,8 @@
p.getContext().getContentResolver().registerContentObserver(
Telephony.Carriers.CONTENT_URI, true, mApnObserver);
- /** Create the default connection */
mApnContexts = new ConcurrentHashMap<String, ApnContext>();
- initApncontextsAndDataConnection();
+ initApnContextsAndDataConnection();
broadcastMessenger();
}
@@ -206,6 +207,7 @@
* because the phone is out of coverage or some like reason.</li>
* </ul>
* @return {@code true} if data connectivity is possible, {@code false} otherwise.
+ * TODO - do per-apn notifications of availability using dependencyMet values.
*/
@Override
protected boolean isDataPossible() {
@@ -227,14 +229,57 @@
return INTENT_RECONNECT_ALARM;
}
- protected void initApncontextsAndDataConnection() {
+ private ApnContext addApnContext(String type) {
+ ApnContext apnContext = new ApnContext(type, LOG_TAG);
+ apnContext.setDependencyMet(false);
+ mApnContexts.put(type, apnContext);
+ return apnContext;
+ }
+
+ protected void initApnContextsAndDataConnection() {
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mPhone.getContext());
boolean defaultEnabled = !sp.getBoolean(PhoneBase.DATA_DISABLED_ON_BOOT_KEY, false);
- // create default type context only if enabled
- if (defaultEnabled) {
- ApnContext apnContext = new ApnContext(Phone.APN_TYPE_DEFAULT, LOG_TAG);
- mApnContexts.put(apnContext.getApnType(), apnContext);
- createDataConnection(Phone.APN_TYPE_DEFAULT);
+ // Load device network attributes from resources
+ String[] networkConfigStrings = mPhone.getContext().getResources().getStringArray(
+ com.android.internal.R.array.networkAttributes);
+ for (String networkConfigString : networkConfigStrings) {
+ NetworkConfig networkConfig = new NetworkConfig(networkConfigString);
+ ApnContext apnContext = null;
+
+ switch (networkConfig.type) {
+ case ConnectivityManager.TYPE_MOBILE:
+ apnContext = addApnContext(Phone.APN_TYPE_DEFAULT);
+ apnContext.setEnabled(defaultEnabled);
+ break;
+ case ConnectivityManager.TYPE_MOBILE_MMS:
+ apnContext = addApnContext(Phone.APN_TYPE_MMS);
+ break;
+ case ConnectivityManager.TYPE_MOBILE_SUPL:
+ apnContext = addApnContext(Phone.APN_TYPE_SUPL);
+ break;
+ case ConnectivityManager.TYPE_MOBILE_DUN:
+ apnContext = addApnContext(Phone.APN_TYPE_DUN);
+ break;
+ case ConnectivityManager.TYPE_MOBILE_HIPRI:
+ apnContext = addApnContext(Phone.APN_TYPE_HIPRI);
+ break;
+ case ConnectivityManager.TYPE_MOBILE_FOTA:
+ apnContext = addApnContext(Phone.APN_TYPE_FOTA);
+ break;
+ case ConnectivityManager.TYPE_MOBILE_IMS:
+ apnContext = addApnContext(Phone.APN_TYPE_IMS);
+ break;
+ case ConnectivityManager.TYPE_MOBILE_CBS:
+ apnContext = addApnContext(Phone.APN_TYPE_CBS);
+ break;
+ default:
+ // skip unknown types
+ continue;
+ }
+ if (apnContext != null) {
+ // set the prop, but also apply the newly set enabled and dependency values
+ onSetDependencyMet(apnContext.getApnType(), networkConfig.dependencyMet);
+ }
}
}
@@ -271,7 +316,9 @@
Iterator<ApnContext> it = mApnContexts.values().iterator();
while (it.hasNext()) {
ApnContext apnContext = it.next();
+ if (apnContext.isReady()) {
result.add(apnContext.getApnType());
+ }
}
return (String[])result.toArray(new String[0]);
@@ -353,24 +400,12 @@
public synchronized int enableApnType(String apnType) {
if (DBG) log("calling enableApnType with type:" + apnType);
- if (!isApnTypeAvailable(apnType)) {
+ ApnContext apnContext = mApnContexts.get(apnType);
+ if (apnContext == null || !isApnTypeAvailable(apnType)) {
if (DBG) log("type not available");
return Phone.APN_TYPE_NOT_AVAILABLE;
}
- ApnContext apnContext = mApnContexts.get(apnType);
- if (apnContext==null) {
- // Is there a Proxy type for this?
- apnContext = getProxyActiveApnType(apnType);
- if (apnContext != null ) {
- notifyApnIdUpToCurrent(Phone.REASON_APN_SWITCHED, apnContext, apnType);
- return Phone.APN_REQUEST_STARTED;
- }
- apnContext = new ApnContext(apnType, LOG_TAG);
- if (DBG) log("New apn type context for type "+apnType);
- mApnContexts.put(apnType, apnContext);
- }
-
// If already active, return
log("enableApnType(" + apnType + ")" + ", mState(" + apnContext.getState() + ")");
@@ -389,24 +424,11 @@
}
if (DBG) log("new apn request for type " + apnType + " is to be handled");
- sendMessage(obtainMessage(EVENT_ENABLE_NEW_APN, apnContext));
+ setEnabled(apnTypeToId(apnType), true);
if (DBG) log("return APN_REQUEST_STARTED");
return Phone.APN_REQUEST_STARTED;
}
- // Returns for ex: if HIGHPRI is supported by DEFAULT
- public ApnContext getProxyActiveApnType(String type) {
-
- Iterator<ApnContext> it = mApnContexts.values().iterator();
-
- while(it.hasNext()) {
- ApnContext apnContext = it.next();
- if (apnContext.getApnSetting() != null && mActiveApn.canHandleType(type))
- return apnContext;
- }
- return null;
- }
-
// A new APN has gone active and needs to send events to catch up with the
// current condition
private void notifyApnIdUpToCurrent(String reason, ApnContext apnContext, String type) {
@@ -437,6 +459,8 @@
if (apnContext.getState() != State.IDLE && apnContext.getState() != State.FAILED) {
Message msg = obtainMessage(EVENT_CLEAN_UP_CONNECTION);
msg.arg1 = 1; // tearDown is true;
+ // TODO - don't set things on apnContext from public functions.
+ // Maybe pass reason as arg2?
apnContext.setReason(Phone.REASON_DATA_DISABLED);
msg.obj = apnContext;
sendMessage(msg);
@@ -487,16 +511,11 @@
*/
@Override
public synchronized boolean getAnyDataEnabled() {
- Iterator<ApnContext> it = mApnContexts.values().iterator();
-
if (!(mInternalDataEnabled && mDataEnabled)) return false;
- if (mApnContexts.isEmpty()) return false;
- while (it.hasNext()) {
- ApnContext apnContext= it.next();
+ for (ApnContext apnContext : mApnContexts.values()) {
// Make sure we dont have a context that going down
// and is explicitly disabled.
- if (!(apnContext.getState() == State.DISCONNECTING
- && apnContext.getPendingAction() == ApnContext.PENDING_ACTION_APN_DISABLE)) {
+ if (isDataAllowed(apnContext)) {
return true;
}
}
@@ -508,7 +527,7 @@
&& apnContext.getPendingAction() == ApnContext.PENDING_ACTION_APN_DISABLE) {
return false;
}
- return isDataAllowed();
+ return apnContext.isReady() && isDataAllowed();
}
//****** Called from ServiceStateTracker
@@ -532,11 +551,13 @@
} else {
// Only check for default APN state
ApnContext defaultApnContext = mApnContexts.get(Phone.APN_TYPE_DEFAULT);
- if (defaultApnContext.getState() == State.FAILED) {
- cleanUpConnection(false, defaultApnContext);
- defaultApnContext.getDataConnection().resetRetryCount();
+ if (defaultApnContext != null) {
+ if (defaultApnContext.getState() == State.FAILED) {
+ cleanUpConnection(false, defaultApnContext);
+ defaultApnContext.getDataConnection().resetRetryCount();
+ }
+ trySetupData(Phone.REASON_GPRS_ATTACHED, Phone.APN_TYPE_DEFAULT);
}
- trySetupData(Phone.REASON_GPRS_ATTACHED, Phone.APN_TYPE_DEFAULT);
}
}
@@ -599,10 +620,11 @@
private boolean trySetupData(ApnContext apnContext) {
- if (DBG)
+ if (DBG) {
log("trySetupData for type:" + apnContext.getApnType() +
- " due to " + apnContext.getReason());
- log("[DSAC DEB] " + "trySetupData with mIsPsRestricted=" + mIsPsRestricted);
+ " due to " + apnContext.getReason());
+ log("[DSAC DEB] " + "trySetupData with mIsPsRestricted=" + mIsPsRestricted);
+ }
if (mPhone.getSimulatedRadioControl() != null) {
// Assume data is connected on the simulator
@@ -656,12 +678,8 @@
if (mAvailability == availability) return;
mAvailability = availability;
- Iterator<ApnContext> it = mApnContexts.values().iterator();
- while (it.hasNext()) {
- ApnContext apnContext = it.next();
- // FIXME: Dont understand why this needs to be done!!
- // This information is not available (DISABLED APNS)
- if (false) {
+ for (ApnContext apnContext : mApnContexts.values()) {
+ if (!apnContext.isReady()) {
if (DBG) log("notify disconnected for type:" + apnContext.getApnType());
mPhone.notifyDataConnection(reason != null ? reason : apnContext.getReason(),
apnContext.getApnType(),
@@ -738,10 +756,10 @@
return;
}
- GsmDataConnection conn = apnContext.getDataConnection();
+ DataConnection conn = apnContext.getDataConnection();
if (conn != null) {
apnContext.setState(State.DISCONNECTING);
- if (tearDown ) {
+ if (tearDown) {
Message msg = obtainMessage(EVENT_DISCONNECT_DONE, apnContext);
conn.disconnect(apnContext.getReason(), msg);
} else {
@@ -750,10 +768,6 @@
mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
}
}
-
- if (apnContext.getPendingAction() == ApnContext.PENDING_ACTION_APN_DISABLE) {
- mApnContexts.remove(apnContext.getApnType());
- }
}
@@ -853,6 +867,10 @@
}
if (dc == null) {
+ dc = createDataConnection(apnContext);
+ }
+
+ if (dc == null) {
if (DBG) log("setupData: No free GsmDataConnection found!");
return false;
}
@@ -1272,42 +1290,98 @@
private void onRecordsLoaded() {
createAllApnList();
- ApnContext defaultApnContext = mApnContexts.get(Phone.APN_TYPE_DEFAULT);
- if (defaultApnContext!=null ) {
- defaultApnContext.setReason(Phone.REASON_SIM_LOADED);
- if (defaultApnContext.getState() == State.FAILED) {
- if (DBG) log("onRecordsLoaded clean connection");
- cleanUpConnection(false, defaultApnContext);
+ for (ApnContext apnContext : mApnContexts.values()) {
+ if (apnContext.isReady()) {
+ apnContext.setReason(Phone.REASON_SIM_LOADED);
+ if (apnContext.getState() == State.FAILED) {
+ if (DBG) {
+ log("onRecordsLoaded clean connection for " + apnContext.getApnType());
+ }
+ cleanUpConnection(false, apnContext);
+ }
+ sendMessage(obtainMessage(EVENT_TRY_SETUP_DATA, apnContext));
}
- sendMessage(obtainMessage(EVENT_TRY_SETUP_DATA,defaultApnContext ));
}
}
- protected void onEnableNewApn(ApnContext apnContext ) {
- // change our retry manager to use the appropriate numbers for the new APN
- log("onEnableNewApn with ApnContext E");
- if (apnContext.getApnType().equals(Phone.APN_TYPE_DEFAULT)) {
- log("onEnableNewApn default type");
- ApnContext defaultApnContext = mApnContexts.get(Phone.APN_TYPE_DEFAULT);
- defaultApnContext.getDataConnection().resetRetryCount();
- } else if (mApnToDataConnectionId.get(apnContext.getApnType()) == null) {
- log("onEnableNewApn ApnType=" + apnContext.getApnType() +
- " missing, make a new connection");
- int id = createDataConnection(apnContext.getApnType());
- mDataConnections.get(id).resetRetryCount();
- } else {
- log("oneEnableNewApn connection already exists, nothing to setup");
+ @Override
+ protected void onSetDependencyMet(String apnType, boolean met) {
+ ApnContext apnContext = mApnContexts.get(apnType);
+ if (apnContext == null) {
+ log("ApnContext not found in onSetDependencyMet(" + apnType + ", " + met + ")");
+ return;
}
+ applyNewState(apnContext, apnContext.isEnabled(), met);
+ }
- // TODO: To support simultaneous PDP contexts, this should really only call
- // cleanUpConnection if it needs to free up a GsmDataConnection.
- if (DBG) log("onEnableNewApn setup data");
- if (apnContext.getState() == State.FAILED) {
- if (DBG) log("previous state is FAILED, reset to IDLE");
- apnContext.setState(State.IDLE);
+ private void applyNewState(ApnContext apnContext, boolean enabled, boolean met) {
+ boolean cleanup = false;
+ boolean trySetup = false;
+ if (DBG) {
+ log("applyNewState(" + apnContext.getApnType() + ", " + enabled +
+ "(" + apnContext.isEnabled() + "), " + met + "(" +
+ apnContext.getDependencyMet() +"))");
}
- trySetupData(apnContext);
- log("onEnableNewApn with ApnContext X");
+ if (apnContext.isReady()) {
+ if (enabled && met) return;
+ if (!enabled) {
+ apnContext.setReason(Phone.REASON_DATA_DISABLED);
+ } else {
+ apnContext.setReason(Phone.REASON_DATA_DEPENDENCY_UNMET);
+ }
+ cleanup = true;
+ } else {
+ if (enabled && met) {
+ if (apnContext.isEnabled()) {
+ apnContext.setReason(Phone.REASON_DATA_DEPENDENCY_MET);
+ } else {
+ apnContext.setReason(Phone.REASON_DATA_ENABLED);
+ }
+ DataConnection conn = checkForConnectionForApnContext(apnContext);
+ if (conn == null) {
+ if (apnContext.getState() == State.FAILED) {
+ apnContext.setState(State.IDLE);
+ }
+ trySetup = true;
+ } else {
+ // TODO send notifications
+ if (DBG) {
+ log("Found existing connection for " + apnContext.getApnType() +
+ ": " + conn);
+ }
+ apnContext.setDataConnection(conn);
+ }
+ }
+ }
+ apnContext.setEnabled(enabled);
+ apnContext.setDependencyMet(met);
+ if (cleanup) cleanUpConnection(true, apnContext);
+ if (trySetup) trySetupData(apnContext);
+ }
+
+ private DataConnection checkForConnectionForApnContext(ApnContext apnContext) {
+ // Loop through all apnContexts looking for one with a conn that satisfies this apnType
+ String apnType = apnContext.getApnType();
+ for (ApnContext c : mApnContexts.values()) {
+ DataConnection conn = c.getDataConnection();
+ if (conn != null) {
+ ApnSetting apnSetting = c.getApnSetting();
+ if (apnSetting != null && apnSetting.canHandleType(apnType)) return conn;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ protected void onEnableApn(int apnId, int enabled) {
+ ApnContext apnContext = mApnContexts.get(apnIdToType(apnId));
+ if (apnContext == null) {
+ log("ApnContext not found in onEnableApn(" + apnId + ", " + enabled + ")");
+ return;
+ }
+ // TODO change our retry manager to use the appropriate numbers for the new APN
+ log("onEnableApn with ApnContext E");
+ applyNewState(apnContext, enabled == ENABLED, apnContext.getDependencyMet());
}
@Override
@@ -1392,7 +1466,7 @@
mLinkProperties = getLinkProperties(apnContext.getDataConnection());
mLinkCapabilities = getLinkCapabilities(apnContext.getDataConnection());
- ApnSetting apn = apnContext.getDataConnection().getApn();
+ ApnSetting apn = apnContext.getApnSetting();
if (apn.proxy != null && apn.proxy.length() != 0) {
try {
ProxyProperties proxy = new ProxyProperties(apn.proxy,
@@ -1508,8 +1582,8 @@
// Check if APN disabled.
if (apnContext.getPendingAction() == ApnContext.PENDING_ACTION_APN_DISABLE) {
- mApnContexts.remove(apnContext.getApnType());
- return;
+ apnContext.setEnabled(false);
+ apnContext.setPendingAction(ApnContext.PENDING_ACTION_NONE);
}
if (TextUtils.equals(apnContext.getApnType(), Phone.APN_TYPE_DEFAULT)
@@ -1553,10 +1627,12 @@
} else {
// reset reconnect timer
ApnContext defaultApnContext = mApnContexts.get(Phone.APN_TYPE_DEFAULT);
- defaultApnContext.getDataConnection().resetRetryCount();
- mReregisterOnReconnectFailure = false;
- // in case data setup was attempted when we were on a voice call
- trySetupData(Phone.REASON_VOICE_CALL_ENDED, Phone.APN_TYPE_DEFAULT);
+ if (defaultApnContext != null) {
+ defaultApnContext.getDataConnection().resetRetryCount();
+ mReregisterOnReconnectFailure = false;
+ // in case data setup was attempted when we were on a voice call
+ trySetupData(Phone.REASON_VOICE_CALL_ENDED, Phone.APN_TYPE_DEFAULT);
+ }
}
}
@@ -1584,9 +1660,11 @@
Iterator<ApnContext> it = mApnContexts.values().iterator();
while (it.hasNext()) {
ApnContext apnContext = it.next();
- if (DBG) log("notify for type:"+apnContext.getApnType());
- mPhone.notifyDataConnection(reason != null ? reason : apnContext.getReason(),
- apnContext.getApnType());
+ if (apnContext.isReady()) {
+ if (DBG) log("notify for type:"+apnContext.getApnType());
+ mPhone.notifyDataConnection(reason != null ? reason : apnContext.getReason(),
+ apnContext.getApnType());
+ }
}
notifyDataAvailability(reason);
}
@@ -1598,7 +1676,6 @@
private void createAllApnList() {
mAllApns = new ArrayList<ApnSetting>();
String operator = mPhone.mSIMRecords.getSIMOperatorNumeric();
-
if (operator != null) {
String selection = "numeric = '" + operator + "'";
if (DBG) log("createAllApnList: selection=" + selection);
@@ -1631,7 +1708,8 @@
}
/** Return the id for a new data connection */
- private int createDataConnection(String apnType) {
+ private GsmDataConnection createDataConnection(ApnContext apnContext) {
+ String apnType = apnContext.getApnType();
log("createDataConnection(" + apnType + ") E");
RetryManager rm = new RetryManager();
@@ -1656,12 +1734,13 @@
}
int id = mUniqueIdGenerator.getAndIncrement();
- DataConnection conn = GsmDataConnection.makeDataConnection(mPhone, id, rm);
+ GsmDataConnection conn = GsmDataConnection.makeDataConnection(mPhone, id, rm);
+ conn.resetRetryCount();
mDataConnections.put(id, conn);
- mApnToDataConnectionId.put(apnType, id);
+ apnContext.setDataConnection(conn);
log("createDataConnection(" + apnType + ") X id=" + id);
- return id;
+ return conn;
}
private void destroyDataConnections() {
@@ -1691,7 +1770,6 @@
}
String operator = mPhone.mSIMRecords.getSIMOperatorNumeric();
-
if (requestedApnType.equals(Phone.APN_TYPE_DEFAULT)) {
if (canSetPreferApn && mPreferredApn != null) {
log("Preferred APN:" + operator + ":"
@@ -1707,13 +1785,14 @@
}
}
}
-
if (mAllApns != null) {
for (ApnSetting apn : mAllApns) {
if (apn.canHandleType(requestedApnType)) {
apnList.add(apn);
}
}
+ } else {
+ loge("mAllApns is empty!");
}
if (DBG) log("buildWaitingApns: X apnList=" + apnList);
return apnList;
@@ -1797,14 +1876,6 @@
onRecordsLoaded();
break;
- case EVENT_ENABLE_NEW_APN:
- ApnContext apnContext = null;
- if (msg.obj instanceof ApnContext) {
- apnContext = (ApnContext)msg.obj;
- }
- onEnableNewApn(apnContext);
- break;
-
case EVENT_DATA_CONNECTION_DETACHED:
onDataConnectionDetached();
break;
@@ -1883,8 +1954,7 @@
if (msg.obj instanceof ApnContext) {
cleanUpConnection(tearDown, (ApnContext)msg.obj);
} else {
- Log.e(LOG_TAG,
- "[GsmDataConnectionTracker] connectpion cleanup request w/o apn context");
+ loge("[GsmDataConnectionTracker] connectpion cleanup request w/o apn context");
}
break;
default:
diff --git a/wifi/java/android/net/wifi/WifiStateTracker.java b/wifi/java/android/net/wifi/WifiStateTracker.java
index 07900ae..338cb4d 100644
--- a/wifi/java/android/net/wifi/WifiStateTracker.java
+++ b/wifi/java/android/net/wifi/WifiStateTracker.java
@@ -50,6 +50,7 @@
private LinkProperties mLinkProperties;
private LinkCapabilities mLinkCapabilities;
private NetworkInfo mNetworkInfo;
+ private NetworkInfo.State mLastState = NetworkInfo.State.UNKNOWN;
/* For sending events to connectivity service handler */
private Handler mCsHandler;
@@ -217,6 +218,14 @@
if (mLinkCapabilities == null) {
mLinkCapabilities = new LinkCapabilities();
}
+ // don't want to send redundent state messages
+ // TODO can this be fixed in WifiStateMachine?
+ NetworkInfo.State state = mNetworkInfo.getState();
+ if (mLastState == state) {
+ return;
+ } else {
+ mLastState = state;
+ }
Message msg = mCsHandler.obtainMessage(EVENT_STATE_CHANGED, mNetworkInfo);
msg.sendToTarget();
} else if (intent.getAction().equals(WifiManager.LINK_CONFIGURATION_CHANGED_ACTION)) {
@@ -228,4 +237,7 @@
}
}
+ public void setDependencyMet(boolean met) {
+ // not supported on this network
+ }
}