1155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande/*
2155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * Copyright (C) 2013 The Android Open Source Project
3155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande *
4155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * Licensed under the Apache License, Version 2.0 (the "License");
5155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * you may not use this file except in compliance with the License.
6155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * You may obtain a copy of the License at
7155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande *
8155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande *      http://www.apache.org/licenses/LICENSE-2.0
9155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande *
10155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * Unless required by applicable law or agreed to in writing, software
11155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * distributed under the License is distributed on an "AS IS" BASIS,
12155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * See the License for the specific language governing permissions and
14155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * limitations under the License.
15155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande */
16155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
17155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandepackage com.android.server.wifi;
18155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
198e14dcb9dc38149b4672eceb3fe22287ea4343a0Peter Qiuimport static android.net.NetworkInfo.DetailedState.CONNECTED;
208e14dcb9dc38149b4672eceb3fe22287ea4343a0Peter Qiu
21155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.content.BroadcastReceiver;
22155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.content.Context;
23155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.content.Intent;
24155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.content.IntentFilter;
25155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.net.NetworkInfo;
26155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.net.TrafficStats;
27155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.net.wifi.WifiManager;
28155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.os.Handler;
298e14dcb9dc38149b4672eceb3fe22287ea4343a0Peter Qiuimport android.os.Looper;
30155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.os.Message;
318e14dcb9dc38149b4672eceb3fe22287ea4343a0Peter Qiuimport android.os.Messenger;
328e14dcb9dc38149b4672eceb3fe22287ea4343a0Peter Qiuimport android.os.RemoteException;
33992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalleimport android.util.Log;
34155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
35155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport java.io.FileDescriptor;
36155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport java.io.PrintWriter;
37155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport java.util.ArrayList;
38155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport java.util.List;
39155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport java.util.concurrent.atomic.AtomicBoolean;
40155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
41155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande/* Polls for traffic stats and notifies the clients */
42155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandefinal class WifiTrafficPoller {
43992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle
44992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle    private boolean DBG = false;
45992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle    private boolean VDBG = false;
46992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle
472af03130d7f85823223b8591dc52858d851b301dMitchell Wills    private static final String TAG = "WifiTrafficPoller";
48155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
49155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Interval in milliseconds between polling for traffic
50155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * statistics
51155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
52155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private static final int POLL_TRAFFIC_STATS_INTERVAL_MSECS = 1000;
53155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
54155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private static final int ENABLE_TRAFFIC_STATS_POLL  = 1;
55155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private static final int TRAFFIC_STATS_POLL         = 2;
56155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private static final int ADD_CLIENT                 = 3;
57155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private static final int REMOVE_CLIENT              = 4;
58155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
59155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private boolean mEnableTrafficStatsPoll = false;
60155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private int mTrafficStatsPollToken = 0;
61155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private long mTxPkts;
62155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private long mRxPkts;
63155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Tracks last reported data activity */
64155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private int mDataActivity;
65155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
66155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private final List<Messenger> mClients = new ArrayList<Messenger>();
67155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    // err on the side of updating at boot since screen on broadcast may be missed
68155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    // the first time
69155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private AtomicBoolean mScreenOn = new AtomicBoolean(true);
70155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private final TrafficHandler mTrafficHandler;
71155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private NetworkInfo mNetworkInfo;
72155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private final String mInterface;
73155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
748e14dcb9dc38149b4672eceb3fe22287ea4343a0Peter Qiu    WifiTrafficPoller(Context context, Looper looper, String iface) {
75155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mInterface = iface;
768e14dcb9dc38149b4672eceb3fe22287ea4343a0Peter Qiu        mTrafficHandler = new TrafficHandler(looper);
77155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
78155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        IntentFilter filter = new IntentFilter();
79155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
80155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        filter.addAction(Intent.ACTION_SCREEN_OFF);
81155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        filter.addAction(Intent.ACTION_SCREEN_ON);
82155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
83155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        context.registerReceiver(
84155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                new BroadcastReceiver() {
85155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    @Override
86155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    public void onReceive(Context context, Intent intent) {
87cf731bc480e2e11474b5d820b7d7a04bd0eff176Ningyuan Wang                        if (intent == null) {
88cf731bc480e2e11474b5d820b7d7a04bd0eff176Ningyuan Wang                            return;
89cf731bc480e2e11474b5d820b7d7a04bd0eff176Ningyuan Wang                        }
90cf731bc480e2e11474b5d820b7d7a04bd0eff176Ningyuan Wang                        if (WifiManager.NETWORK_STATE_CHANGED_ACTION.equals(
91cf731bc480e2e11474b5d820b7d7a04bd0eff176Ningyuan Wang                                intent.getAction())) {
92155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            mNetworkInfo = (NetworkInfo) intent.getParcelableExtra(
93155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                                    WifiManager.EXTRA_NETWORK_INFO);
94cf731bc480e2e11474b5d820b7d7a04bd0eff176Ningyuan Wang                        } else if (Intent.ACTION_SCREEN_OFF.equals(intent.getAction())) {
95155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            mScreenOn.set(false);
96cf731bc480e2e11474b5d820b7d7a04bd0eff176Ningyuan Wang                        } else if (Intent.ACTION_SCREEN_ON.equals(intent.getAction())) {
97155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            mScreenOn.set(true);
98155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        }
99155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        evaluateTrafficStatsPolling();
100155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
101155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                }, filter);
102155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
103155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
104155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    void addClient(Messenger client) {
105155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        Message.obtain(mTrafficHandler, ADD_CLIENT, client).sendToTarget();
106155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
107155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
108155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    void removeClient(Messenger client) {
109155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        Message.obtain(mTrafficHandler, REMOVE_CLIENT, client).sendToTarget();
110155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
111155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
112992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle    void enableVerboseLogging(int verbose) {
113992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle        if (verbose > 0 ) {
114992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle            DBG = true;
115992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle        } else {
116992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle            DBG = false;
117992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle        }
118992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle    }
119992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle
120155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private class TrafficHandler extends Handler {
1218e14dcb9dc38149b4672eceb3fe22287ea4343a0Peter Qiu        public TrafficHandler(Looper looper) {
1228e14dcb9dc38149b4672eceb3fe22287ea4343a0Peter Qiu            super(looper);
1238e14dcb9dc38149b4672eceb3fe22287ea4343a0Peter Qiu        }
1248e14dcb9dc38149b4672eceb3fe22287ea4343a0Peter Qiu
125155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public void handleMessage(Message msg) {
126155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            switch (msg.what) {
127155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case ENABLE_TRAFFIC_STATS_POLL:
128155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mEnableTrafficStatsPoll = (msg.arg1 == 1);
129992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle                    if (DBG) {
130992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle                        Log.e(TAG, "ENABLE_TRAFFIC_STATS_POLL "
131992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle                                + mEnableTrafficStatsPoll + " Token "
132992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle                                + Integer.toString(mTrafficStatsPollToken));
133992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle                    }
134155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mTrafficStatsPollToken++;
135155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (mEnableTrafficStatsPoll) {
136155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        notifyOnDataActivity();
137155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        sendMessageDelayed(Message.obtain(this, TRAFFIC_STATS_POLL,
138155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                                mTrafficStatsPollToken, 0), POLL_TRAFFIC_STATS_INTERVAL_MSECS);
139155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
140155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
141155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case TRAFFIC_STATS_POLL:
142992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle                    if (VDBG) {
143992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle                        Log.e(TAG, "TRAFFIC_STATS_POLL "
144992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle                                + mEnableTrafficStatsPoll + " Token "
145992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle                                + Integer.toString(mTrafficStatsPollToken)
146992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle                                + " num clients " + mClients.size());
147992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle                    }
148155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (msg.arg1 == mTrafficStatsPollToken) {
149155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        notifyOnDataActivity();
150155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        sendMessageDelayed(Message.obtain(this, TRAFFIC_STATS_POLL,
151155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                                mTrafficStatsPollToken, 0), POLL_TRAFFIC_STATS_INTERVAL_MSECS);
152155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
153155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
154155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case ADD_CLIENT:
155155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mClients.add((Messenger) msg.obj);
156992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle                    if (DBG) {
157992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle                        Log.e(TAG, "ADD_CLIENT: "
158992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle                                + Integer.toString(mClients.size()));
159992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle                    }
160155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
161155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case REMOVE_CLIENT:
162155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mClients.remove(msg.obj);
163155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
164155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
165155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
166155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
167155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
168155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
169155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void evaluateTrafficStatsPolling() {
170155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        Message msg;
171155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (mNetworkInfo == null) return;
172155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (mNetworkInfo.getDetailedState() == CONNECTED && mScreenOn.get()) {
173155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            msg = Message.obtain(mTrafficHandler,
174155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    ENABLE_TRAFFIC_STATS_POLL, 1, 0);
175155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        } else {
176155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            msg = Message.obtain(mTrafficHandler,
177155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    ENABLE_TRAFFIC_STATS_POLL, 0, 0);
178155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
179155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        msg.sendToTarget();
180155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
181155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
182155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void notifyOnDataActivity() {
183155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        long sent, received;
184155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        long preTxPkts = mTxPkts, preRxPkts = mRxPkts;
185155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        int dataActivity = WifiManager.DATA_ACTIVITY_NONE;
186155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
187155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mTxPkts = TrafficStats.getTxPackets(mInterface);
188155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mRxPkts = TrafficStats.getRxPackets(mInterface);
189155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
190992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle        if (VDBG) {
191992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle            Log.e(TAG, " packet count Tx="
192992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle                    + Long.toString(mTxPkts)
193992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle                    + " Rx="
194992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle                    + Long.toString(mRxPkts));
195992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle        }
196992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle
197155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (preTxPkts > 0 || preRxPkts > 0) {
198155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            sent = mTxPkts - preTxPkts;
199155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            received = mRxPkts - preRxPkts;
200155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (sent > 0) {
201155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                dataActivity |= WifiManager.DATA_ACTIVITY_OUT;
202155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
203155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (received > 0) {
204155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                dataActivity |= WifiManager.DATA_ACTIVITY_IN;
205155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
206155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
207155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (dataActivity != mDataActivity && mScreenOn.get()) {
208155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                mDataActivity = dataActivity;
209992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle                if (DBG) {
210992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle                    Log.e(TAG, "notifying of data activity "
211992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle                            + Integer.toString(mDataActivity));
212992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle                }
213155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                for (Messenger client : mClients) {
214155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    Message msg = Message.obtain();
215155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    msg.what = WifiManager.DATA_ACTIVITY_NOTIFICATION;
216155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    msg.arg1 = mDataActivity;
217155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    try {
218155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        client.send(msg);
219155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } catch (RemoteException e) {
220155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        // Failed to reach, skip
221155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        // Client removal is handled in WifiService
222155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
223155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                }
224155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
225155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
226155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
227155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
228155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
229155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        pw.println("mEnableTrafficStatsPoll " + mEnableTrafficStatsPoll);
230155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        pw.println("mTrafficStatsPollToken " + mTrafficStatsPollToken);
231155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        pw.println("mTxPkts " + mTxPkts);
232155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        pw.println("mRxPkts " + mRxPkts);
233155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        pw.println("mDataActivity " + mDataActivity);
234155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
235155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
236155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande}
237