blob: f87899c8cc497706603a20163bdaf011eed6bf61 [file] [log] [blame]
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "remoting/host/action_message_handler.h"
#include <utility>
#include "base/bind_helpers.h"
#include "remoting/base/compound_buffer.h"
#include "remoting/host/action_executor.h"
#include "remoting/proto/action.pb.h"
#include "remoting/protocol/message_serialization.h"
namespace remoting {
using protocol::ActionResponse;
ActionMessageHandler::ActionMessageHandler(
const std::string& name,
const std::vector<protocol::ActionRequest::Action>& actions,
std::unique_ptr<protocol::MessagePipe> pipe,
std::unique_ptr<ActionExecutor> action_executor)
: protocol::NamedMessagePipeHandler(name, std::move(pipe)),
action_executor_(std::move(action_executor)),
supported_actions_(actions) {
DCHECK(action_executor_);
}
ActionMessageHandler::~ActionMessageHandler() = default;
void ActionMessageHandler::OnIncomingMessage(
std::unique_ptr<CompoundBuffer> message) {
DCHECK(message);
std::unique_ptr<protocol::ActionRequest> request =
protocol::ParseMessage<protocol::ActionRequest>(message.get());
ActionResponse response;
response.set_request_id(request ? request->request_id() : 0);
if (!request) {
response.set_code(ActionResponse::PROTOCOL_ERROR);
response.set_protocol_error_type(ActionResponse::INVALID_MESSAGE_ERROR);
} else if (!request->has_action()) {
// |has_action()| will return false if either the field is not set or the
// value is out of range. Unfortunately we can't distinguish between these
// two conditions so we return the same error for both.
response.set_code(ActionResponse::PROTOCOL_ERROR);
response.set_protocol_error_type(ActionResponse::INVALID_ACTION_ERROR);
} else if (supported_actions_.count(request->action()) == 0) {
// We received an action which is valid, but not supported by this platform
// or connection mode.
response.set_code(ActionResponse::PROTOCOL_ERROR);
response.set_protocol_error_type(ActionResponse::UNSUPPORTED_ACTION_ERROR);
} else {
// Valid action request received. None of the supported actions at this
// time support return codes, if we add actions in the future which could
// fail in an observable way, we should consider returning that info to the
// client.
action_executor_->ExecuteAction(*request);
response.set_code(ActionResponse::ACTION_SUCCESS);
}
Send(response, base::DoNothing());
}
} // namespace remoting