/* * Copyright (C) 2010 Google Inc. All rights reserved. * * 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.google.anymote.server; import com.google.anymote.Key.Action; import com.google.anymote.Key.Code; import com.google.anymote.Messages.Connect; import com.google.anymote.Messages.Data; import com.google.anymote.Messages.Fling; import com.google.anymote.Messages.FlingResult; import com.google.anymote.Messages.FlingResult.Result; import com.google.anymote.Messages.KeyEvent; import com.google.anymote.Messages.MouseEvent; import com.google.anymote.Messages.MouseWheel; import com.google.anymote.Messages.RemoteMessage; import com.google.anymote.Messages.RequestMessage; import com.google.anymote.Messages.ResponseMessage; import com.google.anymote.common.ConnectInfo; import com.google.anymote.common.RemoteWireAdapter.IMessageListener; import com.google.anymote.common.WireAdapter; /** * Manages messages on the server side. */ public final class ServerMessageAdapter implements ServerAdapter, IMessageListener { /** * The listener of the received events. */ private final RequestReceiver mCommandReceiver; /** * The remote message sender. */ private final WireAdapter mWireAdapter; /** * A class that describe a policy to deal with acknowledgments. */ public static class AckPolicy { /** * Called when a sequence number is received. */ public void onReceivedSequence(int sequenceNumber) { // Default implementation does nothing. } } public ServerMessageAdapter( RequestReceiver receiver, WireAdapter wireAdapter) { mCommandReceiver = receiver; mWireAdapter = wireAdapter; } public WireAdapter getWireAdapter() { return mWireAdapter; } public void onMessage(RemoteMessage message) { if (message.hasRequestMessage()) { interpretRequest(message.getRequestMessage(), message.hasSequenceNumber() ? message.getSequenceNumber() : null); } } /** * Interprets a request message. * * @param message the request message */ private void interpretRequest(RequestMessage message, Integer sequenceNumber) { ResponseMessage.Builder builder = ResponseMessage.newBuilder(); boolean reply = sequenceNumber != null; if (message.hasKeyEventMessage()) { reply = false; onKeyEvent(message.getKeyEventMessage()); } if (message.hasMouseEventMessage()) { reply = false; onMouseEvent(message.getMouseEventMessage()); } if (message.hasMouseWheelMessage()) { reply = false; onMouseWheel(message.getMouseWheelMessage()); } if (message.hasDataMessage()) { reply = false; onData(message.getDataMessage()); } if (message.hasConnectMessage()) { reply = false; onConnect(message.getConnectMessage()); } if (message.hasFlingMessage()) { reply = true; builder.setFlingResultMessage( onFling(message.getFlingMessage(), sequenceNumber)); } if (reply) { sendResponse(builder, sequenceNumber); } } private void onKeyEvent(KeyEvent message) { Code keycode = message.getKeycode(); Action action = message.getAction(); mCommandReceiver.onKeyEvent(keycode, action); } private void onMouseEvent(MouseEvent message) { int xDelta = message.getXDelta(); int yDelta = message.getYDelta(); mCommandReceiver.onMouseEvent(xDelta, yDelta); } private void onMouseWheel(MouseWheel message) { int xScrollAmt = message.getXScroll(); int yScrollAmt = message.getYScroll(); mCommandReceiver.onMouseWheel(xScrollAmt, yScrollAmt); } private void onData(Data message) { mCommandReceiver.onData(message.getType(), message.getData()); } private FlingResult.Builder onFling(Fling message, Integer sequenceNumber) { boolean success = mCommandReceiver.onFling(message.getUri()); return FlingResult.newBuilder().setResult( success ? Result.SUCCESS : Result.FAILURE); } private void onConnect(Connect message) { mCommandReceiver.onConnect(ConnectInfo.parseFromProto(message)); } public void sendData(String type, String data) { Data.Builder replyMessageBuilder = Data.newBuilder(); replyMessageBuilder.setType(type); replyMessageBuilder.setData(data); ResponseMessage.Builder responseBuilder = ResponseMessage.newBuilder(); responseBuilder.setDataMessage(replyMessageBuilder); sendResponse(responseBuilder, null); } /** * Sends a response message. * * @param responseMessage the message to send * @param sequenceNumber optional sequence number associated with response */ private void sendResponse( ResponseMessage.Builder responseMessage, Integer sequenceNumber) { RemoteMessage.Builder message = RemoteMessage.newBuilder().setResponseMessage(responseMessage); if (sequenceNumber != null) { message.setSequenceNumber(sequenceNumber); } mWireAdapter.sendRemoteMessage(message.build()); } }