blob: 40281f8ba2999a06a71da4b0857cb3b65a38f1ce [file] [log] [blame]
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.server.wifi;
import static org.junit.Assert.assertEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.net.NetworkInfo;
import android.net.wifi.WifiManager;
import android.os.Handler;
import android.os.Message;
import android.os.Messenger;
import android.os.test.TestLooper;
import android.support.test.filters.SmallTest;
/**
* Unit tests for {@link com.android.server.wifi.WifiTrafficPoller}.
*/
@SmallTest
public class WifiTrafficPollerTest {
public static final String TAG = "WifiTrafficPollerTest";
private TestLooper mLooper;
private Handler mHandler;
private WifiTrafficPoller mWifiTrafficPoller;
private BroadcastReceiver mReceiver;
private Intent mIntent;
private Messenger mMessenger;
private final static String IFNAME = "wlan0";
private final static long DEFAULT_PACKET_COUNT = 10;
private final static long TX_PACKET_COUNT = 40;
private final static long RX_PACKET_COUNT = 50;
final ArgumentCaptor<Message> mMessageCaptor = ArgumentCaptor.forClass(Message.class);
final ArgumentCaptor<BroadcastReceiver> mBroadcastReceiverCaptor =
ArgumentCaptor.forClass(BroadcastReceiver.class);
@Mock Context mContext;
@Mock WifiNative mWifiNative;
@Mock NetworkInfo mNetworkInfo;
/**
* Called before each test
*/
@Before
public void setUp() throws Exception {
// Ensure looper exists
mLooper = new TestLooper();
mHandler = spy(new Handler(mLooper.getLooper()));
mMessenger = new Messenger(mHandler);
MockitoAnnotations.initMocks(this);
when(mWifiNative.getTxPackets(any(String.class))).thenReturn(DEFAULT_PACKET_COUNT,
TX_PACKET_COUNT);
when(mWifiNative.getRxPackets(any(String.class))).thenReturn(DEFAULT_PACKET_COUNT,
RX_PACKET_COUNT);
when(mWifiNative.getClientInterfaceName()).thenReturn(IFNAME);
mWifiTrafficPoller = new WifiTrafficPoller(mContext, mLooper.getLooper(), mWifiNative);
// Verify the constructor registers broadcast receiver with the collect intent filters.
verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(), argThat(
intentFilter -> intentFilter.hasAction(WifiManager.NETWORK_STATE_CHANGED_ACTION) &&
intentFilter.hasAction(Intent.ACTION_SCREEN_ON) &&
intentFilter.hasAction(Intent.ACTION_SCREEN_OFF)));
mReceiver = mBroadcastReceiverCaptor.getValue();
// For the fist call, this is required to set the DEFAULT_PACKET_COUNT to mTxPkts and
// mRxPkts in WifiTrafficPoll Object.
triggerForUpdatedInformationOfData(Intent.ACTION_SCREEN_ON,
NetworkInfo.DetailedState.CONNECTED);
}
private void registerClient() {
// Register Client to verify that Tx/RX packet message is properly received.
mWifiTrafficPoller.addClient(mMessenger);
mLooper.dispatchAll();
}
private void triggerForUpdatedInformationOfData(String actionScreen,
NetworkInfo.DetailedState networkState) {
when(mNetworkInfo.getDetailedState()).thenReturn(NetworkInfo.DetailedState.DISCONNECTED);
mIntent = new Intent(actionScreen);
mReceiver.onReceive(mContext, mIntent);
mLooper.dispatchAll();
when(mNetworkInfo.getDetailedState()).thenReturn(networkState);
mIntent = new Intent(WifiManager.NETWORK_STATE_CHANGED_ACTION);
mIntent.putExtra(WifiManager.EXTRA_NETWORK_INFO, mNetworkInfo);
mReceiver.onReceive(mContext, mIntent);
mLooper.dispatchAll();
}
/**
* Verify that StartTrafficStatsPolling should not happen in case a network is not connected
*/
@Test
public void testNotStartTrafficStatsPollingWithDisconnected() {
registerClient();
triggerForUpdatedInformationOfData(Intent.ACTION_SCREEN_ON,
NetworkInfo.DetailedState.DISCONNECTED);
// Client should not get any message when the network is disconnected
verify(mHandler, never()).handleMessage(any(Message.class));
}
/**
* Verify that StartTrafficStatsPolling should happen in case screen is on and rx/tx packets are
* available.
*/
@Test
public void testStartTrafficStatsPollingWithScreenOn() {
registerClient();
triggerForUpdatedInformationOfData(Intent.ACTION_SCREEN_ON,
NetworkInfo.DetailedState.CONNECTED);
// Client should get the DATA_ACTIVITY_NOTIFICATION
verify(mHandler).handleMessage(mMessageCaptor.capture());
assertEquals(WifiManager.DATA_ACTIVITY_NOTIFICATION, mMessageCaptor.getValue().what);
}
/**
* Verify that StartTrafficStatsPolling should not happen in case screen is off.
*/
@Test
public void testNotStartTrafficStatsPollingWithScreenOff() {
registerClient();
triggerForUpdatedInformationOfData(Intent.ACTION_SCREEN_OFF,
NetworkInfo.DetailedState.CONNECTED);
verify(mNetworkInfo, atLeastOnce()).getDetailedState();
mLooper.dispatchAll();
// Client should not get any message when the screen is off
verify(mHandler, never()).handleMessage(any(Message.class));
}
/**
* Verify that remove client message should be handled
*/
@Test
public void testRemoveClient() {
registerClient();
mWifiTrafficPoller.removeClient(mMessenger);
mLooper.dispatchAll();
triggerForUpdatedInformationOfData(Intent.ACTION_SCREEN_ON,
NetworkInfo.DetailedState.CONNECTED);
// Client should not get any message after the client is removed.
verify(mHandler, never()).handleMessage(any(Message.class));
}
}