1// Copyright 2012 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 "chrome/browser/metro_viewer/chrome_metro_viewer_process_host_aurawin.h"
6
7#include "ash/shell.h"
8#include "base/logging.h"
9#include "base/memory/ref_counted.h"
10#include "chrome/browser/browser_process.h"
11#include "chrome/browser/browser_process_platform_part_aurawin.h"
12#include "chrome/browser/chrome_notification_types.h"
13#include "chrome/browser/profiles/profile_manager.h"
14#include "chrome/browser/search_engines/util.h"
15#include "chrome/browser/ui/ash/ash_init.h"
16#include "chrome/browser/ui/browser.h"
17#include "chrome/browser/ui/browser_finder.h"
18#include "chrome/browser/ui/browser_list.h"
19#include "chrome/browser/ui/browser_window.h"
20#include "chrome/browser/ui/host_desktop.h"
21#include "chrome/browser/ui/tabs/tab_strip_model.h"
22#include "content/public/browser/browser_thread.h"
23#include "content/public/browser/notification_service.h"
24#include "content/public/browser/page_navigator.h"
25#include "content/public/browser/web_contents.h"
26#include "ui/aura/remote_root_window_host_win.h"
27#include "ui/surface/accelerated_surface_win.h"
28#include "url/gurl.h"
29
30namespace {
31
32void CloseOpenAshBrowsers() {
33  BrowserList* browser_list =
34      BrowserList::GetInstance(chrome::HOST_DESKTOP_TYPE_ASH);
35  if (browser_list) {
36    for (BrowserList::const_iterator i = browser_list->begin();
37         i != browser_list->end(); ++i) {
38      Browser* browser = *i;
39      browser->window()->Close();
40      // If the attempt to Close the browser fails due to unload handlers on
41      // the page or in progress downloads, etc, destroy all tabs on the page.
42      while (browser->tab_strip_model()->count())
43        delete browser->tab_strip_model()->GetWebContentsAt(0);
44    }
45  }
46}
47
48void OpenURL(const GURL& url) {
49  Browser* browser = chrome::FindOrCreateTabbedBrowser(
50      ProfileManager::GetDefaultProfileOrOffTheRecord(),
51      chrome::HOST_DESKTOP_TYPE_ASH);
52  browser->OpenURL(content::OpenURLParams(
53    GURL(url), content::Referrer(), NEW_FOREGROUND_TAB,
54    content::PAGE_TRANSITION_TYPED, false));
55}
56
57}  // namespace
58
59ChromeMetroViewerProcessHost::ChromeMetroViewerProcessHost()
60    : MetroViewerProcessHost(
61          content::BrowserThread::GetMessageLoopProxyForThread(
62              content::BrowserThread::IO)) {
63  g_browser_process->AddRefModule();
64}
65
66void  ChromeMetroViewerProcessHost::OnChannelError() {
67  // TODO(cpu): At some point we only close the browser. Right now this
68  // is very convenient for developing.
69  DLOG(INFO) << "viewer channel error : Quitting browser";
70  aura::RemoteRootWindowHostWin::Instance()->Disconnected();
71  g_browser_process->ReleaseModule();
72  CloseOpenAshBrowsers();
73  chrome::CloseAsh();
74  // Tell the rest of Chrome about it.
75  content::NotificationService::current()->Notify(
76      chrome::NOTIFICATION_ASH_SESSION_ENDED,
77      content::NotificationService::AllSources(),
78      content::NotificationService::NoDetails());
79
80  // This will delete the MetroViewerProcessHost object. Don't access member
81  // variables/functions after this call.
82  g_browser_process->platform_part()->OnMetroViewerProcessTerminated();
83}
84
85void ChromeMetroViewerProcessHost::OnSetTargetSurface(
86    gfx::NativeViewId target_surface) {
87  DLOG(INFO) << __FUNCTION__ << ", target_surface = " << target_surface;
88  HWND hwnd = reinterpret_cast<HWND>(target_surface);
89  chrome::OpenAsh();
90  scoped_refptr<AcceleratedPresenter> any_window =
91      AcceleratedPresenter::GetForWindow(NULL);
92  any_window->SetNewTargetWindow(hwnd);
93  aura::RemoteRootWindowHostWin::Instance()->Connected(this);
94  ash::Shell::GetInstance()->CreateLauncher();
95  ash::Shell::GetInstance()->ShowLauncher();
96  // Tell the rest of Chrome that Ash is running.
97  content::NotificationService::current()->Notify(
98      chrome::NOTIFICATION_ASH_SESSION_STARTED,
99      content::NotificationService::AllSources(),
100      content::NotificationService::NoDetails());
101}
102
103void ChromeMetroViewerProcessHost::OnOpenURL(const string16& url) {
104  OpenURL(GURL(url));
105}
106
107void ChromeMetroViewerProcessHost::OnHandleSearchRequest(
108    const string16& search_string) {
109  GURL url(GetDefaultSearchURLForSearchTerms(
110      ProfileManager::GetDefaultProfileOrOffTheRecord(), search_string));
111  if (url.is_valid())
112    OpenURL(url);
113}
114