1/* 2 * Copyright (C) 2016 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.assertEquals; 20 21import android.os.Handler; 22import android.os.Looper; 23import android.os.Message; 24import android.os.Messenger; 25import android.util.Log; 26 27import com.android.internal.util.AsyncChannel; 28 29 30/** 31 * Provides an AsyncChannel interface that implements the connection initiating half of a 32 * bidirectional channel as described in {@link com.android.internal.util.AsyncChannel}. 33 */ 34public class BidirectionalAsyncChannel { 35 private static final String TAG = "BidirectionalAsyncChannel"; 36 37 private AsyncChannel mChannel; 38 public enum ChannelState { DISCONNECTED, HALF_CONNECTED, CONNECTED, FAILURE }; 39 private ChannelState mState = ChannelState.DISCONNECTED; 40 41 public void assertConnected() { 42 assertEquals("AsyncChannel was not fully connected", ChannelState.CONNECTED, mState); 43 } 44 45 public void connect(final Looper looper, final Messenger messenger, 46 final Handler incomingMessageHandler) { 47 assertEquals("AsyncChannel must be disconnected to connect", 48 ChannelState.DISCONNECTED, mState); 49 mChannel = new AsyncChannel(); 50 Handler rawMessageHandler = new Handler(looper) { 51 @Override 52 public void handleMessage(Message msg) { 53 switch (msg.what) { 54 case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED: 55 if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) { 56 Log.d(TAG, "Successfully half connected " + this); 57 mChannel.sendMessage(AsyncChannel.CMD_CHANNEL_FULL_CONNECTION); 58 mState = ChannelState.HALF_CONNECTED; 59 } else { 60 Log.d(TAG, "Failed to connect channel " + this); 61 mState = ChannelState.FAILURE; 62 mChannel = null; 63 } 64 break; 65 case AsyncChannel.CMD_CHANNEL_FULLY_CONNECTED: 66 mState = ChannelState.CONNECTED; 67 Log.d(TAG, "Channel fully connected" + this); 68 break; 69 case AsyncChannel.CMD_CHANNEL_DISCONNECTED: 70 mState = ChannelState.DISCONNECTED; 71 mChannel = null; 72 Log.d(TAG, "Channel disconnected" + this); 73 break; 74 default: 75 incomingMessageHandler.handleMessage(msg); 76 break; 77 } 78 } 79 }; 80 mChannel.connect(null, rawMessageHandler, messenger); 81 } 82 83 public void disconnect() { 84 assertEquals("AsyncChannel must be connected to disconnect", 85 ChannelState.CONNECTED, mState); 86 mChannel.sendMessage(AsyncChannel.CMD_CHANNEL_DISCONNECT); 87 mState = ChannelState.DISCONNECTED; 88 mChannel = null; 89 } 90 91 public void sendMessage(Message msg) { 92 assertEquals("AsyncChannel must be connected to send messages", 93 ChannelState.CONNECTED, mState); 94 mChannel.sendMessage(msg); 95 } 96} 97