Home | History | Annotate | Download | only in lib
      1 // Copyright 2015 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "mojo/public/cpp/bindings/lib/control_message_handler.h"
      6 
      7 #include <stddef.h>
      8 #include <stdint.h>
      9 #include <utility>
     10 
     11 #include "base/logging.h"
     12 #include "mojo/public/cpp/bindings/lib/message_builder.h"
     13 #include "mojo/public/cpp/bindings/lib/serialization.h"
     14 #include "mojo/public/cpp/bindings/lib/validation_util.h"
     15 #include "mojo/public/interfaces/bindings/interface_control_messages.mojom.h"
     16 
     17 namespace mojo {
     18 namespace internal {
     19 namespace {
     20 
     21 bool ValidateControlRequestWithResponse(Message* message) {
     22   ValidationContext validation_context(message->payload(),
     23                                        message->payload_num_bytes(), 0, 0,
     24                                        message, "ControlRequestValidator");
     25   if (!ValidateMessageIsRequestExpectingResponse(message, &validation_context))
     26     return false;
     27 
     28   switch (message->header()->name) {
     29     case interface_control::kRunMessageId:
     30       return ValidateMessagePayload<
     31           interface_control::internal::RunMessageParams_Data>(
     32           message, &validation_context);
     33   }
     34   return false;
     35 }
     36 
     37 bool ValidateControlRequestWithoutResponse(Message* message) {
     38   ValidationContext validation_context(message->payload(),
     39                                        message->payload_num_bytes(), 0, 0,
     40                                        message, "ControlRequestValidator");
     41   if (!ValidateMessageIsRequestWithoutResponse(message, &validation_context))
     42     return false;
     43 
     44   switch (message->header()->name) {
     45     case interface_control::kRunOrClosePipeMessageId:
     46       return ValidateMessageIsRequestWithoutResponse(message,
     47                                                      &validation_context) &&
     48              ValidateMessagePayload<
     49                  interface_control::internal::RunOrClosePipeMessageParams_Data>(
     50                  message, &validation_context);
     51   }
     52   return false;
     53 }
     54 
     55 }  // namespace
     56 
     57 // static
     58 bool ControlMessageHandler::IsControlMessage(const Message* message) {
     59   return message->header()->name == interface_control::kRunMessageId ||
     60          message->header()->name == interface_control::kRunOrClosePipeMessageId;
     61 }
     62 
     63 ControlMessageHandler::ControlMessageHandler(uint32_t interface_version)
     64     : interface_version_(interface_version) {
     65 }
     66 
     67 ControlMessageHandler::~ControlMessageHandler() {
     68 }
     69 
     70 bool ControlMessageHandler::Accept(Message* message) {
     71   if (!ValidateControlRequestWithoutResponse(message))
     72     return false;
     73 
     74   if (message->header()->name == interface_control::kRunOrClosePipeMessageId)
     75     return RunOrClosePipe(message);
     76 
     77   NOTREACHED();
     78   return false;
     79 }
     80 
     81 bool ControlMessageHandler::AcceptWithResponder(
     82     Message* message,
     83     MessageReceiverWithStatus* responder) {
     84   if (!ValidateControlRequestWithResponse(message))
     85     return false;
     86 
     87   if (message->header()->name == interface_control::kRunMessageId)
     88     return Run(message, responder);
     89 
     90   NOTREACHED();
     91   return false;
     92 }
     93 
     94 bool ControlMessageHandler::Run(Message* message,
     95                                 MessageReceiverWithStatus* responder) {
     96   interface_control::internal::RunMessageParams_Data* params =
     97       reinterpret_cast<interface_control::internal::RunMessageParams_Data*>(
     98           message->mutable_payload());
     99   interface_control::RunMessageParamsPtr params_ptr;
    100   Deserialize<interface_control::RunMessageParamsDataView>(params, &params_ptr,
    101                                                            &context_);
    102   auto& input = *params_ptr->input;
    103   interface_control::RunOutputPtr output = interface_control::RunOutput::New();
    104   if (input.is_query_version()) {
    105     output->set_query_version_result(
    106         interface_control::QueryVersionResult::New());
    107     output->get_query_version_result()->version = interface_version_;
    108   } else if (input.is_flush_for_testing()) {
    109     output.reset();
    110   } else {
    111     output.reset();
    112   }
    113 
    114   auto response_params_ptr = interface_control::RunResponseMessageParams::New();
    115   response_params_ptr->output = std::move(output);
    116   size_t size =
    117       PrepareToSerialize<interface_control::RunResponseMessageParamsDataView>(
    118           response_params_ptr, &context_);
    119   MessageBuilder builder(interface_control::kRunMessageId,
    120                          Message::kFlagIsResponse, size, 0);
    121   builder.message()->set_request_id(message->request_id());
    122 
    123   interface_control::internal::RunResponseMessageParams_Data* response_params =
    124       nullptr;
    125   Serialize<interface_control::RunResponseMessageParamsDataView>(
    126       response_params_ptr, builder.buffer(), &response_params, &context_);
    127   bool ok = responder->Accept(builder.message());
    128   ALLOW_UNUSED_LOCAL(ok);
    129   delete responder;
    130 
    131   return true;
    132 }
    133 
    134 bool ControlMessageHandler::RunOrClosePipe(Message* message) {
    135   interface_control::internal::RunOrClosePipeMessageParams_Data* params =
    136       reinterpret_cast<
    137           interface_control::internal::RunOrClosePipeMessageParams_Data*>(
    138           message->mutable_payload());
    139   interface_control::RunOrClosePipeMessageParamsPtr params_ptr;
    140   Deserialize<interface_control::RunOrClosePipeMessageParamsDataView>(
    141       params, &params_ptr, &context_);
    142   auto& input = *params_ptr->input;
    143   if (input.is_require_version())
    144     return interface_version_ >= input.get_require_version()->version;
    145 
    146   return false;
    147 }
    148 
    149 }  // namespace internal
    150 }  // namespace mojo
    151