Index: chrome/browser/android/media_iph_manager.cc |
diff --git a/chrome/browser/android/media_iph_manager.cc b/chrome/browser/android/media_iph_manager.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..b0b20956239a87030dc2d56cea8f0564f3daedbd |
--- /dev/null |
+++ b/chrome/browser/android/media_iph_manager.cc |
@@ -0,0 +1,125 @@ |
+// Copyright 2017 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 "chrome/browser/android/media_iph_manager.h" |
+ |
+#include "base/memory/ptr_util.h" |
+#include "base/optional.h" |
+#include "content/public/browser/navigation_handle.h" |
+#include "content/public/browser/render_frame_host.h" |
+#include "content/public/browser/render_widget_host_view.h" |
+#include "mojo/public/cpp/bindings/strong_binding.h" |
+#include "services/service_manager/public/cpp/bind_source_info.h" |
+#include "services/service_manager/public/cpp/interface_provider.h" |
+ |
+namespace { |
+ |
+void SendDismissUIToRenderer(content::RenderFrameHost* render_frame_host) { |
+ chrome::mojom::MediaIPHDelegateServicePtr delegate_service; |
+ render_frame_host->GetRemoteInterfaces()->GetInterface(&delegate_service); |
+ delegate_service->WidgetDismissed(); |
+} |
+ |
+} // namespace |
+ |
+class MediaIPHManager::MediaIPHService : public chrome::mojom::MediaIPHService { |
+ public: |
+ MediaIPHService(content::RenderFrameHost* render_frame_host, |
+ MediaIPHManager* manager) |
+ : render_frame_host_(render_frame_host), manager_(manager) { |
+ DCHECK(render_frame_host_); |
+ DCHECK(manager_); |
+ } |
+ ~MediaIPHService() override = default; |
+ |
+ // chrome::mojom::MediaPromoUI implementation. |
+ void ShowIPHWidget(const gfx::Rect& button_rect, bool new_request) override { |
+ manager_->ShowIPHWidget(render_frame_host_, button_rect, new_request); |
+ } |
+ |
+ void HideIPHWidget() override { manager_->HideIPHWidget(render_frame_host_); } |
+ |
+ private: |
+ content::RenderFrameHost* render_frame_host_; |
+ MediaIPHManager* manager_; |
+}; |
+ |
+MediaIPHManager::MediaIPHManager(content::WebContents* web_contents, |
+ MediaIPHManagerClient* client) |
+ : WebContentsObserver(web_contents), client_(client), weak_factory_(this) { |
+ DCHECK(client_); |
+} |
+ |
+MediaIPHManager::~MediaIPHManager() { |
+ if (active_render_frame_host_) { |
+ client_->DismissMediaDownloadIPH(); |
+ } |
+} |
+ |
+void MediaIPHManager::WidgetDismissed() { |
+ DCHECK(active_render_frame_host_); |
+ |
+ SendDismissUIToRenderer(active_render_frame_host_); |
+ active_render_frame_host_ = nullptr; |
+} |
+ |
+void MediaIPHManager::RenderFrameCreated( |
+ content::RenderFrameHost* render_frame_host) { |
+ // Register the bridge service for the renderer to request showing the UI. |
+ render_frame_host->GetInterfaceRegistry()->AddInterface( |
+ base::Bind(&MediaIPHManager::CreateIPHService, weak_factory_.GetWeakPtr(), |
+ render_frame_host)); |
+} |
+ |
+void MediaIPHManager::RenderFrameDeleted( |
+ content::RenderFrameHost* render_frame_host) { |
+ if (active_render_frame_host_ != render_frame_host) |
+ return; |
+ client_->DismissMediaDownloadIPH(); |
+} |
+ |
+void MediaIPHManager::CreateIPHService( |
+ content::RenderFrameHost* render_frame_host, |
+ const service_manager::BindSourceInfo& source_info, |
+ chrome::mojom::MediaIPHServiceRequest request) { |
+ mojo::MakeStrongBinding( |
+ base::MakeUnique<MediaIPHService>(render_frame_host, this), |
+ std::move(request)); |
+} |
+ |
+void MediaIPHManager::ShowIPHWidget(content::RenderFrameHost* render_frame_host, |
+ const gfx::Rect& rect_in_main_frame, |
+ bool new_request) { |
+ if (active_render_frame_host_ && |
+ active_render_frame_host_ != render_frame_host) { |
+ // If we are currently showing the UI for another frame, inform the |
+ // requesting frame that the widget can not be shown. |
+ SendDismissUIToRenderer(render_frame_host); |
+ return; |
+ } |
+ |
+ if (!active_render_frame_host_) { |
+ // We might have dismissed the widget while this update was in flight. |
+ if (!new_request) |
+ return; |
+ |
+ // If we don't want to show the IPH for this button, inform the renderer. |
+ if (!client_->ShowMediaDownloadIPH()) { |
+ SendDismissUIToRenderer(render_frame_host); |
+ return; |
+ } |
+ |
+ active_render_frame_host_ = render_frame_host; |
+ } |
+ |
+ client_->UpdateMediaDownloadIPHPosition(rect_in_main_frame); |
+} |
+ |
+void MediaIPHManager::HideIPHWidget( |
+ content::RenderFrameHost* render_frame_host) { |
+ // We might have dismissed the widget for this frame already. |
+ if (active_render_frame_host_ != render_frame_host) |
+ return; |
+ client_->DismissMediaDownloadIPH(); |
+} |