Index: chrome/browser/extensions/bookmark_app_helper_browsertest.cc |
diff --git a/chrome/browser/extensions/bookmark_app_helper_browsertest.cc b/chrome/browser/extensions/bookmark_app_helper_browsertest.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..065080e24d406783ce63591fce6ffbbac739071e |
--- /dev/null |
+++ b/chrome/browser/extensions/bookmark_app_helper_browsertest.cc |
@@ -0,0 +1,152 @@ |
+// 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/extensions/bookmark_app_helper.h" |
+ |
+#include "base/run_loop.h" |
+#include "base/strings/utf_string_conversions.h" |
+#include "chrome/app/chrome_command_ids.h" |
+#include "chrome/browser/ui/browser.h" |
+#include "chrome/browser/ui/browser_commands.h" |
+#include "chrome/browser/ui/tabs/tab_strip_model.h" |
+#include "chrome/browser/ui/test/test_browser_dialog.h" |
+#include "chrome/common/render_messages.h" |
+#include "content/public/browser/browser_message_filter.h" |
+#include "content/public/browser/render_process_host.h" |
+#include "content/public/browser/render_widget_host.h" |
+#include "content/public/browser/render_widget_host_view.h" |
+#include "content/public/browser/web_contents.h" |
+ |
+namespace extensions { |
+namespace { |
+ |
+content::RenderWidgetHost* GetActiveRenderWidgetHost(Browser* browser) { |
+ return browser->tab_strip_model() |
+ ->GetActiveWebContents() |
+ ->GetRenderWidgetHostView() |
+ ->GetRenderWidgetHost(); |
+} |
+ |
+// Extends BookmarkAppHelper to see the call to OnIconsDownloaded. |
+class TestBookmarkAppHelper : public BookmarkAppHelper { |
+ public: |
+ TestBookmarkAppHelper(Profile* profile, |
+ WebApplicationInfo web_app_info, |
+ content::WebContents* contents, |
+ base::Closure on_icons_downloaded_closure) |
+ : BookmarkAppHelper(profile, web_app_info, contents), |
+ on_icons_downloaded_closure_(on_icons_downloaded_closure) {} |
+ |
+ // TestBookmarkAppHelper: |
+ void OnIconsDownloaded( |
+ bool success, |
+ const std::map<GURL, std::vector<SkBitmap>>& bitmaps) override { |
+ on_icons_downloaded_closure_.Run(); |
+ BookmarkAppHelper::OnIconsDownloaded(success, bitmaps); |
+ } |
+ |
+ private: |
+ base::Closure on_icons_downloaded_closure_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(TestBookmarkAppHelper); |
+}; |
+ |
+// Intercepts the ChromeViewHostMsg_DidGetWebApplicationInfo that would usually |
+// get sent to extensions::TabHelper to create a BookmarkAppHelper that lets us |
+// detect when icons are downloaded and the dialog is ready to show. |
+class WebAppReadyMsgWatcher : public content::BrowserMessageFilter { |
+ public: |
+ explicit WebAppReadyMsgWatcher(Browser* browser) |
+ : BrowserMessageFilter(ChromeMsgStart), browser_(browser) {} |
+ |
+ content::WebContents* web_contents() { |
+ return browser_->tab_strip_model()->GetActiveWebContents(); |
+ } |
+ |
+ void OnDidGetWebApplicationInfo(const WebApplicationInfo& const_info) { |
+ WebApplicationInfo info = const_info; |
+ // Mimic extensions::TabHelper for fields missing from the manifest. |
+ if (info.app_url.is_empty()) |
+ info.app_url = web_contents()->GetURL(); |
+ if (info.title.empty()) |
+ info.title = web_contents()->GetTitle(); |
+ if (info.title.empty()) |
+ info.title = base::UTF8ToUTF16(info.app_url.spec()); |
+ |
+ bookmark_app_helper_ = base::MakeUnique<TestBookmarkAppHelper>( |
+ browser_->profile(), info, web_contents(), quit_closure_); |
+ bookmark_app_helper_->Create( |
+ base::Bind(&WebAppReadyMsgWatcher::FinishCreateBookmarkApp, this)); |
+ } |
+ |
+ void FinishCreateBookmarkApp(const Extension* extension, |
+ const WebApplicationInfo& web_app_info) { |
+ // ~WebAppReadyMsgWatcher() is called on the IO thread, but |
+ // |bookmark_app_helper_| must be destroyed on the UI thread. |
+ bookmark_app_helper_.reset(); |
+ } |
+ |
+ void Wait() { |
+ base::RunLoop run_loop; |
+ quit_closure_ = run_loop.QuitClosure(); |
+ run_loop.Run(); |
+ } |
+ |
+ // BrowserMessageFilter: |
+ void OverrideThreadForMessage(const IPC::Message& message, |
+ content::BrowserThread::ID* thread) override { |
+ if (message.type() == ChromeViewHostMsg_DidGetWebApplicationInfo::ID) |
+ *thread = content::BrowserThread::UI; |
+ } |
+ |
+ bool OnMessageReceived(const IPC::Message& message) override { |
+ bool handled = true; |
+ IPC_BEGIN_MESSAGE_MAP(WebAppReadyMsgWatcher, message) |
+ IPC_MESSAGE_HANDLER(ChromeViewHostMsg_DidGetWebApplicationInfo, |
+ OnDidGetWebApplicationInfo) |
+ IPC_MESSAGE_UNHANDLED(handled = false) |
+ IPC_END_MESSAGE_MAP() |
+ return handled; |
+ } |
+ |
+ private: |
+ ~WebAppReadyMsgWatcher() override {} |
+ |
+ Browser* browser_; |
+ base::Closure quit_closure_; |
+ std::unique_ptr<TestBookmarkAppHelper> bookmark_app_helper_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(WebAppReadyMsgWatcher); |
+}; |
+ |
+} // namespace |
+ |
+class BookmarkAppHelperTest : public DialogBrowserTest { |
+ public: |
+ BookmarkAppHelperTest() {} |
+ |
+ // DialogBrowserTest: |
+ void ShowDialog(const std::string& name) override { |
+ ASSERT_TRUE(embedded_test_server()->Start()); |
+ AddTabAtIndex( |
+ 1, |
+ GURL(embedded_test_server()->GetURL("/favicon/page_with_favicon.html")), |
+ ui::PAGE_TRANSITION_LINK); |
+ |
+ scoped_refptr<WebAppReadyMsgWatcher> filter = |
+ new WebAppReadyMsgWatcher(browser()); |
+ GetActiveRenderWidgetHost(browser())->GetProcess()->AddFilter(filter.get()); |
+ chrome::ExecuteCommand(browser(), IDC_CREATE_HOSTED_APP); |
+ filter->Wait(); |
+ } |
+ |
+ private: |
+ DISALLOW_COPY_AND_ASSIGN(BookmarkAppHelperTest); |
+}; |
+ |
+IN_PROC_BROWSER_TEST_F(BookmarkAppHelperTest, InvokeDialog_create) { |
+ RunDialog(); |
+} |
+ |
+} // namespace extensions |