From d55a6b498d66d8fc415908ecf63e50f46cce67e8 Mon Sep 17 00:00:00 2001 From: Robert Greenwalt Date: Fri, 25 Mar 2011 13:09:25 -0700 Subject: [PATCH] Add external dependency API. An APN will not be connected to if some external dependency is not met. bug:3486704 Change-Id: I7d94df343b260013efd11faa978deb13f07f1389 --- .../bluetooth/BluetoothTetheringDataTracker.java | 4 + core/java/android/net/ConnectivityManager.java | 12 + core/java/android/net/DummyDataStateTracker.java | 4 + core/java/android/net/IConnectivityManager.aidl | 2 + core/java/android/net/MobileDataStateTracker.java | 20 ++ core/java/android/net/NetworkConfig.java | 76 +++++ core/java/android/net/NetworkStateTracker.java | 5 + core/res/res/values/config.xml | 1 + .../com/android/server/ConnectivityService.java | 137 +++++---- .../com/android/internal/telephony/ApnContext.java | 59 +++- .../android/internal/telephony/DataConnection.java | 4 + .../internal/telephony/DataConnectionTracker.java | 47 +++- .../java/com/android/internal/telephony/Phone.java | 2 + .../internal/telephony/gsm/GsmDataConnection.java | 5 - .../telephony/gsm/GsmDataConnectionTracker.java | 306 +++++++++++++-------- wifi/java/android/net/wifi/WifiStateTracker.java | 12 + 16 files changed, 484 insertions(+), 212 deletions(-) create mode 100644 core/java/android/net/NetworkConfig.java diff --git a/core/java/android/bluetooth/BluetoothTetheringDataTracker.java b/core/java/android/bluetooth/BluetoothTetheringDataTracker.java index c08f14f3f81f..a7b00375e841 100644 --- a/core/java/android/bluetooth/BluetoothTetheringDataTracker.java +++ b/core/java/android/bluetooth/BluetoothTetheringDataTracker.java @@ -300,4 +300,8 @@ public class BluetoothTetheringDataTracker implements NetworkStateTracker { 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 26f375d43db3..b541ec30c021 100644 --- a/core/java/android/net/ConnectivityManager.java +++ b/core/java/android/net/ConnectivityManager.java @@ -690,4 +690,16 @@ public class ConnectivityManager 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 d0c77cf900c6..e39725a2d140 100644 --- a/core/java/android/net/DummyDataStateTracker.java +++ b/core/java/android/net/DummyDataStateTracker.java @@ -191,6 +191,10 @@ public class DummyDataStateTracker implements NetworkStateTracker { 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 70ab4f153ef7..8be492c8e077 100644 --- a/core/java/android/net/IConnectivityManager.aidl +++ b/core/java/android/net/IConnectivityManager.aidl @@ -92,4 +92,6 @@ interface IConnectivityManager 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 5b4da66a4f24..bb6ee0f809cd 100644 --- a/core/java/android/net/MobileDataStateTracker.java +++ b/core/java/android/net/MobileDataStateTracker.java @@ -20,6 +20,7 @@ import android.content.BroadcastReceiver; 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 @@ public class MobileDataStateTracker implements NetworkStateTracker { } } + /** + * 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 000000000000..4adb76b8610f --- /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 eb97d77ba345..f53063de766c 100644 --- a/core/java/android/net/NetworkStateTracker.java +++ b/core/java/android/net/NetworkStateTracker.java @@ -176,4 +176,9 @@ public interface NetworkStateTracker { * 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 203719152ad8..669529676d7e 100755 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -132,6 +132,7 @@ based on the hardware --> + "wifi,1,1,1" "mobile,0,0,0" diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java index f170cb7358e2..d3349cc9c3d3 100644 --- a/services/java/com/android/server/ConnectivityService.java +++ b/services/java/com/android/server/ConnectivityService.java @@ -27,6 +27,7 @@ import android.net.DummyDataStateTracker; 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 @@ public class ConnectivityService extends IConnectivityManager.Stub { 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 @@ public class ConnectivityService extends IConnectivityManager.Stub { 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 @@ public class ConnectivityService extends IConnectivityManager.Stub { 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 @@ public class ConnectivityService extends IConnectivityManager.Stub { 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 @@ public class ConnectivityService extends IConnectivityManager.Stub { "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 @@ public class ConnectivityService extends IConnectivityManager.Stub { 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 @@ public class ConnectivityService extends IConnectivityManager.Stub { * 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 @@ public class ConnectivityService extends IConnectivityManager.Stub { 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 @@ public class ConnectivityService extends IConnectivityManager.Stub { break; default: loge("Trying to create a DataStateTracker for an unknown radio type " + - mNetAttributes[netType].mRadio); + mNetConfigs[netType].mRadio); continue; } } @@ -469,8 +457,8 @@ public class ConnectivityService extends IConnectivityManager.Stub { 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 class ConnectivityService extends IConnectivityManager.Stub { 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 class ConnectivityService extends IConnectivityManager.Stub { 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 @@ public class ConnectivityService extends IConnectivityManager.Stub { } enforceChangePermission(); if (!ConnectivityManager.isNetworkTypeValid(networkType) || - mNetAttributes[networkType] == null) { + mNetConfigs[networkType] == null) { return Phone.APN_REQUEST_FAILED; } @@ -999,6 +987,24 @@ public class ConnectivityService extends IConnectivityManager.Stub { 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 @@ public class ConnectivityService extends IConnectivityManager.Stub { 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 @@ public class ConnectivityService extends IConnectivityManager.Stub { * 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= mNetAttributes[checkType].mPriority) continue; +// if (currentPriority >= mNetConfigs[checkType].mPriority) continue; NetworkStateTracker checkTracker = mNetTrackers[checkType]; NetworkInfo checkInfo = checkTracker.getNetworkInfo(); @@ -1223,7 +1229,7 @@ public class ConnectivityService extends IConnectivityManager.Stub { 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 @@ public class ConnectivityService extends IConnectivityManager.Stub { // 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 @@ public class ConnectivityService extends IConnectivityManager.Stub { 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 @@ public class ConnectivityService extends IConnectivityManager.Stub { { 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 @@ public class ConnectivityService extends IConnectivityManager.Stub { if (p == null) return; Collection 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 @@ public class ConnectivityService extends IConnectivityManager.Stub { 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 @@ public class ConnectivityService extends IConnectivityManager.Stub { 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 @@ public class ConnectivityService extends IConnectivityManager.Stub { 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 a86ea7eec63e..2e7c3a32c11e 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.app.PendingIntent; import android.util.Log; import java.util.ArrayList; -import com.android.internal.telephony.gsm.GsmDataConnection; /** * Maintain the Apn context @@ -30,9 +29,13 @@ public class ApnContext { 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 @@ public class ApnContext { 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 @@ public class ApnContext { 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 e21e951b87b9..7214cf6a37e7 100644 --- a/telephony/java/com/android/internal/telephony/DataConnection.java +++ b/telephony/java/com/android/internal/telephony/DataConnection.java @@ -1097,4 +1097,8 @@ public abstract class DataConnection extends HierarchicalStateMachine { 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 fba73fb582ea..d5b65e1b9202 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.LinkProperties; 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 @@ public abstract class DataConnectionTracker extends Handler { 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 abstract class DataConnectionTracker extends Handler { 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 @@ public abstract class DataConnectionTracker extends Handler { 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 @@ public abstract class DataConnectionTracker extends Handler { } } - 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 @@ public abstract class DataConnectionTracker extends Handler { 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 @@ public abstract class DataConnectionTracker extends Handler { 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 @@ public abstract class DataConnectionTracker extends Handler { } } 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 @@ public abstract class DataConnectionTracker extends Handler { } } + 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 7450047a3d6d..9f16d31add76 100644 --- a/telephony/java/com/android/internal/telephony/Phone.java +++ b/telephony/java/com/android/internal/telephony/Phone.java @@ -175,6 +175,8 @@ public interface Phone { 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 b0b2ac56515d..2589de450812 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 @@ public class GsmDataConnection extends DataConnection { 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 891a2378376e..b5dadf60c5f1 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.Intent; 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 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { p.getContext().getContentResolver().registerContentObserver( Telephony.Carriers.CONTENT_URI, true, mApnObserver); - /** Create the default connection */ mApnContexts = new ConcurrentHashMap(); - initApncontextsAndDataConnection(); + initApnContextsAndDataConnection(); broadcastMessenger(); } @@ -206,6 +207,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { * because the phone is out of coverage or some like reason. * * @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 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { 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 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { Iterator 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 final class GsmDataConnectionTracker extends DataConnectionTracker { 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 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { } 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 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 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { 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 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { */ @Override public synchronized boolean getAnyDataEnabled() { - Iterator 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 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { && apnContext.getPendingAction() == ApnContext.PENDING_ACTION_APN_DISABLE) { return false; } - return isDataAllowed(); + return apnContext.isReady() && isDataAllowed(); } //****** Called from ServiceStateTracker @@ -532,11 +551,13 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { } 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 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { 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 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { if (mAvailability == availability) return; mAvailability = availability; - Iterator 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 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { 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 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType()); } } - - if (apnContext.getPendingAction() == ApnContext.PENDING_ACTION_APN_DISABLE) { - mApnContexts.remove(apnContext.getApnType()); - } } @@ -853,6 +867,10 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { } if (dc == null) { + dc = createDataConnection(apnContext); + } + + if (dc == null) { if (DBG) log("setupData: No free GsmDataConnection found!"); return false; } @@ -1272,42 +1290,98 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { 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(); + @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); + } + + 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() +"))"); + } + 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 { - log("oneEnableNewApn connection already exists, nothing to setup"); + 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; + } - // 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); + @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; } - trySetupData(apnContext); - log("onEnableNewApn with ApnContext X"); + // 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 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { 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 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { // 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 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { } 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 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { Iterator 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 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { private void createAllApnList() { mAllApns = new ArrayList(); String operator = mPhone.mSIMRecords.getSIMOperatorNumeric(); - if (operator != null) { String selection = "numeric = '" + operator + "'"; if (DBG) log("createAllApnList: selection=" + selection); @@ -1631,7 +1708,8 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { } /** 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 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { } 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 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { } String operator = mPhone.mSIMRecords.getSIMOperatorNumeric(); - if (requestedApnType.equals(Phone.APN_TYPE_DEFAULT)) { if (canSetPreferApn && mPreferredApn != null) { log("Preferred APN:" + operator + ":" @@ -1707,13 +1785,14 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { } } } - 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 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { 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 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { 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 07900ae4ca43..338cb4d0b466 100644 --- a/wifi/java/android/net/wifi/WifiStateTracker.java +++ b/wifi/java/android/net/wifi/WifiStateTracker.java @@ -50,6 +50,7 @@ public class WifiStateTracker implements NetworkStateTracker { 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 @@ public class WifiStateTracker implements NetworkStateTracker { 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 class WifiStateTracker implements NetworkStateTracker { } } + public void setDependencyMet(boolean met) { + // not supported on this network + } } -- 2.11.0