diff options
11 files changed, 106 insertions, 0 deletions
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java index 5f8793c..fa1ff85 100644 --- a/core/java/android/net/ConnectivityManager.java +++ b/core/java/android/net/ConnectivityManager.java @@ -137,6 +137,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. * <p> diff --git a/core/java/android/net/EthernetDataTracker.java b/core/java/android/net/EthernetDataTracker.java index 5197c9e..c690430 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 a97f203..6f4dd5f 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 06414d9..9253f24 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -121,6 +121,7 @@ <protected-broadcast android:name="android.net.conn.CONNECTIVITY_CHANGE" /> <protected-broadcast android:name="android.net.conn.CONNECTIVITY_CHANGE_IMMEDIATE" /> + <protected-broadcast android:name="android.net.conn.DATA_ACTIVITY_CHANGE" /> <protected-broadcast android:name="android.nfc.action.LLCP_LINK_STATE_CHANGED" /> <protected-broadcast android:name="com.android.nfc_extras.action.RF_FIELD_ON_DETECTED" /> @@ -508,6 +509,11 @@ android:permissionGroup="android.permission-group.NETWORK" android:protectionLevel="signature|system" /> + <!-- @hide --> + <permission android:name="android.permission.RECEIVE_DATA_ACTIVITY_CHANGE" + android:permissionGroup="android.permission-group.NETWORK" + android:protectionLevel="signature|system" /> + <!-- ================================== --> <!-- Permissions for accessing accounts --> <!-- ================================== --> diff --git a/services/java/com/android/server/CommonTimeManagementService.java b/services/java/com/android/server/CommonTimeManagementService.java index 9a25d2e..c316733 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 230f07b..9f93901 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 67bb680..c3f3a5d 100644 --- a/services/java/com/android/server/NetworkManagementService.java +++ b/services/java/com/android/server/NetworkManagementService.java @@ -280,6 +280,20 @@ public class NetworkManagementService extends INetworkManagementService.Stub } /** + * 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 <active/idle> <label>" + */ + if (cooked.length < 4 || !cooked[1].equals("IfaceClass")) { + throw new IllegalStateException( + String.format("Invalid event from daemon (%s)", raw)); + } + boolean isActive = cooked[2].equals("active"); + notifyInterfaceClassActivity(cooked[3], isActive); + return true; + // break; default: break; } return false; diff --git a/services/java/com/android/server/ThrottleService.java b/services/java/com/android/server/ThrottleService.java index f35a5af..98e6dc0 100644 --- a/services/java/com/android/server/ThrottleService.java +++ b/services/java/com/android/server/ThrottleService.java @@ -195,6 +195,7 @@ public class ThrottleService extends IThrottleManager.Stub { public void interfaceRemoved(String iface) {} public void limitReached(String limitName, String iface) {} + public void interfaceClassDataActivityChanged(String label, boolean active) {} } diff --git a/services/java/com/android/server/connectivity/Tethering.java b/services/java/com/android/server/connectivity/Tethering.java index 5aa3a29..e4f1f7a 100644 --- a/services/java/com/android/server/connectivity/Tethering.java +++ b/services/java/com/android/server/connectivity/Tethering.java @@ -319,6 +319,8 @@ public class Tethering extends INetworkManagementEventObserver.Stub { public void limitReached(String limitName, String iface) {} + public void interfaceClassDataActivityChanged(String label, boolean active) {} + public int tether(String iface) { if (DBG) Log.d(TAG, "Tethering " + iface); TetherInterfaceSM sm = null; diff --git a/services/java/com/android/server/connectivity/Vpn.java b/services/java/com/android/server/connectivity/Vpn.java index 4b82037..b12d597 100644 --- a/services/java/com/android/server/connectivity/Vpn.java +++ b/services/java/com/android/server/connectivity/Vpn.java @@ -291,6 +291,9 @@ public class Vpn extends INetworkManagementEventObserver.Stub { public void limitReached(String limit, String interfaze) { } + public void interfaceClassDataActivityChanged(String label, boolean active) { + } + private void enforceControlPermission() { // System user is allowed to control VPN. if (Binder.getCallingUid() == Process.SYSTEM_UID) { diff --git a/services/java/com/android/server/net/NetworkAlertObserver.java b/services/java/com/android/server/net/NetworkAlertObserver.java index 0d1c3b2..9e181c5 100644 --- a/services/java/com/android/server/net/NetworkAlertObserver.java +++ b/services/java/com/android/server/net/NetworkAlertObserver.java @@ -41,4 +41,7 @@ public abstract class NetworkAlertObserver extends INetworkManagementEventObserv public void interfaceAdded(String iface) { // ignored; interface changes come through ConnectivityService } + public void interfaceClassDataActivityChanged(String label, boolean active) { + // ignored; interface changes come through ConnectivityService + } } |