From db3c8678e5cbdfec011afaf25bde2091152c30ad Mon Sep 17 00:00:00 2001 From: Haoyu Bai Date: Wed, 20 Jun 2012 14:29:57 -0700 Subject: [PATCH] Network data activity change intent for network interfaces. The activity notification is received from netd, an intent DATA_ACTIVITY_CHANGE is then raised for other part of the system to consume. Change-Id: Idfcc4763c51c5b314c57f546c12557082f06bebf --- .../java/android/net/ConnectivityManager.java | 22 ++++++++++++++ .../java/android/net/EthernetDataTracker.java | 4 +++ .../net/INetworkManagementEventObserver.aidl | 7 +++++ core/res/AndroidManifest.xml | 6 ++++ .../server/CommonTimeManagementService.java | 2 ++ .../android/server/ConnectivityService.java | 29 +++++++++++++++++++ .../server/NetworkManagementService.java | 27 +++++++++++++++++ .../com/android/server/ThrottleService.java | 1 + .../server/connectivity/Tethering.java | 2 ++ .../com/android/server/connectivity/Vpn.java | 3 ++ .../server/net/NetworkAlertObserver.java | 3 ++ 11 files changed, 106 insertions(+) diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java index 5f8793c6df3d7..fa1ff8521288b 100644 --- a/core/java/android/net/ConnectivityManager.java +++ b/core/java/android/net/ConnectivityManager.java @@ -136,6 +136,28 @@ public class ConnectivityManager { */ public static final String EXTRA_INET_CONDITION = "inetCondition"; + /** + * Broadcast action to indicate the change of data activity status + * (idle or active) on a network in a recent period. + * The network becomes active when data transimission is started, or + * idle if there is no data transimition for a period of time. + * {@hide} + */ + @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) + public static final String ACTION_DATA_ACTIVITY_CHANGE = "android.net.conn.DATA_ACTIVITY_CHANGE"; + /** + * The lookup key for an enum that indicates the network device type on which this data activity + * change happens. + * {@hide} + */ + public static final String EXTRA_DEVICE_TYPE = "deviceType"; + /** + * The lookup key for a boolean that indicates the device is active or not. {@code true} means + * it is actively sending or receiving data and {@code false} means it is idle. + * {@hide} + */ + public static final String EXTRA_IS_ACTIVE = "isActive"; + /** * Broadcast Action: The setting for background data usage has changed * values. Use {@link #getBackgroundDataSetting()} to get the current value. diff --git a/core/java/android/net/EthernetDataTracker.java b/core/java/android/net/EthernetDataTracker.java index 5197c9e82e96f..c690430c09f0a 100644 --- a/core/java/android/net/EthernetDataTracker.java +++ b/core/java/android/net/EthernetDataTracker.java @@ -99,6 +99,10 @@ public class EthernetDataTracker implements NetworkStateTracker { public void limitReached(String limitName, String iface) { // Ignored. } + + public void interfaceClassDataActivityChanged(String label, boolean active) { + // Ignored. + } } private EthernetDataTracker() { diff --git a/core/java/android/net/INetworkManagementEventObserver.aidl b/core/java/android/net/INetworkManagementEventObserver.aidl index a97f2030a146f..6f4dd5f348ebd 100644 --- a/core/java/android/net/INetworkManagementEventObserver.aidl +++ b/core/java/android/net/INetworkManagementEventObserver.aidl @@ -62,4 +62,11 @@ interface INetworkManagementEventObserver { */ void limitReached(String limitName, String iface); + /** + * Interface data activity status is changed. + * + * @param iface The interface. + * @param active True if the interface is actively transmitting data, false if it is idle. + */ + void interfaceClassDataActivityChanged(String label, boolean active); } diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 06414d9bb4970..9253f24bff24f 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -121,6 +121,7 @@ + @@ -508,6 +509,11 @@ android:permissionGroup="android.permission-group.NETWORK" android:protectionLevel="signature|system" /> + + + diff --git a/services/java/com/android/server/CommonTimeManagementService.java b/services/java/com/android/server/CommonTimeManagementService.java index 9a25d2ea5f397..c316733fe0589 100644 --- a/services/java/com/android/server/CommonTimeManagementService.java +++ b/services/java/com/android/server/CommonTimeManagementService.java @@ -120,6 +120,8 @@ class CommonTimeManagementService extends Binder { reevaluateServiceState(); } public void limitReached(String limitName, String iface) { } + + public void interfaceClassDataActivityChanged(String label, boolean active) {} }; private BroadcastReceiver mConnectivityMangerObserver = new BroadcastReceiver() { diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java index 230f07bb5baf2..9f9390195f629 100644 --- a/services/java/com/android/server/ConnectivityService.java +++ b/services/java/com/android/server/ConnectivityService.java @@ -17,6 +17,7 @@ package com.android.server; import static android.Manifest.permission.MANAGE_NETWORK_POLICY; +import static android.Manifest.permission.RECEIVE_DATA_ACTIVITY_CHANGE; import static android.net.ConnectivityManager.CONNECTIVITY_ACTION; import static android.net.ConnectivityManager.CONNECTIVITY_ACTION_IMMEDIATE; import static android.net.ConnectivityManager.isNetworkTypeValid; @@ -35,6 +36,7 @@ import android.net.ConnectivityManager; import android.net.DummyDataStateTracker; import android.net.EthernetDataTracker; import android.net.IConnectivityManager; +import android.net.INetworkManagementEventObserver; import android.net.INetworkPolicyListener; import android.net.INetworkPolicyManager; import android.net.INetworkStatsService; @@ -546,6 +548,13 @@ public class ConnectivityService extends IConnectivityManager.Stub { mSettingsObserver = new SettingsObserver(mHandler, EVENT_APPLY_GLOBAL_HTTP_PROXY); mSettingsObserver.observe(mContext); + INetworkManagementEventObserver netdObserver = new NetdObserver(); + try { + mNetd.registerObserver(netdObserver); + } catch (RemoteException e) { + loge("Error registering observer :" + e); + } + loadGlobalProxy(); } private NetworkStateTracker makeWimaxStateTracker() { @@ -923,6 +932,19 @@ private NetworkStateTracker makeWimaxStateTracker() { return tracker != null && tracker.setRadio(turnOn); } + private class NetdObserver extends INetworkManagementEventObserver.Stub { + public void interfaceClassDataActivityChanged(String label, boolean active) { + int deviceType = Integer.parseInt(label); + sendDataActivityBroadcast(deviceType, active); + } + + public void interfaceStatusChanged(String iface, boolean up) {} + public void interfaceLinkStateChanged(String iface, boolean up) {} + public void interfaceAdded(String iface) {} + public void interfaceRemoved(String iface) {} + public void limitReached(String limitName, String iface) {} + } + /** * Used to notice when the calling process dies so we can self-expire * @@ -1759,6 +1781,13 @@ private NetworkStateTracker makeWimaxStateTracker() { sendStickyBroadcastDelayed(makeGeneralIntent(info, bcastType), delayMs); } + private void sendDataActivityBroadcast(int deviceType, boolean active) { + Intent intent = new Intent(ConnectivityManager.ACTION_DATA_ACTIVITY_CHANGE); + intent.putExtra(ConnectivityManager.EXTRA_DEVICE_TYPE, deviceType); + intent.putExtra(ConnectivityManager.EXTRA_IS_ACTIVE, active); + mContext.sendOrderedBroadcast(intent, RECEIVE_DATA_ACTIVITY_CHANGE); + } + /** * Called when an attempt to fail over to another network has failed. * @param info the {@link NetworkInfo} for the failed network diff --git a/services/java/com/android/server/NetworkManagementService.java b/services/java/com/android/server/NetworkManagementService.java index 67bb680721063..c3f3a5d47fe40 100644 --- a/services/java/com/android/server/NetworkManagementService.java +++ b/services/java/com/android/server/NetworkManagementService.java @@ -279,6 +279,20 @@ public class NetworkManagementService extends INetworkManagementService.Stub mObservers.finishBroadcast(); } + /** + * Notify our observers of a change in the data activity state of the interface + */ + private void notifyInterfaceClassActivity(String label, boolean active) { + final int length = mObservers.beginBroadcast(); + for (int i = 0; i < length; i++) { + try { + mObservers.getBroadcastItem(i).interfaceClassDataActivityChanged(label, active); + } catch (RemoteException e) { + } + } + mObservers.finishBroadcast(); + } + /** * Prepare native daemon once connected, enabling modules and pushing any * existing in-memory rules. @@ -405,6 +419,19 @@ public class NetworkManagementService extends INetworkManagementService.Stub throw new IllegalStateException( String.format("Invalid event from daemon (%s)", raw)); // break; + case NetdResponseCode.InterfaceClassActivity: + /* + * An network interface class state changed (active/idle) + * Format: "NNN IfaceClass