chromium/chromecast/cast_core/runtime/browser/runtime_service_impl.h

// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROMECAST_CAST_CORE_RUNTIME_BROWSER_RUNTIME_SERVICE_IMPL_H_
#define CHROMECAST_CAST_CORE_RUNTIME_BROWSER_RUNTIME_SERVICE_IMPL_H_

#include <memory>
#include <optional>
#include <string_view>

#include "base/memory/weak_ptr.h"
#include "base/task/sequenced_task_runner.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "chromecast/cast_core/grpc/grpc_server.h"
#include "chromecast/cast_core/runtime/browser/cast_runtime_action_recorder.h"
#include "chromecast/cast_core/runtime/browser/cast_runtime_metrics_recorder.h"
#include "chromecast/cast_core/runtime/browser/cast_runtime_metrics_recorder_service.h"
#include "chromecast/cast_core/runtime/browser/runtime_application_service_impl.h"
#include "components/cast_receiver/browser/public/runtime_application_dispatcher.h"
#include "components/cast_receiver/common/public/status.h"
#include "third_party/cast_core/public/src/proto/metrics/metrics_recorder.castcore.pb.h"
#include "third_party/cast_core/public/src/proto/runtime/runtime_service.castcore.pb.h"

namespace cast_receiver {
class ContentBrowserClientMixins;
}  // namespace cast_receiver

namespace chromecast {

class CastWebService;

// An implementation of the gRPC-defined RuntimeService for use with Cast Core.
class RuntimeServiceImpl final
    : public CastRuntimeMetricsRecorder::EventBuilderFactory {
 public:
  // |application_client| and |web_service| are expected to persist for the
  // lifetime of this instance.
  RuntimeServiceImpl(cast_receiver::ContentBrowserClientMixins& browser_mixins,
                     CastWebService& web_service);
  ~RuntimeServiceImpl() override;

  // Starts and stops the runtime service, including the gRPC completion queue.
  cast_receiver::Status Start();
  cast_receiver::Status Start(std::string_view runtime_id,
                              std::string_view runtime_service_endpoint);
  cast_receiver::Status Stop();

  // CastRuntimeMetricsRecorder::EventBuilderFactory overrides:
  std::unique_ptr<CastEventBuilder> CreateEventBuilder() override;

 private:
  // RuntimeService gRPC handlers:
  void HandleLoadApplication(
      cast::runtime::LoadApplicationRequest request,
      cast::runtime::RuntimeServiceHandler::LoadApplication::Reactor* reactor);
  void HandleLaunchApplication(
      cast::runtime::LaunchApplicationRequest request,
      cast::runtime::RuntimeServiceHandler::LaunchApplication::Reactor*
          reactor);
  void HandleStopApplication(
      cast::runtime::StopApplicationRequest request,
      cast::runtime::RuntimeServiceHandler::StopApplication::Reactor* reactor);
  void HandleHeartbeat(
      cast::runtime::HeartbeatRequest request,
      cast::runtime::RuntimeServiceHandler::Heartbeat::Reactor* reactor);
  void HandleStartMetricsRecorder(
      cast::runtime::StartMetricsRecorderRequest request,
      cast::runtime::RuntimeServiceHandler::StartMetricsRecorder::Reactor*
          reactor);
  void HandleStopMetricsRecorder(
      cast::runtime::StopMetricsRecorderRequest request,
      cast::runtime::RuntimeServiceHandler::StopMetricsRecorder::Reactor*
          reactor);

  // Helper methods.
  void OnApplicationLoaded(
      std::string session_id,
      cast::runtime::RuntimeServiceHandler::LoadApplication::Reactor* reactor,
      cast_receiver::Status status);
  void OnApplicationLaunching(
      std::string session_id,
      cast::runtime::RuntimeServiceHandler::LaunchApplication::Reactor* reactor,
      cast_receiver::Status status);
  void OnApplicationStopping(
      std::string session_id,
      cast::runtime::RuntimeServiceHandler::StopApplication::Reactor* reactor,
      cast_receiver::Status status);
  void SendHeartbeat();
  void OnHeartbeatSent(
      grpc::Status status,
      cast::runtime::RuntimeServiceHandler::Heartbeat::Reactor* reactor);
  void RecordMetrics(cast::metrics::RecordRequest request,
                     CastRuntimeMetricsRecorderService::RecordCompleteCallback
                         record_complete_callback);
  void OnMetricsRecorded(
      CastRuntimeMetricsRecorderService::RecordCompleteCallback
          record_complete_callback,
      cast::utils::GrpcStatusOr<cast::metrics::RecordResponse> response_or);
  void OnMetricsRecorderServiceStopped(
      cast::runtime::RuntimeServiceHandler::StopMetricsRecorder::Reactor*
          reactor);

  void ResetGrpcServices();

  SEQUENCE_CHECKER(sequence_checker_);

  std::unique_ptr<cast_receiver::RuntimeApplicationDispatcher<
      RuntimeApplicationServiceImpl>>
      application_dispatcher_;

  scoped_refptr<base::SequencedTaskRunner> task_runner_;

  raw_ref<CastWebService> const web_service_;

  // Allows metrics, histogram, action recording, which can be reported by
  // CastRuntimeMetricsRecorderService if Cast Core starts it.
  CastRuntimeActionRecorder action_recorder_;
  CastRuntimeMetricsRecorder metrics_recorder_;

  std::optional<cast::utils::GrpcServer> grpc_server_;
  std::optional<cast::metrics::MetricsRecorderServiceStub>
      metrics_recorder_stub_;
  std::optional<CastRuntimeMetricsRecorderService> metrics_recorder_service_;

  // Heartbeat period as set by Cast Core.
  base::TimeDelta heartbeat_period_;

  // Heartbeat timeout timer.
  base::OneShotTimer heartbeat_timer_;

  // Server streaming reactor used to send the heartbeats to Cast Core.
  cast::runtime::RuntimeServiceHandler::Heartbeat::Reactor* heartbeat_reactor_ =
      nullptr;

  base::WeakPtrFactory<RuntimeServiceImpl> weak_factory_{this};
};

}  // namespace chromecast

#endif  // CHROMECAST_CAST_CORE_RUNTIME_BROWSER_RUNTIME_SERVICE_IMPL_H_