Loading core/java/android/net/TrafficStats.java +37 −0 Original line number Diff line number Diff line Loading @@ -68,6 +68,43 @@ public class TrafficStats { */ public static native long getMobileRxBytes(); /** * Get the total number of packets transmitted through the specified interface. * * @return number of packets. If the statistics are not supported by this interface, * {@link #UNSUPPORTED} will be returned. * @hide */ public static native long getTxPackets(String iface); /** * Get the total number of packets received through the specified interface. * * @return number of packets. If the statistics are not supported by this interface, * {@link #UNSUPPORTED} will be returned. * @hide */ public static native long getRxPackets(String iface); /** * Get the total number of bytes transmitted through the specified interface. * * @return number of bytes. If the statistics are not supported by this interface, * {@link #UNSUPPORTED} will be returned. * @hide */ public static native long getTxBytes(String iface); /** * Get the total number of bytes received through the specified interface. * * @return number of bytes. If the statistics are not supported by this interface, * {@link #UNSUPPORTED} will be returned. * @hide */ public static native long getRxBytes(String iface); /** * Get the total number of packets sent through all network interfaces. * Loading core/jni/android_net_TrafficStats.cpp +31 −0 Original line number Diff line number Diff line Loading @@ -130,6 +130,33 @@ static jlong getMobileRxBytes(JNIEnv* env, jobject clazz) { "/sys/class/net/ppp0/statistics/rx_bytes"); } static jlong getData(JNIEnv* env, char *what, jstring interface) { char filename[80]; jboolean isCopy; const char *interfaceStr = env->GetStringUTFChars(interface, &isCopy); snprintf(filename, sizeof(filename), "/sys/class/net/%s/statistics/%s", interfaceStr, what); return readNumber(filename); } static jlong getTxPackets(JNIEnv* env, jobject clazz, jstring interface) { return getData(env, "tx_packets", interface); } static jlong getRxPackets(JNIEnv* env, jobject clazz, jstring interface) { return getData(env, "rx_packets", interface); } static jlong getTxBytes(JNIEnv* env, jobject clazz, jstring interface) { return getData(env, "tx_bytes", interface); } static jlong getRxBytes(JNIEnv* env, jobject clazz, jstring interface) { return getData(env, "rx_bytes", interface); } // Total stats are read less often, so we're willing to put up // with listing the directory and concatenating filenames. Loading Loading @@ -288,6 +315,10 @@ static JNINativeMethod gMethods[] = { {"getMobileRxPackets", "()J", (void*) getMobileRxPackets}, {"getMobileTxBytes", "()J", (void*) getMobileTxBytes}, {"getMobileRxBytes", "()J", (void*) getMobileRxBytes}, {"getTxPackets", "(Ljava/lang/String;)J", (void*) getTxPackets}, {"getRxPackets", "(Ljava/lang/String;)J", (void*) getRxPackets}, {"getTxBytes", "(Ljava/lang/String;)J", (void*) getTxBytes}, {"getRxBytes", "(Ljava/lang/String;)J", (void*) getRxBytes}, {"getTotalTxPackets", "()J", (void*) getTotalTxPackets}, {"getTotalRxPackets", "()J", (void*) getTotalRxPackets}, {"getTotalTxBytes", "()J", (void*) getTotalTxBytes}, Loading packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java +53 −0 Original line number Diff line number Diff line Loading @@ -33,6 +33,11 @@ import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiInfo; import android.net.wifi.WifiManager; import android.os.Binder; import android.os.Handler; import android.os.HandlerThread; import android.os.Looper; import android.os.Message; import android.os.Messenger; import android.os.RemoteException; import android.provider.Settings; import android.provider.Telephony; Loading @@ -50,6 +55,7 @@ import com.android.internal.telephony.IccCard; import com.android.internal.telephony.TelephonyIntents; import com.android.internal.telephony.cdma.EriInfo; import com.android.server.am.BatteryStatsService; import com.android.internal.util.AsyncChannel; import com.android.systemui.R; Loading Loading @@ -82,6 +88,7 @@ public class NetworkController extends BroadcastReceiver { // wifi final WifiManager mWifiManager; AsyncChannel mWifiChannel; boolean mWifiEnabled, mWifiConnected; int mWifiLevel; String mWifiSsid; Loading Loading @@ -140,6 +147,14 @@ public class NetworkController extends BroadcastReceiver { // wifi mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); HandlerThread handlerThread = new HandlerThread("WifiServiceThread"); handlerThread.start(); Handler handler = new WifiHandler(handlerThread.getLooper()); mWifiChannel = new AsyncChannel(); Messenger wifiMessenger = mWifiManager.getMessenger(); if (wifiMessenger != null) { mWifiChannel.connect(mContext, handler, wifiMessenger); } // broadcasts IntentFilter filter = new IntentFilter(); Loading Loading @@ -584,6 +599,44 @@ public class NetworkController extends BroadcastReceiver { // ===== Wifi =================================================================== class WifiHandler extends Handler { WifiHandler(Looper looper) { super(looper); } @Override public void handleMessage(Message msg) { switch (msg.what) { case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED: if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) { mWifiChannel.sendMessage(Message.obtain(this, AsyncChannel.CMD_CHANNEL_FULL_CONNECTION)); } else { Slog.e(TAG, "Failed to connect to wifi"); } break; case WifiManager.DATA_ACTIVITY_NOTIFICATION: int dataActivity = msg.arg1; /* TODO: update icons based on data activity */ switch (dataActivity) { case WifiManager.DATA_ACTIVITY_IN: break; case WifiManager.DATA_ACTIVITY_OUT: break; case WifiManager.DATA_ACTIVITY_INOUT: break; case WifiManager.DATA_ACTIVITY_NONE: break; } break; default: //Ignore break; } } } private void updateWifiState(Intent intent) { final String action = intent.getAction(); if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) { Loading services/java/com/android/server/WifiService.java +175 −38 Original line number Diff line number Diff line Loading @@ -42,14 +42,18 @@ import android.net.ConnectivityManager; import android.net.DhcpInfo; import android.net.NetworkInfo; import android.net.NetworkInfo.State; import android.net.NetworkInfo.DetailedState; import android.net.TrafficStats; import android.os.Binder; import android.os.Handler; import android.os.Messenger; import android.os.HandlerThread; import android.os.IBinder; import android.os.INetworkManagementService; import android.os.Message; import android.os.RemoteException; import android.os.ServiceManager; import android.os.SystemProperties; import android.os.WorkSource; import android.provider.Settings; import android.text.TextUtils; Loading Loading @@ -111,6 +115,20 @@ public class WifiService extends IWifiManager.Stub { private final IBatteryStats mBatteryStats; private boolean mEnableTrafficStatsPoll = false; private int mTrafficStatsPollToken = 0; private long mTxPkts; private long mRxPkts; /* Tracks last reported data activity */ private int mDataActivity; private String mInterfaceName; /** * Interval in milliseconds between polling for traffic * statistics */ private static final int POLL_TRAFFIC_STATS_INTERVAL_MSECS = 1000; /** * See {@link Settings.Secure#WIFI_IDLE_MS}. This is the default value if a * Settings.Secure value is not present. This timeout value is chosen as Loading @@ -123,6 +141,9 @@ public class WifiService extends IWifiManager.Stub { private static final String ACTION_DEVICE_IDLE = "com.android.server.WifiManager.action.DEVICE_IDLE"; private static final int CMD_ENABLE_TRAFFIC_STATS_POLL = 1; private static final int CMD_TRAFFIC_STATS_POLL = 2; private boolean mIsReceiverRegistered = false; Loading Loading @@ -180,18 +201,20 @@ public class WifiService extends IWifiManager.Stub { /** * Asynchronous channel to WifiStateMachine */ private AsyncChannel mChannel; private AsyncChannel mWifiStateMachineChannel; /** * TODO: Possibly change WifiService into an AsyncService. * Clients receiving asynchronous messages */ private class WifiServiceHandler extends Handler { private AsyncChannel mWshChannel; private List<AsyncChannel> mClients = new ArrayList<AsyncChannel>(); WifiServiceHandler(android.os.Looper looper, Context context) { /** * Handles client connections */ private class AsyncServiceHandler extends Handler { AsyncServiceHandler(android.os.Looper looper) { super(looper); mWshChannel = new AsyncChannel(); mWshChannel.connect(context, this, mWifiStateMachine.getHandler()); } @Override Loading @@ -199,11 +222,33 @@ public class WifiService extends IWifiManager.Stub { switch (msg.what) { case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED: { if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) { mChannel = mWshChannel; Slog.d(TAG, "New client listening to asynchronous messages"); mClients.add((AsyncChannel) msg.obj); } else { Slog.d(TAG, "WifiServicehandler.handleMessage could not connect error=" + msg.arg1); mChannel = null; Slog.e(TAG, "Client connection failure, error=" + msg.arg1); } break; } case AsyncChannel.CMD_CHANNEL_FULL_CONNECTION: { AsyncChannel ac = new AsyncChannel(); ac.connect(mContext, this, msg.replyTo); break; } case CMD_ENABLE_TRAFFIC_STATS_POLL: { mEnableTrafficStatsPoll = (msg.arg1 == 1); mTrafficStatsPollToken++; if (mEnableTrafficStatsPoll) { notifyOnDataActivity(); sendMessageDelayed(Message.obtain(this, CMD_TRAFFIC_STATS_POLL, mTrafficStatsPollToken, 0), POLL_TRAFFIC_STATS_INTERVAL_MSECS); } break; } case CMD_TRAFFIC_STATS_POLL: { if (msg.arg1 == mTrafficStatsPollToken) { notifyOnDataActivity(); sendMessageDelayed(Message.obtain(this, CMD_TRAFFIC_STATS_POLL, mTrafficStatsPollToken, 0), POLL_TRAFFIC_STATS_INTERVAL_MSECS); } break; } Loading @@ -214,7 +259,40 @@ public class WifiService extends IWifiManager.Stub { } } } WifiServiceHandler mHandler; private AsyncServiceHandler mAsyncServiceHandler; /** * Handles interaction with WifiStateMachine */ private class WifiStateMachineHandler extends Handler { private AsyncChannel mWsmChannel; WifiStateMachineHandler(android.os.Looper looper) { super(looper); mWsmChannel = new AsyncChannel(); mWsmChannel.connect(mContext, this, mWifiStateMachine.getHandler()); } @Override public void handleMessage(Message msg) { switch (msg.what) { case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED: { if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) { mWifiStateMachineChannel = mWsmChannel; } else { Slog.e(TAG, "WifiStateMachine connection failure, error=" + msg.arg1); mWifiStateMachineChannel = null; } break; } default: { Slog.d(TAG, "WifiStateMachineHandler.handleMessage ignoring msg=" + msg); break; } } } } WifiStateMachineHandler mWifiStateMachineHandler; /** * Temporary for computing UIDS that are responsible for starting WIFI. Loading @@ -224,7 +302,10 @@ public class WifiService extends IWifiManager.Stub { WifiService(Context context) { mContext = context; mWifiStateMachine = new WifiStateMachine(mContext); mInterfaceName = SystemProperties.get("wifi.interface", "wlan0"); mWifiStateMachine = new WifiStateMachine(mContext, mInterfaceName); mWifiStateMachine.enableRssiPolling(true); mBatteryStats = BatteryStatsService.getService(); Loading @@ -232,10 +313,6 @@ public class WifiService extends IWifiManager.Stub { Intent idleIntent = new Intent(ACTION_DEVICE_IDLE, null); mIdleIntent = PendingIntent.getBroadcast(mContext, IDLE_REQUEST, idleIntent, 0); HandlerThread wifiThread = new HandlerThread("WifiService"); wifiThread.start(); mHandler = new WifiServiceHandler(wifiThread.getLooper(), context); mContext.registerReceiver( new BroadcastReceiver() { @Override Loading Loading @@ -271,6 +348,7 @@ public class WifiService extends IWifiManager.Stub { switch(mNetworkInfo.getDetailedState()) { case CONNECTED: case DISCONNECTED: evaluateTrafficStatsPolling(); resetNotification(); break; } Loading @@ -281,6 +359,11 @@ public class WifiService extends IWifiManager.Stub { } }, filter); HandlerThread wifiThread = new HandlerThread("WifiService"); wifiThread.start(); mAsyncServiceHandler = new AsyncServiceHandler(wifiThread.getLooper()); mWifiStateMachineHandler = new WifiStateMachineHandler(wifiThread.getLooper()); // Setting is in seconds NOTIFICATION_REPEAT_DELAY_MS = Settings.Secure.getInt(context.getContentResolver(), Settings.Secure.WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY, 900) * 1000l; Loading Loading @@ -337,10 +420,10 @@ public class WifiService extends IWifiManager.Stub { */ public boolean pingSupplicant() { enforceAccessPermission(); if (mChannel != null) { return mWifiStateMachine.syncPingSupplicant(mChannel); if (mWifiStateMachineChannel != null) { return mWifiStateMachine.syncPingSupplicant(mWifiStateMachineChannel); } else { Slog.e(TAG, "mChannel is not initialized"); Slog.e(TAG, "mWifiStateMachineChannel is not initialized"); return false; } } Loading Loading @@ -550,10 +633,10 @@ public class WifiService extends IWifiManager.Stub { */ public int addOrUpdateNetwork(WifiConfiguration config) { enforceChangePermission(); if (mChannel != null) { return mWifiStateMachine.syncAddOrUpdateNetwork(mChannel, config); if (mWifiStateMachineChannel != null) { return mWifiStateMachine.syncAddOrUpdateNetwork(mWifiStateMachineChannel, config); } else { Slog.e(TAG, "mChannel is not initialized"); Slog.e(TAG, "mWifiStateMachineChannel is not initialized"); return -1; } } Loading @@ -566,10 +649,10 @@ public class WifiService extends IWifiManager.Stub { */ public boolean removeNetwork(int netId) { enforceChangePermission(); if (mChannel != null) { return mWifiStateMachine.syncRemoveNetwork(mChannel, netId); if (mWifiStateMachineChannel != null) { return mWifiStateMachine.syncRemoveNetwork(mWifiStateMachineChannel, netId); } else { Slog.e(TAG, "mChannel is not initialized"); Slog.e(TAG, "mWifiStateMachineChannel is not initialized"); return false; } } Loading @@ -583,10 +666,11 @@ public class WifiService extends IWifiManager.Stub { */ public boolean enableNetwork(int netId, boolean disableOthers) { enforceChangePermission(); if (mChannel != null) { return mWifiStateMachine.syncEnableNetwork(mChannel, netId, disableOthers); if (mWifiStateMachineChannel != null) { return mWifiStateMachine.syncEnableNetwork(mWifiStateMachineChannel, netId, disableOthers); } else { Slog.e(TAG, "mChannel is not initialized"); Slog.e(TAG, "mWifiStateMachineChannel is not initialized"); return false; } } Loading @@ -599,10 +683,10 @@ public class WifiService extends IWifiManager.Stub { */ public boolean disableNetwork(int netId) { enforceChangePermission(); if (mChannel != null) { return mWifiStateMachine.syncDisableNetwork(mChannel, netId); if (mWifiStateMachineChannel != null) { return mWifiStateMachine.syncDisableNetwork(mWifiStateMachineChannel, netId); } else { Slog.e(TAG, "mChannel is not initialized"); Slog.e(TAG, "mWifiStateMachineChannel is not initialized"); return false; } } Loading Loading @@ -639,10 +723,10 @@ public class WifiService extends IWifiManager.Stub { public boolean saveConfiguration() { boolean result = true; enforceChangePermission(); if (mChannel != null) { return mWifiStateMachine.syncSaveConfig(mChannel); if (mWifiStateMachineChannel != null) { return mWifiStateMachine.syncSaveConfig(mWifiStateMachineChannel); } else { Slog.e(TAG, "mChannel is not initialized"); Slog.e(TAG, "mWifiStateMachineChannel is not initialized"); return false; } } Loading Loading @@ -776,14 +860,23 @@ public class WifiService extends IWifiManager.Stub { public WpsResult startWps(WpsConfiguration config) { enforceChangePermission(); if (mChannel != null) { return mWifiStateMachine.startWps(mChannel, config); if (mWifiStateMachineChannel != null) { return mWifiStateMachine.startWps(mWifiStateMachineChannel, config); } else { Slog.e(TAG, "mChannel is not initialized"); Slog.e(TAG, "mWifiStateMachineChannel is not initialized"); return new WpsResult(WpsResult.Status.FAILURE); } } /** * Get a reference to handler. This is used by a client to establish * an AsyncChannel communication with WifiService */ public Messenger getMessenger() { enforceAccessPermission(); return new Messenger(mAsyncServiceHandler); } private final BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { Loading @@ -805,6 +898,7 @@ public class WifiService extends IWifiManager.Stub { // Once the screen is on, we are not keeping WIFI running // because of any locks so clear that tracking immediately. reportStartWorkSource(); evaluateTrafficStatsPolling(); mWifiStateMachine.enableRssiPolling(true); mWifiStateMachine.enableAllNetworks(); updateWifiState(); Loading @@ -813,6 +907,7 @@ public class WifiService extends IWifiManager.Stub { Slog.d(TAG, "ACTION_SCREEN_OFF"); } mScreenOff = true; evaluateTrafficStatsPolling(); mWifiStateMachine.enableRssiPolling(false); /* * Set a timer to put Wi-Fi to sleep, but only if the screen is off Loading Loading @@ -1416,6 +1511,48 @@ public class WifiService extends IWifiManager.Stub { } } /** * Evaluate if traffic stats polling is needed based on * connection and screen on status */ private void evaluateTrafficStatsPolling() { Message msg; if (mNetworkInfo.getDetailedState() == DetailedState.CONNECTED && !mScreenOff) { msg = Message.obtain(mAsyncServiceHandler, CMD_ENABLE_TRAFFIC_STATS_POLL, 1, 0); } else { msg = Message.obtain(mAsyncServiceHandler, CMD_ENABLE_TRAFFIC_STATS_POLL, 0, 0); } msg.sendToTarget(); } private void notifyOnDataActivity() { long sent, received; long preTxPkts = mTxPkts, preRxPkts = mRxPkts; int dataActivity = WifiManager.DATA_ACTIVITY_NONE; mTxPkts = TrafficStats.getTxPackets(mInterfaceName); mRxPkts = TrafficStats.getRxPackets(mInterfaceName); if (preTxPkts > 0 || preRxPkts > 0) { sent = mTxPkts - preTxPkts; received = mRxPkts - preRxPkts; if (sent > 0) { dataActivity |= WifiManager.DATA_ACTIVITY_OUT; } if (received > 0) { dataActivity |= WifiManager.DATA_ACTIVITY_IN; } if (dataActivity != mDataActivity && !mScreenOff) { mDataActivity = dataActivity; for (AsyncChannel client : mClients) { client.sendMessage(WifiManager.DATA_ACTIVITY_NOTIFICATION, mDataActivity); } } } } private void checkAndSetNotification() { // If we shouldn't place a notification on available networks, then // don't bother doing any of the following Loading wifi/java/android/net/wifi/IWifiManager.aidl +11 −8 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ import android.net.wifi.WpsResult; import android.net.wifi.ScanResult; import android.net.DhcpInfo; import android.os.Messenger; import android.os.WorkSource; /** Loading Loading @@ -111,5 +112,7 @@ interface IWifiManager void forgetNetwork(int networkId); WpsResult startWps(in WpsConfiguration config); Messenger getMessenger(); } Loading
core/java/android/net/TrafficStats.java +37 −0 Original line number Diff line number Diff line Loading @@ -68,6 +68,43 @@ public class TrafficStats { */ public static native long getMobileRxBytes(); /** * Get the total number of packets transmitted through the specified interface. * * @return number of packets. If the statistics are not supported by this interface, * {@link #UNSUPPORTED} will be returned. * @hide */ public static native long getTxPackets(String iface); /** * Get the total number of packets received through the specified interface. * * @return number of packets. If the statistics are not supported by this interface, * {@link #UNSUPPORTED} will be returned. * @hide */ public static native long getRxPackets(String iface); /** * Get the total number of bytes transmitted through the specified interface. * * @return number of bytes. If the statistics are not supported by this interface, * {@link #UNSUPPORTED} will be returned. * @hide */ public static native long getTxBytes(String iface); /** * Get the total number of bytes received through the specified interface. * * @return number of bytes. If the statistics are not supported by this interface, * {@link #UNSUPPORTED} will be returned. * @hide */ public static native long getRxBytes(String iface); /** * Get the total number of packets sent through all network interfaces. * Loading
core/jni/android_net_TrafficStats.cpp +31 −0 Original line number Diff line number Diff line Loading @@ -130,6 +130,33 @@ static jlong getMobileRxBytes(JNIEnv* env, jobject clazz) { "/sys/class/net/ppp0/statistics/rx_bytes"); } static jlong getData(JNIEnv* env, char *what, jstring interface) { char filename[80]; jboolean isCopy; const char *interfaceStr = env->GetStringUTFChars(interface, &isCopy); snprintf(filename, sizeof(filename), "/sys/class/net/%s/statistics/%s", interfaceStr, what); return readNumber(filename); } static jlong getTxPackets(JNIEnv* env, jobject clazz, jstring interface) { return getData(env, "tx_packets", interface); } static jlong getRxPackets(JNIEnv* env, jobject clazz, jstring interface) { return getData(env, "rx_packets", interface); } static jlong getTxBytes(JNIEnv* env, jobject clazz, jstring interface) { return getData(env, "tx_bytes", interface); } static jlong getRxBytes(JNIEnv* env, jobject clazz, jstring interface) { return getData(env, "rx_bytes", interface); } // Total stats are read less often, so we're willing to put up // with listing the directory and concatenating filenames. Loading Loading @@ -288,6 +315,10 @@ static JNINativeMethod gMethods[] = { {"getMobileRxPackets", "()J", (void*) getMobileRxPackets}, {"getMobileTxBytes", "()J", (void*) getMobileTxBytes}, {"getMobileRxBytes", "()J", (void*) getMobileRxBytes}, {"getTxPackets", "(Ljava/lang/String;)J", (void*) getTxPackets}, {"getRxPackets", "(Ljava/lang/String;)J", (void*) getRxPackets}, {"getTxBytes", "(Ljava/lang/String;)J", (void*) getTxBytes}, {"getRxBytes", "(Ljava/lang/String;)J", (void*) getRxBytes}, {"getTotalTxPackets", "()J", (void*) getTotalTxPackets}, {"getTotalRxPackets", "()J", (void*) getTotalRxPackets}, {"getTotalTxBytes", "()J", (void*) getTotalTxBytes}, Loading
packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java +53 −0 Original line number Diff line number Diff line Loading @@ -33,6 +33,11 @@ import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiInfo; import android.net.wifi.WifiManager; import android.os.Binder; import android.os.Handler; import android.os.HandlerThread; import android.os.Looper; import android.os.Message; import android.os.Messenger; import android.os.RemoteException; import android.provider.Settings; import android.provider.Telephony; Loading @@ -50,6 +55,7 @@ import com.android.internal.telephony.IccCard; import com.android.internal.telephony.TelephonyIntents; import com.android.internal.telephony.cdma.EriInfo; import com.android.server.am.BatteryStatsService; import com.android.internal.util.AsyncChannel; import com.android.systemui.R; Loading Loading @@ -82,6 +88,7 @@ public class NetworkController extends BroadcastReceiver { // wifi final WifiManager mWifiManager; AsyncChannel mWifiChannel; boolean mWifiEnabled, mWifiConnected; int mWifiLevel; String mWifiSsid; Loading Loading @@ -140,6 +147,14 @@ public class NetworkController extends BroadcastReceiver { // wifi mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); HandlerThread handlerThread = new HandlerThread("WifiServiceThread"); handlerThread.start(); Handler handler = new WifiHandler(handlerThread.getLooper()); mWifiChannel = new AsyncChannel(); Messenger wifiMessenger = mWifiManager.getMessenger(); if (wifiMessenger != null) { mWifiChannel.connect(mContext, handler, wifiMessenger); } // broadcasts IntentFilter filter = new IntentFilter(); Loading Loading @@ -584,6 +599,44 @@ public class NetworkController extends BroadcastReceiver { // ===== Wifi =================================================================== class WifiHandler extends Handler { WifiHandler(Looper looper) { super(looper); } @Override public void handleMessage(Message msg) { switch (msg.what) { case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED: if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) { mWifiChannel.sendMessage(Message.obtain(this, AsyncChannel.CMD_CHANNEL_FULL_CONNECTION)); } else { Slog.e(TAG, "Failed to connect to wifi"); } break; case WifiManager.DATA_ACTIVITY_NOTIFICATION: int dataActivity = msg.arg1; /* TODO: update icons based on data activity */ switch (dataActivity) { case WifiManager.DATA_ACTIVITY_IN: break; case WifiManager.DATA_ACTIVITY_OUT: break; case WifiManager.DATA_ACTIVITY_INOUT: break; case WifiManager.DATA_ACTIVITY_NONE: break; } break; default: //Ignore break; } } } private void updateWifiState(Intent intent) { final String action = intent.getAction(); if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) { Loading
services/java/com/android/server/WifiService.java +175 −38 Original line number Diff line number Diff line Loading @@ -42,14 +42,18 @@ import android.net.ConnectivityManager; import android.net.DhcpInfo; import android.net.NetworkInfo; import android.net.NetworkInfo.State; import android.net.NetworkInfo.DetailedState; import android.net.TrafficStats; import android.os.Binder; import android.os.Handler; import android.os.Messenger; import android.os.HandlerThread; import android.os.IBinder; import android.os.INetworkManagementService; import android.os.Message; import android.os.RemoteException; import android.os.ServiceManager; import android.os.SystemProperties; import android.os.WorkSource; import android.provider.Settings; import android.text.TextUtils; Loading Loading @@ -111,6 +115,20 @@ public class WifiService extends IWifiManager.Stub { private final IBatteryStats mBatteryStats; private boolean mEnableTrafficStatsPoll = false; private int mTrafficStatsPollToken = 0; private long mTxPkts; private long mRxPkts; /* Tracks last reported data activity */ private int mDataActivity; private String mInterfaceName; /** * Interval in milliseconds between polling for traffic * statistics */ private static final int POLL_TRAFFIC_STATS_INTERVAL_MSECS = 1000; /** * See {@link Settings.Secure#WIFI_IDLE_MS}. This is the default value if a * Settings.Secure value is not present. This timeout value is chosen as Loading @@ -123,6 +141,9 @@ public class WifiService extends IWifiManager.Stub { private static final String ACTION_DEVICE_IDLE = "com.android.server.WifiManager.action.DEVICE_IDLE"; private static final int CMD_ENABLE_TRAFFIC_STATS_POLL = 1; private static final int CMD_TRAFFIC_STATS_POLL = 2; private boolean mIsReceiverRegistered = false; Loading Loading @@ -180,18 +201,20 @@ public class WifiService extends IWifiManager.Stub { /** * Asynchronous channel to WifiStateMachine */ private AsyncChannel mChannel; private AsyncChannel mWifiStateMachineChannel; /** * TODO: Possibly change WifiService into an AsyncService. * Clients receiving asynchronous messages */ private class WifiServiceHandler extends Handler { private AsyncChannel mWshChannel; private List<AsyncChannel> mClients = new ArrayList<AsyncChannel>(); WifiServiceHandler(android.os.Looper looper, Context context) { /** * Handles client connections */ private class AsyncServiceHandler extends Handler { AsyncServiceHandler(android.os.Looper looper) { super(looper); mWshChannel = new AsyncChannel(); mWshChannel.connect(context, this, mWifiStateMachine.getHandler()); } @Override Loading @@ -199,11 +222,33 @@ public class WifiService extends IWifiManager.Stub { switch (msg.what) { case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED: { if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) { mChannel = mWshChannel; Slog.d(TAG, "New client listening to asynchronous messages"); mClients.add((AsyncChannel) msg.obj); } else { Slog.d(TAG, "WifiServicehandler.handleMessage could not connect error=" + msg.arg1); mChannel = null; Slog.e(TAG, "Client connection failure, error=" + msg.arg1); } break; } case AsyncChannel.CMD_CHANNEL_FULL_CONNECTION: { AsyncChannel ac = new AsyncChannel(); ac.connect(mContext, this, msg.replyTo); break; } case CMD_ENABLE_TRAFFIC_STATS_POLL: { mEnableTrafficStatsPoll = (msg.arg1 == 1); mTrafficStatsPollToken++; if (mEnableTrafficStatsPoll) { notifyOnDataActivity(); sendMessageDelayed(Message.obtain(this, CMD_TRAFFIC_STATS_POLL, mTrafficStatsPollToken, 0), POLL_TRAFFIC_STATS_INTERVAL_MSECS); } break; } case CMD_TRAFFIC_STATS_POLL: { if (msg.arg1 == mTrafficStatsPollToken) { notifyOnDataActivity(); sendMessageDelayed(Message.obtain(this, CMD_TRAFFIC_STATS_POLL, mTrafficStatsPollToken, 0), POLL_TRAFFIC_STATS_INTERVAL_MSECS); } break; } Loading @@ -214,7 +259,40 @@ public class WifiService extends IWifiManager.Stub { } } } WifiServiceHandler mHandler; private AsyncServiceHandler mAsyncServiceHandler; /** * Handles interaction with WifiStateMachine */ private class WifiStateMachineHandler extends Handler { private AsyncChannel mWsmChannel; WifiStateMachineHandler(android.os.Looper looper) { super(looper); mWsmChannel = new AsyncChannel(); mWsmChannel.connect(mContext, this, mWifiStateMachine.getHandler()); } @Override public void handleMessage(Message msg) { switch (msg.what) { case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED: { if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) { mWifiStateMachineChannel = mWsmChannel; } else { Slog.e(TAG, "WifiStateMachine connection failure, error=" + msg.arg1); mWifiStateMachineChannel = null; } break; } default: { Slog.d(TAG, "WifiStateMachineHandler.handleMessage ignoring msg=" + msg); break; } } } } WifiStateMachineHandler mWifiStateMachineHandler; /** * Temporary for computing UIDS that are responsible for starting WIFI. Loading @@ -224,7 +302,10 @@ public class WifiService extends IWifiManager.Stub { WifiService(Context context) { mContext = context; mWifiStateMachine = new WifiStateMachine(mContext); mInterfaceName = SystemProperties.get("wifi.interface", "wlan0"); mWifiStateMachine = new WifiStateMachine(mContext, mInterfaceName); mWifiStateMachine.enableRssiPolling(true); mBatteryStats = BatteryStatsService.getService(); Loading @@ -232,10 +313,6 @@ public class WifiService extends IWifiManager.Stub { Intent idleIntent = new Intent(ACTION_DEVICE_IDLE, null); mIdleIntent = PendingIntent.getBroadcast(mContext, IDLE_REQUEST, idleIntent, 0); HandlerThread wifiThread = new HandlerThread("WifiService"); wifiThread.start(); mHandler = new WifiServiceHandler(wifiThread.getLooper(), context); mContext.registerReceiver( new BroadcastReceiver() { @Override Loading Loading @@ -271,6 +348,7 @@ public class WifiService extends IWifiManager.Stub { switch(mNetworkInfo.getDetailedState()) { case CONNECTED: case DISCONNECTED: evaluateTrafficStatsPolling(); resetNotification(); break; } Loading @@ -281,6 +359,11 @@ public class WifiService extends IWifiManager.Stub { } }, filter); HandlerThread wifiThread = new HandlerThread("WifiService"); wifiThread.start(); mAsyncServiceHandler = new AsyncServiceHandler(wifiThread.getLooper()); mWifiStateMachineHandler = new WifiStateMachineHandler(wifiThread.getLooper()); // Setting is in seconds NOTIFICATION_REPEAT_DELAY_MS = Settings.Secure.getInt(context.getContentResolver(), Settings.Secure.WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY, 900) * 1000l; Loading Loading @@ -337,10 +420,10 @@ public class WifiService extends IWifiManager.Stub { */ public boolean pingSupplicant() { enforceAccessPermission(); if (mChannel != null) { return mWifiStateMachine.syncPingSupplicant(mChannel); if (mWifiStateMachineChannel != null) { return mWifiStateMachine.syncPingSupplicant(mWifiStateMachineChannel); } else { Slog.e(TAG, "mChannel is not initialized"); Slog.e(TAG, "mWifiStateMachineChannel is not initialized"); return false; } } Loading Loading @@ -550,10 +633,10 @@ public class WifiService extends IWifiManager.Stub { */ public int addOrUpdateNetwork(WifiConfiguration config) { enforceChangePermission(); if (mChannel != null) { return mWifiStateMachine.syncAddOrUpdateNetwork(mChannel, config); if (mWifiStateMachineChannel != null) { return mWifiStateMachine.syncAddOrUpdateNetwork(mWifiStateMachineChannel, config); } else { Slog.e(TAG, "mChannel is not initialized"); Slog.e(TAG, "mWifiStateMachineChannel is not initialized"); return -1; } } Loading @@ -566,10 +649,10 @@ public class WifiService extends IWifiManager.Stub { */ public boolean removeNetwork(int netId) { enforceChangePermission(); if (mChannel != null) { return mWifiStateMachine.syncRemoveNetwork(mChannel, netId); if (mWifiStateMachineChannel != null) { return mWifiStateMachine.syncRemoveNetwork(mWifiStateMachineChannel, netId); } else { Slog.e(TAG, "mChannel is not initialized"); Slog.e(TAG, "mWifiStateMachineChannel is not initialized"); return false; } } Loading @@ -583,10 +666,11 @@ public class WifiService extends IWifiManager.Stub { */ public boolean enableNetwork(int netId, boolean disableOthers) { enforceChangePermission(); if (mChannel != null) { return mWifiStateMachine.syncEnableNetwork(mChannel, netId, disableOthers); if (mWifiStateMachineChannel != null) { return mWifiStateMachine.syncEnableNetwork(mWifiStateMachineChannel, netId, disableOthers); } else { Slog.e(TAG, "mChannel is not initialized"); Slog.e(TAG, "mWifiStateMachineChannel is not initialized"); return false; } } Loading @@ -599,10 +683,10 @@ public class WifiService extends IWifiManager.Stub { */ public boolean disableNetwork(int netId) { enforceChangePermission(); if (mChannel != null) { return mWifiStateMachine.syncDisableNetwork(mChannel, netId); if (mWifiStateMachineChannel != null) { return mWifiStateMachine.syncDisableNetwork(mWifiStateMachineChannel, netId); } else { Slog.e(TAG, "mChannel is not initialized"); Slog.e(TAG, "mWifiStateMachineChannel is not initialized"); return false; } } Loading Loading @@ -639,10 +723,10 @@ public class WifiService extends IWifiManager.Stub { public boolean saveConfiguration() { boolean result = true; enforceChangePermission(); if (mChannel != null) { return mWifiStateMachine.syncSaveConfig(mChannel); if (mWifiStateMachineChannel != null) { return mWifiStateMachine.syncSaveConfig(mWifiStateMachineChannel); } else { Slog.e(TAG, "mChannel is not initialized"); Slog.e(TAG, "mWifiStateMachineChannel is not initialized"); return false; } } Loading Loading @@ -776,14 +860,23 @@ public class WifiService extends IWifiManager.Stub { public WpsResult startWps(WpsConfiguration config) { enforceChangePermission(); if (mChannel != null) { return mWifiStateMachine.startWps(mChannel, config); if (mWifiStateMachineChannel != null) { return mWifiStateMachine.startWps(mWifiStateMachineChannel, config); } else { Slog.e(TAG, "mChannel is not initialized"); Slog.e(TAG, "mWifiStateMachineChannel is not initialized"); return new WpsResult(WpsResult.Status.FAILURE); } } /** * Get a reference to handler. This is used by a client to establish * an AsyncChannel communication with WifiService */ public Messenger getMessenger() { enforceAccessPermission(); return new Messenger(mAsyncServiceHandler); } private final BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { Loading @@ -805,6 +898,7 @@ public class WifiService extends IWifiManager.Stub { // Once the screen is on, we are not keeping WIFI running // because of any locks so clear that tracking immediately. reportStartWorkSource(); evaluateTrafficStatsPolling(); mWifiStateMachine.enableRssiPolling(true); mWifiStateMachine.enableAllNetworks(); updateWifiState(); Loading @@ -813,6 +907,7 @@ public class WifiService extends IWifiManager.Stub { Slog.d(TAG, "ACTION_SCREEN_OFF"); } mScreenOff = true; evaluateTrafficStatsPolling(); mWifiStateMachine.enableRssiPolling(false); /* * Set a timer to put Wi-Fi to sleep, but only if the screen is off Loading Loading @@ -1416,6 +1511,48 @@ public class WifiService extends IWifiManager.Stub { } } /** * Evaluate if traffic stats polling is needed based on * connection and screen on status */ private void evaluateTrafficStatsPolling() { Message msg; if (mNetworkInfo.getDetailedState() == DetailedState.CONNECTED && !mScreenOff) { msg = Message.obtain(mAsyncServiceHandler, CMD_ENABLE_TRAFFIC_STATS_POLL, 1, 0); } else { msg = Message.obtain(mAsyncServiceHandler, CMD_ENABLE_TRAFFIC_STATS_POLL, 0, 0); } msg.sendToTarget(); } private void notifyOnDataActivity() { long sent, received; long preTxPkts = mTxPkts, preRxPkts = mRxPkts; int dataActivity = WifiManager.DATA_ACTIVITY_NONE; mTxPkts = TrafficStats.getTxPackets(mInterfaceName); mRxPkts = TrafficStats.getRxPackets(mInterfaceName); if (preTxPkts > 0 || preRxPkts > 0) { sent = mTxPkts - preTxPkts; received = mRxPkts - preRxPkts; if (sent > 0) { dataActivity |= WifiManager.DATA_ACTIVITY_OUT; } if (received > 0) { dataActivity |= WifiManager.DATA_ACTIVITY_IN; } if (dataActivity != mDataActivity && !mScreenOff) { mDataActivity = dataActivity; for (AsyncChannel client : mClients) { client.sendMessage(WifiManager.DATA_ACTIVITY_NOTIFICATION, mDataActivity); } } } } private void checkAndSetNotification() { // If we shouldn't place a notification on available networks, then // don't bother doing any of the following Loading
wifi/java/android/net/wifi/IWifiManager.aidl +11 −8 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ import android.net.wifi.WpsResult; import android.net.wifi.ScanResult; import android.net.DhcpInfo; import android.os.Messenger; import android.os.WorkSource; /** Loading Loading @@ -111,5 +112,7 @@ interface IWifiManager void forgetNetwork(int networkId); WpsResult startWps(in WpsConfiguration config); Messenger getMessenger(); }