1/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.wifi;
18
19import static org.junit.Assert.assertTrue;
20import static org.mockito.Mockito.any;
21import static org.mockito.Mockito.anyInt;
22import static org.mockito.Mockito.anyString;
23import static org.mockito.Mockito.doAnswer;
24import static org.mockito.Mockito.mock;
25
26import android.os.Handler;
27import android.os.Message;
28import android.util.SparseArray;
29
30import com.android.server.wifi.MockAnswerUtil.AnswerWithArguments;
31
32import java.lang.reflect.Field;
33import java.util.HashMap;
34import java.util.Map;
35
36/**
37 * Creates a WifiMonitor and installs it as the current WifiMonitor instance
38 * WARNING: This does not perfectly mock the behavior of WifiMonitor at the moment
39 *          ex. startMoniroting does nothing and will not send a connection/disconnection event
40 */
41public class MockWifiMonitor {
42    private final WifiMonitor mWifiMonitor;
43
44    public MockWifiMonitor() throws Exception {
45        mWifiMonitor = mock(WifiMonitor.class);
46
47        Field field = WifiMonitor.class.getDeclaredField("sWifiMonitor");
48        field.setAccessible(true);
49        field.set(null, mWifiMonitor);
50
51        doAnswer(new RegisterHandlerAnswer())
52                .when(mWifiMonitor).registerHandler(anyString(), anyInt(), any(Handler.class));
53
54    }
55
56    private final Map<String, SparseArray<Handler>> mHandlerMap = new HashMap<>();
57    private class RegisterHandlerAnswer extends AnswerWithArguments {
58        public void answer(String iface, int what, Handler handler) {
59            SparseArray<Handler> ifaceHandlers = mHandlerMap.get(iface);
60            if (ifaceHandlers == null) {
61                ifaceHandlers = new SparseArray<>();
62                mHandlerMap.put(iface, ifaceHandlers);
63            }
64            ifaceHandlers.put(what, handler);
65        }
66    }
67
68    /**
69     * Send a message and assert that it was dispatched to a handler
70     */
71    public void sendMessage(String iface, int what) {
72        sendMessage(iface, Message.obtain(null, what));
73    }
74    public void sendMessage(String iface, Message message) {
75        SparseArray<Handler> ifaceHandlers = mHandlerMap.get(iface);
76        if (ifaceHandlers != null) {
77            assertTrue("No handler for iface=" + iface + ",what=" + message.what,
78                    sendMessage(ifaceHandlers, message));
79        } else {
80            boolean sent = false;
81            for (Map.Entry<String, SparseArray<Handler>> entry : mHandlerMap.entrySet()) {
82                if (sendMessage(entry.getValue(), Message.obtain(message))) {
83                    sent = true;
84                }
85            }
86            assertTrue("No handler for message with nonexistant iface, iface=" + iface
87                    + ",what=" + message.what, sent);
88        }
89    }
90    private boolean sendMessage(SparseArray<Handler> ifaceHandlers, Message message) {
91        Handler handler = ifaceHandlers.get(message.what);
92        if (handler != null) {
93            message.setTarget(handler);
94            message.sendToTarget();
95            return true;
96        }
97        return false;
98    }
99
100}
101