Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / views / apps / native_app_window_views_win.cc
1 // Copyright 2013 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/ui/views/apps/native_app_window_views_win.h"
6
7 #include "apps/app_window.h"
8 #include "apps/app_window_registry.h"
9 #include "ash/shell.h"
10 #include "base/command_line.h"
11 #include "base/file_util.h"
12 #include "base/path_service.h"
13 #include "base/strings/utf_string_conversions.h"
14 #include "base/threading/sequenced_worker_pool.h"
15 #include "chrome/browser/apps/per_app_settings_service.h"
16 #include "chrome/browser/apps/per_app_settings_service_factory.h"
17 #include "chrome/browser/metro_utils/metro_chrome_win.h"
18 #include "chrome/browser/profiles/profile.h"
19 #include "chrome/browser/ui/web_applications/web_app_ui.h"
20 #include "chrome/browser/web_applications/web_app.h"
21 #include "chrome/browser/web_applications/web_app_win.h"
22 #include "chrome/common/chrome_switches.h"
23 #include "content/public/browser/browser_thread.h"
24 #include "extensions/common/extension.h"
25 #include "ui/aura/remote_window_tree_host_win.h"
26 #include "ui/base/win/shell.h"
27 #include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h"
28 #include "ui/views/win/hwnd_util.h"
29
30 namespace {
31
32 void CreateIconAndSetRelaunchDetails(
33     const base::FilePath& web_app_path,
34     const base::FilePath& icon_file,
35     const ShellIntegration::ShortcutInfo& shortcut_info,
36     const HWND hwnd) {
37   DCHECK(content::BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread());
38
39   // Set the relaunch data so "Pin this program to taskbar" has the app's
40   // information.
41   CommandLine command_line = ShellIntegration::CommandLineArgsForLauncher(
42       shortcut_info.url,
43       shortcut_info.extension_id,
44       shortcut_info.profile_path);
45
46   base::FilePath chrome_exe;
47   if (!PathService::Get(base::FILE_EXE, &chrome_exe)) {
48     NOTREACHED();
49     return;
50   }
51   command_line.SetProgram(chrome_exe);
52   ui::win::SetRelaunchDetailsForWindow(command_line.GetCommandLineString(),
53       shortcut_info.title, hwnd);
54
55   if (!base::PathExists(web_app_path) &&
56       !base::CreateDirectory(web_app_path)) {
57     return;
58   }
59
60   ui::win::SetAppIconForWindow(icon_file.value(), hwnd);
61   web_app::internals::CheckAndSaveIcon(icon_file, shortcut_info.favicon);
62 }
63
64 }  // namespace
65
66 NativeAppWindowViewsWin::NativeAppWindowViewsWin()
67     : weak_ptr_factory_(this) {
68 }
69
70 void NativeAppWindowViewsWin::ActivateParentDesktopIfNecessary() {
71   if (!ash::Shell::HasInstance())
72     return;
73
74   views::Widget* widget =
75       implicit_cast<views::WidgetDelegate*>(this)->GetWidget();
76   chrome::HostDesktopType host_desktop_type =
77       chrome::GetHostDesktopTypeForNativeWindow(widget->GetNativeWindow());
78   // Only switching into Ash from Native is supported. Tearing the user out of
79   // Metro mode can only be done by launching a process from Metro mode itself.
80   // This is done for launching apps, but not regular activations.
81   if (host_desktop_type == chrome::HOST_DESKTOP_TYPE_ASH &&
82       chrome::GetActiveDesktop() == chrome::HOST_DESKTOP_TYPE_NATIVE) {
83     chrome::ActivateMetroChrome();
84   }
85 }
86
87 void NativeAppWindowViewsWin::OnShortcutInfoLoaded(
88     const ShellIntegration::ShortcutInfo& shortcut_info) {
89   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
90
91   HWND hwnd = GetNativeAppWindowHWND();
92
93   // Set window's icon to the one we're about to create/update in the web app
94   // path. The icon cache will refresh on icon creation.
95   base::FilePath web_app_path = web_app::GetWebAppDataDirectory(
96       shortcut_info.profile_path, shortcut_info.extension_id,
97       shortcut_info.url);
98   base::FilePath icon_file = web_app_path
99       .Append(web_app::internals::GetSanitizedFileName(shortcut_info.title))
100       .ReplaceExtension(FILE_PATH_LITERAL(".ico"));
101
102   content::BrowserThread::PostBlockingPoolTask(
103       FROM_HERE,
104       base::Bind(&CreateIconAndSetRelaunchDetails,
105                  web_app_path, icon_file, shortcut_info, hwnd));
106 }
107
108 HWND NativeAppWindowViewsWin::GetNativeAppWindowHWND() const {
109   return views::HWNDForWidget(window()->GetTopLevelWidget());
110 }
111
112 void NativeAppWindowViewsWin::OnBeforeWidgetInit(
113     views::Widget::InitParams* init_params, views::Widget* widget) {
114   // If an app has any existing windows, ensure new ones are created on the
115   // same desktop.
116   apps::AppWindow* any_existing_window =
117       apps::AppWindowRegistry::Get(browser_context())
118           ->GetCurrentAppWindowForApp(extension()->id());
119   chrome::HostDesktopType desktop_type;
120   if (any_existing_window) {
121     desktop_type = chrome::GetHostDesktopTypeForNativeWindow(
122         any_existing_window->GetNativeWindow());
123   } else {
124     PerAppSettingsService* settings =
125         PerAppSettingsServiceFactory::GetForBrowserContext(browser_context());
126     if (settings->HasDesktopLastLaunchedFrom(extension()->id())) {
127       desktop_type = settings->GetDesktopLastLaunchedFrom(extension()->id());
128     } else {
129       // We don't know what desktop this app was last launched from, so take our
130       // best guess as to what desktop the user is on.
131       desktop_type = chrome::GetActiveDesktop();
132     }
133   }
134   if (desktop_type == chrome::HOST_DESKTOP_TYPE_ASH)
135     init_params->context = ash::Shell::GetPrimaryRootWindow();
136   else
137     init_params->native_widget = new views::DesktopNativeWidgetAura(widget);
138 }
139
140 void NativeAppWindowViewsWin::InitializeDefaultWindow(
141     const apps::AppWindow::CreateParams& create_params) {
142   NativeAppWindowViews::InitializeDefaultWindow(create_params);
143
144   std::string app_name =
145       web_app::GenerateApplicationNameFromExtensionId(extension()->id());
146   base::string16 app_name_wide = base::UTF8ToWide(app_name);
147   HWND hwnd = GetNativeAppWindowHWND();
148   ui::win::SetAppIdForWindow(
149       ShellIntegration::GetAppModelIdForProfile(
150           app_name_wide,
151           Profile::FromBrowserContext(browser_context())->GetPath()),
152       hwnd);
153
154   web_app::UpdateShortcutInfoAndIconForApp(
155       *extension(),
156       Profile::FromBrowserContext(browser_context()),
157       base::Bind(&NativeAppWindowViewsWin::OnShortcutInfoLoaded,
158                  weak_ptr_factory_.GetWeakPtr()));
159 }
160
161 void NativeAppWindowViewsWin::Show() {
162   ActivateParentDesktopIfNecessary();
163   NativeAppWindowViews::Show();
164 }
165
166 void NativeAppWindowViewsWin::Activate() {
167   ActivateParentDesktopIfNecessary();
168   NativeAppWindowViews::Activate();
169 }