blob: 8dd55e0cd90d55189a09659b33f679eba3a84898 [file] [log] [blame]
// 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 CHROME_BROWSER_UI_WEBUI_ACCESS_CODE_CAST_ACCESS_CODE_CAST_HANDLER_H_
#define CHROME_BROWSER_UI_WEBUI_ACCESS_CODE_CAST_ACCESS_CODE_CAST_HANDLER_H_
#include "base/scoped_observation.h"
#include "chrome/browser/media/router/discovery/access_code/access_code_cast_sink_service.h"
#include "chrome/browser/media/router/discovery/access_code/discovery_resources.pb.h"
#include "chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl.h"
#include "chrome/browser/media/router/discovery/mdns/media_sink_util.h"
#include "chrome/browser/ui/media_router/media_cast_mode.h"
#include "chrome/browser/ui/media_router/media_route_starter.h"
#include "chrome/browser/ui/media_router/media_router_ui.h"
#include "chrome/browser/ui/media_router/media_router_ui_helper.h"
#include "chrome/browser/ui/media_router/media_sink_with_cast_modes_observer.h"
#include "chrome/browser/ui/media_router/query_result_manager.h"
#include "chrome/browser/ui/webui/access_code_cast/access_code_cast.mojom.h"
#include "components/media_router/browser/presentation/start_presentation_context.h"
#include "components/media_router/browser/presentation/web_contents_presentation_manager.h"
#include "components/media_router/common/discovery/media_sink_internal.h"
#include "components/signin/public/identity_manager/identity_manager.h"
#include "components/sync/driver/sync_service.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "mojo/public/cpp/bindings/remote.h"
using ::access_code_cast::mojom::AddSinkResultCode;
using ::media_router::AccessCodeCastDiscoveryInterface;
using ::media_router::CreateCastMediaSinkResult;
using ::media_router::MediaSinkInternal;
namespace media_router {
class MediaRouter;
}
// TODO(b/213324920): Remove WebUI from the media_router namespace after
// expiration module has been completed.
namespace media_router {
class AccessCodeCastHandler : public access_code_cast::mojom::PageHandler,
public MediaSinkWithCastModesObserver {
public:
using DiscoveryDevice = chrome_browser_media::proto::DiscoveryDevice;
AccessCodeCastHandler(
mojo::PendingReceiver<access_code_cast::mojom::PageHandler> page_handler,
mojo::PendingRemote<access_code_cast::mojom::Page> page,
const media_router::CastModeSet& cast_mode_set,
std::unique_ptr<MediaRouteStarter> media_route_starter);
~AccessCodeCastHandler() override;
// access_code_cast::mojom::PageHandler overrides:
void AddSink(const std::string& access_code,
access_code_cast::mojom::CastDiscoveryMethod discovery_method,
AddSinkCallback callback) override;
// access_code_cast::mojom::PageHandler overrides:
void CastToSink(CastToSinkCallback callback) override;
private:
friend class AccessCodeCastHandlerTest;
FRIEND_TEST_ALL_PREFIXES(AccessCodeCastHandlerTest, DiscoveredDeviceAdded);
FRIEND_TEST_ALL_PREFIXES(AccessCodeCastHandlerTest, OtherDevicesIgnored);
FRIEND_TEST_ALL_PREFIXES(AccessCodeCastHandlerTest, DesktopMirroring);
FRIEND_TEST_ALL_PREFIXES(AccessCodeCastHandlerTest, DesktopMirroringError);
FRIEND_TEST_ALL_PREFIXES(AccessCodeCastHandlerTest, OnSinkAddedResult);
FRIEND_TEST_ALL_PREFIXES(AccessCodeCastHandlerTest, RouteAlreadyExists);
FRIEND_TEST_ALL_PREFIXES(AccessCodeCastHandlerTest, ProfileSyncSuccess);
FRIEND_TEST_ALL_PREFIXES(AccessCodeCastHandlerTest, ProfileSyncError);
FRIEND_TEST_ALL_PREFIXES(AccessCodeCastHandlerTest, ProfileSyncPaused);
// Constructor that is used for testing.
AccessCodeCastHandler(
mojo::PendingReceiver<access_code_cast::mojom::PageHandler> page_handler,
mojo::PendingRemote<access_code_cast::mojom::Page> page,
const media_router::CastModeSet& cast_mode_set,
std::unique_ptr<MediaRouteStarter> media_route_starter,
AccessCodeCastSinkService* access_code_sink_service);
void Init();
// Returns true if the specified cast mode is among the cast modes specified
// for the dialog to use when it was initialized.
bool IsCastModeAvailable(MediaCastMode mode) const;
MediaRouter* GetMediaRouter() const {
return media_route_starter_->GetMediaRouter();
}
void OnSinkAddedResult(
access_code_cast::mojom::AddSinkResultCode add_sink_result,
absl::optional<MediaSink::Id> sink_id);
// MediaSinkWithCastModesObserver:
void OnSinksUpdated(
const std::vector<MediaSinkWithCastModes>& sinks) override;
// Callback passed to MediaRouter to receive response to route creation
// requests.
void OnRouteResponse(MediaCastMode cast_mode,
int route_request_id,
const MediaSink::Id& sink_id,
CastToSinkCallback dialog_callback,
const RouteRequestResult& result);
void SetSinkCallbackForTesting(AddSinkCallback callback);
void SetIdentityManagerForTesting(signin::IdentityManager* identity_manager);
void SetSyncServiceForTesting(syncer::SyncService* sync_service);
void set_sink_id_for_testing(const MediaSink::Id& sink_id) {
sink_id_ = sink_id;
}
// Checks to see if all the conditions necessary to complete discovery have
// been satisfied. If so, alerts the dialog.
void CheckForDiscoveryCompletion();
// Checks to see that if route already exists for the given media sink id.
bool HasActiveRoute(const MediaSink::Id& sink_id);
// A check to verify that sync is enabled for the given profile. This is
// necessary to check before the access code casting discovery flow, since it
// will fail to make a server call if sync is not enabled.
bool IsAccountSyncEnabled();
mojo::Remote<access_code_cast::mojom::Page> page_;
mojo::Receiver<access_code_cast::mojom::PageHandler> receiver_;
const media_router::CastModeSet cast_mode_set_;
// Contains the info necessary to start a media route.
std::unique_ptr<MediaRouteStarter> media_route_starter_;
raw_ptr<AccessCodeCastSinkService> access_code_sink_service_;
raw_ptr<signin::IdentityManager> identity_manager_;
raw_ptr<syncer::SyncService> sync_service_;
AddSinkCallback add_sink_callback_;
int access_code_not_found_count_ = 0;
// The id of the media sink discovered from the access code;
absl::optional<MediaSink::Id> sink_id_;
// This contains a value only when tracking a pending route request.
absl::optional<RouteRequest> current_route_request_;
base::WeakPtrFactory<AccessCodeCastHandler> weak_ptr_factory_{this};
};
} // namespace media_router
#endif // CHROME_BROWSER_UI_WEBUI_ACCESS_CODE_CAST_ACCESS_CODE_CAST_HANDLER_H_