194bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills/*
294bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills * Copyright (C) 2016 The Android Open Source Project
394bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills *
494bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills * Licensed under the Apache License, Version 2.0 (the "License");
594bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills * you may not use this file except in compliance with the License.
694bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills * You may obtain a copy of the License at
794bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills *
894bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills *      http://www.apache.org/licenses/LICENSE-2.0
994bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills *
1094bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills * Unless required by applicable law or agreed to in writing, software
1194bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills * distributed under the License is distributed on an "AS IS" BASIS,
1294bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1394bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills * See the License for the specific language governing permissions and
1494bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills * limitations under the License
1594bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills */
1694bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills
1794bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Willspackage com.android.server.wifi;
1894bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills
1994bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Willsimport static org.junit.Assert.assertEquals;
2094bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills
2194bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Willsimport android.os.Handler;
2294bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Willsimport android.os.Looper;
2394bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Willsimport android.os.Message;
2494bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Willsimport android.os.Messenger;
2594bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Willsimport android.util.Log;
2694bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills
2794bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Willsimport com.android.internal.util.AsyncChannel;
2894bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills
2994bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills
3094bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills/**
3194bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills * Provides an AsyncChannel interface that implements the connection initiating half of a
3294bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills * bidirectional channel as described in {@link com.android.internal.util.AsyncChannel}.
3394bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills */
3494bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Willspublic class BidirectionalAsyncChannel {
3594bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    private static final String TAG = "BidirectionalAsyncChannel";
3694bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills
3794bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    private AsyncChannel mChannel;
3894bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    public enum ChannelState { DISCONNECTED, HALF_CONNECTED, CONNECTED, FAILURE };
3994bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    private ChannelState mState = ChannelState.DISCONNECTED;
4094bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills
4194bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    public void assertConnected() {
4294bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills        assertEquals("AsyncChannel was not fully connected", ChannelState.CONNECTED, mState);
4394bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    }
4494bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills
4594bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    public void connect(final Looper looper, final Messenger messenger,
4694bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills            final Handler incomingMessageHandler) {
4794bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills        assertEquals("AsyncChannel must be disconnected to connect",
4894bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills                ChannelState.DISCONNECTED, mState);
4994bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills        mChannel = new AsyncChannel();
5094bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills        Handler rawMessageHandler = new Handler(looper) {
5194bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills                @Override
5294bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills                public void handleMessage(Message msg) {
5394bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills                    switch (msg.what) {
5494bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills                    case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED:
5594bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills                        if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
5694bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills                            Log.d(TAG, "Successfully half connected " + this);
5794bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills                            mChannel.sendMessage(AsyncChannel.CMD_CHANNEL_FULL_CONNECTION);
5894bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills                            mState = ChannelState.HALF_CONNECTED;
5994bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills                        } else {
6094bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills                            Log.d(TAG, "Failed to connect channel " + this);
6194bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills                            mState = ChannelState.FAILURE;
6294bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills                            mChannel = null;
6394bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills                        }
6494bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills                        break;
6594bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills                    case AsyncChannel.CMD_CHANNEL_FULLY_CONNECTED:
6694bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills                        mState = ChannelState.CONNECTED;
6794bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills                        Log.d(TAG, "Channel fully connected" + this);
6894bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills                        break;
6994bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills                    case AsyncChannel.CMD_CHANNEL_DISCONNECTED:
7094bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills                        mState = ChannelState.DISCONNECTED;
7194bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills                        mChannel = null;
7294bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills                        Log.d(TAG, "Channel disconnected" + this);
7394bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills                        break;
7494bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills                    default:
7594bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills                        incomingMessageHandler.handleMessage(msg);
7694bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills                        break;
7794bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills                    }
7894bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills                }
7994bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills            };
8094bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills        mChannel.connect(null, rawMessageHandler, messenger);
8194bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    }
8294bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills
8394bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    public void disconnect() {
8494bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills        assertEquals("AsyncChannel must be connected to disconnect",
8594bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills                ChannelState.CONNECTED, mState);
8694bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills        mChannel.sendMessage(AsyncChannel.CMD_CHANNEL_DISCONNECT);
8794bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills        mState = ChannelState.DISCONNECTED;
8894bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills        mChannel = null;
8994bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    }
9094bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills
9194bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    public void sendMessage(Message msg) {
9294bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills        assertEquals("AsyncChannel must be connected to send messages",
9394bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills                ChannelState.CONNECTED, mState);
9494bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills        mChannel.sendMessage(msg);
9594bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    }
9694bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills}
97