From eaecb133ea615c9e80274fb3ec14f2fbf6f0445b Mon Sep 17 00:00:00 2001 From: Robert Greenwalt Date: Wed, 8 Sep 2010 15:24:47 -0700 Subject: [PATCH] Add network condition reporting. Apps can report if they like their connection to the nets and we display either not-really-connected or fully-connected icons. Final icons TBD. bug:2978624 Change-Id: I28be52085edfe54571c0d4559aba0df883548654 --- .../java/android/net/ConnectivityManager.java | 22 ++++- .../android/net/IConnectivityManager.aidl | 2 + .../android/server/ConnectivityService.java | 89 +++++++++++++++++++ 3 files changed, 112 insertions(+), 1 deletion(-) diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java index 280ded6bcc..331ce10a64 100644 --- a/core/java/android/net/ConnectivityManager.java +++ b/core/java/android/net/ConnectivityManager.java @@ -102,6 +102,14 @@ public class ConnectivityManager * it with {@link android.content.Intent#getStringExtra(String)}. */ public static final String EXTRA_EXTRA_INFO = "extraInfo"; + /** + * The lookup key for an int that provides information about + * our connection to the internet at large. 0 indicates no connection, + * 100 indicates a great connection. Retrieve it with + * {@link android.content.Intent@getIntExtra(String)}. + * {@hide} + */ + public static final String EXTRA_INET_CONDITION = "inetCondition"; /** * Broadcast Action: The setting for background data usage has changed @@ -524,5 +532,17 @@ public class ConnectivityManager } catch (RemoteException e) { return TETHER_ERROR_SERVICE_UNAVAIL; } - } + } + + /** + * @param networkType The type of network you want to report on + * @param percentage The quality of the connection 0 is bad, 100 is good + * {@hide} + */ + public void reportInetCondition(int networkType, int percentage) { + try { + mService.reportInetCondition(networkType, percentage); + } catch (RemoteException e) { + } + } } diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl index b05c2edd10..b734ac7ebb 100644 --- a/core/java/android/net/IConnectivityManager.aidl +++ b/core/java/android/net/IConnectivityManager.aidl @@ -72,4 +72,6 @@ interface IConnectivityManager String[] getTetherableUsbRegexs(); String[] getTetherableWifiRegexs(); + + void reportInetCondition(int networkType, int percentage); } diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java index c751f3decd..9784d96aed 100644 --- a/services/java/com/android/server/ConnectivityService.java +++ b/services/java/com/android/server/ConnectivityService.java @@ -89,6 +89,11 @@ public class ConnectivityService extends IConnectivityManager.Stub { private Context mContext; private int mNetworkPreference; private int mActiveDefaultNetwork = -1; + // 0 is full bad, 100 is full good + private int mDefaultInetCondition = 0; + private int mDefaultInetConditionPublished = 0; + private boolean mInetConditionChangeInFlight = false; + private int mDefaultConnectionSequence = 0; private int mNumDnsEntries; @@ -1016,6 +1021,7 @@ public class ConnectivityService extends IConnectivityManager.Stub { intent.putExtra(ConnectivityManager.EXTRA_EXTRA_INFO, info.getExtraInfo()); } + intent.putExtra(ConnectivityManager.EXTRA_INET_CONDITION, mDefaultInetConditionPublished); sendStickyBroadcast(intent); } @@ -1134,6 +1140,14 @@ public class ConnectivityService extends IConnectivityManager.Stub { } } mActiveDefaultNetwork = type; + // this will cause us to come up initially as unconnected and switching + // to connected after our normal pause unless somebody reports us as reall + // disconnected + mDefaultInetConditionPublished = 0; + mDefaultConnectionSequence++; + mInetConditionChangeInFlight = false; + // Don't do this - if we never sign in stay, grey + //reportNetworkCondition(mActiveDefaultNetwork, 100); } thisNet.setTeardownRequested(false); thisNet.updateNetworkSettings(); @@ -1436,6 +1450,70 @@ public class ConnectivityService extends IConnectivityManager.Stub { FeatureUser u = (FeatureUser)msg.obj; u.expire(); break; + case NetworkStateTracker.EVENT_INET_CONDITION_CHANGE: + if (DBG) { + Slog.d(TAG, "Inet connectivity change, net=" + + msg.arg1 + ", condition=" + msg.arg2 + + ",mActiveDefaultNetwork=" + mActiveDefaultNetwork); + } + if (mActiveDefaultNetwork == -1) { + if (DBG) Slog.d(TAG, "no active default network - aborting"); + break; + } + if (mActiveDefaultNetwork != msg.arg1) { + if (DBG) Slog.d(TAG, "given net not default - aborting"); + break; + } + mDefaultInetCondition = msg.arg2; + int delay; + if (mInetConditionChangeInFlight == false) { + if (DBG) Slog.d(TAG, "starting a change hold"); + // setup a new hold to debounce this + if (mDefaultInetCondition > 50) { + delay = Settings.Secure.getInt(mContext.getContentResolver(), + Settings.Secure.INET_CONDITION_DEBOUNCE_UP_DELAY, 500); + } else { + delay = Settings.Secure.getInt(mContext.getContentResolver(), + Settings.Secure.INET_CONDITION_DEBOUNCE_DOWN_DELAY, 3000); + } + mInetConditionChangeInFlight = true; + sendMessageDelayed(obtainMessage( + NetworkStateTracker.EVENT_INET_CONDITION_HOLD_END, + mActiveDefaultNetwork, mDefaultConnectionSequence), delay); + } else { + // we've set the new condition, when this hold ends that will get + // picked up + if (DBG) Slog.d(TAG, "currently in hold - not setting new end evt"); + } + break; + case NetworkStateTracker.EVENT_INET_CONDITION_HOLD_END: + if (DBG) { + Slog.d(TAG, "Inet hold end, net=" + msg.arg1 + + ", condition =" + mDefaultInetCondition + + ", published condition =" + mDefaultInetConditionPublished); + } + mInetConditionChangeInFlight = false; + + if (mActiveDefaultNetwork == -1) { + if (DBG) Slog.d(TAG, "no active default network - aborting"); + break; + } + if (mDefaultConnectionSequence != msg.arg2) { + if (DBG) Slog.d(TAG, "event hold for obsolete network - aborting"); + break; + } + if (mDefaultInetConditionPublished == mDefaultInetCondition) { + if (DBG) Slog.d(TAG, "no change in condition - aborting"); + break; + } + NetworkInfo networkInfo = mNetTrackers[mActiveDefaultNetwork].getNetworkInfo(); + if (networkInfo.isConnected() == false) { + if (DBG) Slog.d(TAG, "default network not connected - aborting"); + break; + } + mDefaultInetConditionPublished = mDefaultInetCondition; + sendConnectedBroadcast(networkInfo); + break; } } } @@ -1519,4 +1597,15 @@ public class ConnectivityService extends IConnectivityManager.Stub { Settings.Secure.TETHER_SUPPORTED, defaultVal) != 0); return tetherEnabledInSettings && mTetheringConfigValid; } + + // 100 percent is full good, 0 is full bad. + public void reportInetCondition(int networkType, int percentage) { + if (DBG) Slog.d(TAG, "reportNetworkCondition(" + networkType + ", " + percentage + ")"); + mContext.enforceCallingOrSelfPermission( + android.Manifest.permission.STATUS_BAR, + "ConnectivityService"); + + mHandler.sendMessage(mHandler.obtainMessage( + NetworkStateTracker.EVENT_INET_CONDITION_CHANGE, networkType, percentage)); + } }