diff options
author | erikwright@chromium.org <erikwright@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-09-07 18:47:30 +0000 |
---|---|---|
committer | erikwright@chromium.org <erikwright@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-09-07 18:47:30 +0000 |
commit | 6fd9b4cdd4a8d9fa2f0e7f63689b6d4c5a2f3f71 (patch) | |
tree | 1c08b23a957274772b044361ecb81868c1f668ac /win8 | |
parent | ab6d23fe5463f88e7e48147d10447575296f75f9 (diff) | |
download | chromium_src-6fd9b4cdd4a8d9fa2f0e7f63689b6d4c5a2f3f71.zip chromium_src-6fd9b4cdd4a8d9fa2f0e7f63689b6d4c5a2f3f71.tar.gz chromium_src-6fd9b4cdd4a8d9fa2f0e7f63689b6d4c5a2f3f71.tar.bz2 |
Revert 155429 - Integrate the Windows 8 code into the Chromium tree.
Exception: Missing input files:
c:\b\build\slave\cr-win-rel\build\src\win8\metro_driver\..\win8\delegate_execute\chrome_util.h
http://build.chromium.org/p/chromium/builders/Win%20Builder/builds/37270/steps/runhooks/logs/stdio
BUG=127799
TEST=A Chromium build can run as the immersive browser on Windows 8.
Review URL: https://chromiumcodereview.appspot.com/10875008
TBR=robertshield@chromium.org
Review URL: https://chromiumcodereview.appspot.com/10919152
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@155435 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'win8')
42 files changed, 0 insertions, 6440 deletions
diff --git a/win8/delegate_execute/chrome_util.cc b/win8/delegate_execute/chrome_util.cc deleted file mode 100644 index 701f2e8..0000000 --- a/win8/delegate_execute/chrome_util.cc +++ /dev/null @@ -1,267 +0,0 @@ -// Copyright (c) 2012 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 "win8/delegate_execute/chrome_util.h" - -#include <atlbase.h> -#include <shlobj.h> -#include <windows.h> - -#include <algorithm> -#include <limits> -#include <string> - -#include "base/file_path.h" -#include "base/file_util.h" -#include "base/md5.h" -#include "base/process_util.h" -#include "base/string_util.h" -#include "base/utf_string_conversions.h" -#include "base/win/registry.h" -#include "base/win/scoped_comptr.h" -#include "base/win/scoped_handle.h" -#include "base/win/win_util.h" -#include "google_update/google_update_idl.h" - -namespace { - -#if defined(GOOGLE_CHROME_BUILD) -const wchar_t kAppUserModelId[] = L"Chrome"; -#else // GOOGLE_CHROME_BUILD -const wchar_t kAppUserModelId[] = L"Chromium"; -#endif // GOOGLE_CHROME_BUILD - -#if defined(GOOGLE_CHROME_BUILD) - -// TODO(grt): These constants live in installer_util. Consider moving them -// into common_constants to allow for reuse. -const FilePath::CharType kNewChromeExe[] = FILE_PATH_LITERAL("new_chrome.exe"); -const wchar_t kRenameCommandValue[] = L"cmd"; -const wchar_t kChromeAppGuid[] = L"{8A69D345-D564-463c-AFF1-A69D9E530F96}"; -const wchar_t kRegPathChromeClient[] = - L"Software\\Google\\Update\\Clients\\" - L"{8A69D345-D564-463c-AFF1-A69D9E530F96}"; -const int kExitCodeRenameSuccessful = 23; - -// Returns the name of the global event used to detect if |chrome_exe| is in -// use by a browser process. -// TODO(grt): Move this somewhere central so it can be used by both this -// IsBrowserRunning (below) and IsBrowserAlreadyRunning (browser_util_win.cc). -string16 GetEventName(const FilePath& chrome_exe) { - static wchar_t const kEventPrefix[] = L"Global\\"; - const size_t prefix_len = arraysize(kEventPrefix) - 1; - string16 name; - name.reserve(prefix_len + chrome_exe.value().size()); - name.assign(kEventPrefix, prefix_len); - name.append(chrome_exe.value()); - std::replace(name.begin() + prefix_len, name.end(), '\\', '!'); - std::transform(name.begin() + prefix_len, name.end(), - name.begin() + prefix_len, tolower); - return name; -} - -// Returns true if |chrome_exe| is in use by a browser process. In this case, -// "in use" means past ChromeBrowserMainParts::PreMainMessageLoopRunImpl. -bool IsBrowserRunning(const FilePath& chrome_exe) { - base::win::ScopedHandle handle(::OpenEvent( - SYNCHRONIZE, FALSE, GetEventName(chrome_exe).c_str())); - if (handle.IsValid()) - return true; - DWORD last_error = ::GetLastError(); - if (last_error != ERROR_FILE_NOT_FOUND) { - AtlTrace("%hs. Failed to open browser event; error %u.\n", __FUNCTION__, - last_error); - } - return false; -} - -// Returns true if the file new_chrome.exe exists in the same directory as -// |chrome_exe|. -bool NewChromeExeExists(const FilePath& chrome_exe) { - FilePath new_chrome_exe(chrome_exe.DirName().Append(kNewChromeExe)); - return file_util::PathExists(new_chrome_exe); -} - -bool GetUpdateCommand(bool is_per_user, string16* update_command) { - const HKEY root = is_per_user ? HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE; - base::win::RegKey key(root, kRegPathChromeClient, KEY_QUERY_VALUE); - - return key.ReadValue(kRenameCommandValue, update_command) == ERROR_SUCCESS; -} - -#endif // GOOGLE_CHROME_BUILD - -// TODO(grt): This code also lives in installer_util. Refactor for reuse. -bool IsPerUserInstall(const FilePath& chrome_exe) { - wchar_t program_files_path[MAX_PATH] = {0}; - if (SUCCEEDED(SHGetFolderPath(NULL, CSIDL_PROGRAM_FILES, NULL, - SHGFP_TYPE_CURRENT, program_files_path))) { - return !StartsWith(chrome_exe.value().c_str(), program_files_path, false); - } else { - NOTREACHED(); - } - return true; -} - -// TODO(gab): This code also lives in shell_util. Refactor for reuse. -string16 ByteArrayToBase32(const uint8* bytes, size_t size) { - static const char kEncoding[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"; - - // Eliminate special cases first. - if (size == 0) { - return string16(); - } else if (size == 1) { - string16 ret; - ret.push_back(kEncoding[(bytes[0] & 0xf8) >> 3]); - ret.push_back(kEncoding[(bytes[0] & 0x07) << 2]); - return ret; - } else if (size >= std::numeric_limits<size_t>::max() / 8) { - // If |size| is too big, the calculation of |encoded_length| below will - // overflow. - AtlTrace("%hs. Byte array is too long.\n", __FUNCTION__); - return string16(); - } - - // Overestimate the number of bits in the string by 4 so that dividing by 5 - // is the equivalent of rounding up the actual number of bits divided by 5. - const size_t encoded_length = (size * 8 + 4) / 5; - - string16 ret; - ret.reserve(encoded_length); - - // A bit stream which will be read from the left and appended to from the - // right as it's emptied. - uint16 bit_stream = (bytes[0] << 8) + bytes[1]; - size_t next_byte_index = 2; - int free_bits = 0; - while (free_bits < 16) { - // Extract the 5 leftmost bits in the stream - ret.push_back(kEncoding[(bit_stream & 0xf800) >> 11]); - bit_stream <<= 5; - free_bits += 5; - - // If there is enough room in the bit stream, inject another byte (if there - // are any left...). - if (free_bits >= 8 && next_byte_index < size) { - free_bits -= 8; - bit_stream += bytes[next_byte_index++] << free_bits; - } - } - - if (ret.length() != encoded_length) { - AtlTrace("%hs. Encoding doesn't match expected length.\n", __FUNCTION__); - return string16(); - } - return ret; -} - -// TODO(gab): This code also lives in shell_util. Refactor for reuse. -bool GetUserSpecificRegistrySuffix(string16* suffix) { - string16 user_sid; - if (!base::win::GetUserSidString(&user_sid)) { - AtlTrace("%hs. GetUserSidString failed.\n", __FUNCTION__); - return false; - } - COMPILE_ASSERT(sizeof(base::MD5Digest) == 16, size_of_MD5_not_as_expected_); - base::MD5Digest md5_digest; - std::string user_sid_ascii(UTF16ToASCII(user_sid)); - base::MD5Sum(user_sid_ascii.c_str(), user_sid_ascii.length(), &md5_digest); - const string16 base32_md5( - ByteArrayToBase32(md5_digest.a, arraysize(md5_digest.a))); - // The value returned by the base32 algorithm above must never change and must - // always be 26 characters long (i.e. if someone ever moves this to base and - // implements the full base32 algorithm (i.e. with appended '=' signs in the - // output), they must provide a flag to allow this method to still request - // the output with no appended '=' signs). - if (base32_md5.length() != 26U) { - AtlTrace("%hs. Base32 encoding of md5 hash is incorrect.\n", __FUNCTION__); - return false; - } - suffix->reserve(base32_md5.length() + 1); - suffix->assign(1, L'.'); - suffix->append(base32_md5); - return true; -} - -} // namespace - -namespace delegate_execute { - -void UpdateChromeIfNeeded(const FilePath& chrome_exe) { -#if defined(GOOGLE_CHROME_BUILD) - // Nothing to do if a browser is already running or if there's no - // new_chrome.exe. - if (IsBrowserRunning(chrome_exe) || !NewChromeExeExists(chrome_exe)) - return; - - base::ProcessHandle process_handle = base::kNullProcessHandle; - - if (IsPerUserInstall(chrome_exe)) { - // Read the update command from the registry. - string16 update_command; - if (!GetUpdateCommand(true, &update_command)) { - AtlTrace("%hs. Failed to read update command from registry.\n", - __FUNCTION__); - } else { - // Run the update command. - base::LaunchOptions launch_options; - launch_options.start_hidden = true; - if (!base::LaunchProcess(update_command, launch_options, - &process_handle)) { - AtlTrace("%hs. Failed to launch command to finalize update; " - "error %u.\n", __FUNCTION__, ::GetLastError()); - process_handle = base::kNullProcessHandle; - } - } - } else { - // Run the update command via Google Update. - HRESULT hr = S_OK; - base::win::ScopedComPtr<IProcessLauncher> process_launcher; - hr = process_launcher.CreateInstance(__uuidof(ProcessLauncherClass)); - if (FAILED(hr)) { - AtlTrace("%hs. Failed to Create ProcessLauncher; hr=0x%X.\n", - __FUNCTION__, hr); - } else { - ULONG_PTR handle = 0; - hr = process_launcher->LaunchCmdElevated( - kChromeAppGuid, kRenameCommandValue, GetCurrentProcessId(), &handle); - if (FAILED(hr)) { - AtlTrace("%hs. Failed to launch command to finalize update; " - "hr=0x%X.\n", __FUNCTION__, hr); - } else { - process_handle = reinterpret_cast<base::ProcessHandle>(handle); - } - } - } - - // Wait for the update to complete and report the results. - if (process_handle != base::kNullProcessHandle) { - int exit_code = 0; - // WaitForExitCode will close the handle in all cases. - if (!base::WaitForExitCode(process_handle, &exit_code)) { - AtlTrace("%hs. Failed to get result when finalizing update.\n", - __FUNCTION__); - } else if (exit_code != kExitCodeRenameSuccessful) { - AtlTrace("%hs. Failed to finalize update with exit code %d.\n", - __FUNCTION__, exit_code); - } else { - AtlTrace("%hs. Finalized pending update.\n", __FUNCTION__); - } - } -#endif -} - -// TODO(gab): This code also lives in shell_util. Refactor for reuse. -string16 GetAppId(const FilePath& chrome_exe) { - string16 app_id(kAppUserModelId); - string16 suffix; - if (IsPerUserInstall(chrome_exe) && - !GetUserSpecificRegistrySuffix(&suffix)) { - AtlTrace("%hs. GetUserSpecificRegistrySuffix failed.\n", - __FUNCTION__); - } - return app_id.append(suffix); -} - -} // delegate_execute diff --git a/win8/delegate_execute/chrome_util.h b/win8/delegate_execute/chrome_util.h deleted file mode 100644 index 634ce6c..0000000 --- a/win8/delegate_execute/chrome_util.h +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) 2012 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. - -#ifndef WIN8_DELEGATE_EXECUTE_CHROME_UTIL_H_ -#define WIN8_DELEGATE_EXECUTE_CHROME_UTIL_H_ - -#include "base/string16.h" - -class FilePath; - -namespace delegate_execute { - -// Finalizes a previously updated installation. -void UpdateChromeIfNeeded(const FilePath& chrome_exe); - -// Returns the appid of the Chrome pointed to by |chrome_exe|. -string16 GetAppId(const FilePath& chrome_exe); - -} // namespace delegate_execute - -#endif // WIN8_DELEGATE_EXECUTE_CHROME_UTIL_H_ diff --git a/win8/delegate_execute/command_execute_impl.cc b/win8/delegate_execute/command_execute_impl.cc deleted file mode 100644 index ef1378a..0000000 --- a/win8/delegate_execute/command_execute_impl.cc +++ /dev/null @@ -1,440 +0,0 @@ -// Copyright (c) 2012 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. -// Implementation of the CommandExecuteImpl class which implements the -// IExecuteCommand and related interfaces for handling ShellExecute based -// launches of the Chrome browser. - -#include "win8/delegate_execute/command_execute_impl.h" - -#include "base/file_util.h" -#include "base/path_service.h" -#include "base/utf_string_conversions.h" -#include "base/win/scoped_co_mem.h" -#include "base/win/scoped_handle.h" -#include "chrome/common/chrome_constants.h" -#include "chrome/common/chrome_paths.h" -#include "chrome/common/chrome_switches.h" -#include "win8/delegate_execute/chrome_util.h" - -// CommandExecuteImpl is resposible for activating chrome in Windows 8. The -// flow is complicated and this tries to highlight the important events. -// The current approach is to have a single instance of chrome either -// running in desktop or metro mode. If there is no current instance then -// the desktop shortcut launches desktop chrome and the metro tile or search -// charm launches metro chrome. -// If chrome is running then focus/activation is given to the existing one -// regarless of what launch point the user used. -// -// The general flow when chrome is the default browser is as follows: -// -// 1- User interacts with launch point (icon, tile, search, shellexec, etc) -// 2- Windows finds the appid for launch item and resolves it to chrome -// 3- Windows activates CommandExecuteImpl inside a surrogate process -// 4- Windows calls the following sequence of entry points: -// CommandExecuteImpl::SetShowWindow -// CommandExecuteImpl::SetPosition -// CommandExecuteImpl::SetDirectory -// CommandExecuteImpl::SetParameter -// CommandExecuteImpl::SetNoShowUI -// CommandExecuteImpl::SetSelection -// CommandExecuteImpl::Initialize -// Up to this point the code basically just gathers values passed in, like -// the launch scheme (or url) and the activation verb. -// 5- Windows calls CommandExecuteImpl::Getvalue() -// Here we need to return AHE_IMMERSIVE or AHE_DESKTOP. That depends on: -// a) if run in high-integrity return AHE_DESKTOP -// b) if chrome is running return the AHE_ mode of chrome -// c) if the current process is inmmersive return AHE_IMMERSIVE -// d) if the protocol is file and IExecuteCommandHost::GetUIMode() is not -// ECHUIM_DESKTOP then return AHE_IMMERSIVE -// e) if none of the above return AHE_DESKTOP -// 6- If we returned AHE_DESKTOP in step 5 then CommandExecuteImpl::Execute() -// is called, here we call GetLaunchMode() which: -// a) if chrome is running return the mode of chrome or -// b) return IExecuteCommandHost::GetUIMode() -// 7- If GetLaunchMode() returns -// a) ECHUIM_DESKTOP we call LaunchDestopChrome() that calls ::CreateProcess -// b) else we call one of the IApplicationActivationManager activation -// functions depending on the parameters passed in step 4. -// -// Some examples will help clarify the common cases. -// -// I - No chrome running, taskbar icon launch: -// a) Scheme is 'file', Verb is 'open' -// b) GetValue() returns at e) step : AHE_DESKTOP -// c) Execute() calls LaunchDestopChrome() -// --> desktop chrome runs -// II- No chrome running, tile activation launch: -// a) Scheme is 'file', Verb is 'open' -// b) GetValue() returns at d) step : AHE_IMMERSIVE -// c) Windows does not call us back and just activates chrome -// --> metro chrome runs -// III- No chrome running, url link click on metro app: -// a) Scheme is 'http', Verb is 'open' -// b) Getvalue() returns at e) step : AHE_DESKTOP -// c) Execute() calls IApplicationActivationManager::ActivateForProtocol -// --> metro chrome runs -// -CommandExecuteImpl::CommandExecuteImpl() - : integrity_level_(base::INTEGRITY_UNKNOWN), - launch_scheme_(INTERNET_SCHEME_DEFAULT), - chrome_mode_(ECHUIM_SYSTEM_LAUNCHER) { - memset(&start_info_, 0, sizeof(start_info_)); - start_info_.cb = sizeof(start_info_); - // We need to query the user data dir of chrome so we need chrome's - // path provider. - chrome::RegisterPathProvider(); -} - -// CommandExecuteImpl -STDMETHODIMP CommandExecuteImpl::SetKeyState(DWORD key_state) { - AtlTrace("In %hs\n", __FUNCTION__); - return S_OK; -} - -STDMETHODIMP CommandExecuteImpl::SetParameters(LPCWSTR params) { - AtlTrace("In %hs [%S]\n", __FUNCTION__, params); - if (params) { - parameters_ = params; - } - return S_OK; -} - -STDMETHODIMP CommandExecuteImpl::SetPosition(POINT pt) { - AtlTrace("In %hs\n", __FUNCTION__); - return S_OK; -} - -STDMETHODIMP CommandExecuteImpl::SetShowWindow(int show) { - AtlTrace("In %hs show=%d\n", __FUNCTION__, show); - start_info_.wShowWindow = show; - start_info_.dwFlags |= STARTF_USESHOWWINDOW; - return S_OK; -} - -STDMETHODIMP CommandExecuteImpl::SetNoShowUI(BOOL no_show_ui) { - AtlTrace("In %hs no_show=%d\n", __FUNCTION__, no_show_ui); - return S_OK; -} - -STDMETHODIMP CommandExecuteImpl::SetDirectory(LPCWSTR directory) { - AtlTrace("In %hs\n", __FUNCTION__); - return S_OK; -} - -STDMETHODIMP CommandExecuteImpl::GetValue(enum AHE_TYPE* pahe) { - AtlTrace("In %hs\n", __FUNCTION__); - - if (!GetLaunchScheme(&display_name_, &launch_scheme_)) { - AtlTrace("Failed to get scheme, E_FAIL\n"); - return E_FAIL; - } - - if (integrity_level_ == base::HIGH_INTEGRITY) { - // Metro mode apps don't work in high integrity mode. - AtlTrace("High integrity, AHE_DESKTOP\n"); - *pahe = AHE_DESKTOP; - return S_OK; - } - - FilePath user_data_dir; - if (!PathService::Get(chrome::DIR_USER_DATA, &user_data_dir)) { - AtlTrace("Failed to get chrome's data dir path, E_FAIL\n"); - return E_FAIL; - } - - HWND chrome_window = ::FindWindowEx(HWND_MESSAGE, NULL, - chrome::kMessageWindowClass, - user_data_dir.value().c_str()); - if (chrome_window) { - AtlTrace("Found chrome window %p\n", chrome_window); - // The failure cases below are deemed to happen due to the inherently racy - // procedure of going from chrome's window to process handle during which - // chrome might have exited. Failing here would probably just cause the - // user to retry at which point we would do the right thing. - DWORD chrome_pid = 0; - ::GetWindowThreadProcessId(chrome_window, &chrome_pid); - if (!chrome_pid) { - AtlTrace("Failed to get chrome's PID, E_FAIL\n"); - return E_FAIL; - } - base::win::ScopedHandle process( - ::OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, chrome_pid)); - if (!process.IsValid()) { - AtlTrace("Failed to open chrome's process [%d], E_FAIL\n", chrome_pid); - return E_FAIL; - } - if (IsImmersiveProcess(process.Get())) { - AtlTrace("Chrome [%d] is inmmersive, AHE_IMMERSIVE\n", chrome_pid); - chrome_mode_ = ECHUIM_IMMERSIVE; - *pahe = AHE_IMMERSIVE; - } else { - AtlTrace("Chrome [%d] is Desktop, AHE_DESKTOP\n"); - chrome_mode_ = ECHUIM_DESKTOP; - *pahe = AHE_DESKTOP; - } - return S_OK; - } - - if (IsImmersiveProcess(GetCurrentProcess())) { - AtlTrace("Current process is inmmersive, AHE_IMMERSIVE\n"); - *pahe = AHE_IMMERSIVE; - return S_OK; - } - - if ((launch_scheme_ == INTERNET_SCHEME_FILE) && - (GetLaunchMode() != ECHUIM_DESKTOP)) { - AtlTrace("INTERNET_SCHEME_FILE, mode != ECHUIM_DESKTOP, AHE_IMMERSIVE\n"); - *pahe = AHE_IMMERSIVE; - return S_OK; - } - - AtlTrace("Fallback is AHE_DESKTOP\n"); - *pahe = AHE_DESKTOP; - return S_OK; -} - -STDMETHODIMP CommandExecuteImpl::Execute() { - AtlTrace("In %hs\n", __FUNCTION__); - - if (integrity_level_ == base::HIGH_INTEGRITY) - return LaunchDesktopChrome(); - - EC_HOST_UI_MODE mode = GetLaunchMode(); - if (mode == ECHUIM_DESKTOP) - return LaunchDesktopChrome(); - - HRESULT hr = E_FAIL; - CComPtr<IApplicationActivationManager> activation_manager; - hr = activation_manager.CoCreateInstance(CLSID_ApplicationActivationManager); - if (!activation_manager) { - AtlTrace("Failed to get the activation manager, error 0x%x\n", hr); - return S_OK; - } - - string16 app_id = delegate_execute::GetAppId(chrome_exe_); - - DWORD pid = 0; - if (launch_scheme_ == INTERNET_SCHEME_FILE) { - AtlTrace("Activating for file\n"); - hr = activation_manager->ActivateApplication(app_id.c_str(), - verb_.c_str(), - AO_NOERRORUI, - &pid); - } else { - AtlTrace("Activating for protocol\n"); - hr = activation_manager->ActivateForProtocol(app_id.c_str(), - item_array_, - &pid); - } - if (hr == E_APPLICATION_NOT_REGISTERED) { - AtlTrace("Metro chrome is not registered, launching in desktop\n"); - return LaunchDesktopChrome(); - } - AtlTrace("Metro Chrome launch, pid=%d, returned 0x%x\n", pid, hr); - return S_OK; -} - -STDMETHODIMP CommandExecuteImpl::Initialize(LPCWSTR name, - IPropertyBag* bag) { - AtlTrace("In %hs\n", __FUNCTION__); - if (!FindChromeExe(&chrome_exe_)) - return E_FAIL; - delegate_execute::UpdateChromeIfNeeded(chrome_exe_); - if (name) { - AtlTrace("Verb is %S\n", name); - verb_ = name; - } - - base::GetProcessIntegrityLevel(base::GetCurrentProcessHandle(), - &integrity_level_); - if (integrity_level_ == base::HIGH_INTEGRITY) { - AtlTrace("Delegate execute launched in high integrity level\n"); - } - return S_OK; -} - -STDMETHODIMP CommandExecuteImpl::SetSelection(IShellItemArray* item_array) { - AtlTrace("In %hs\n", __FUNCTION__); - item_array_ = item_array; - return S_OK; -} - -STDMETHODIMP CommandExecuteImpl::GetSelection(REFIID riid, void** selection) { - AtlTrace("In %hs\n", __FUNCTION__); - return S_OK; -} - -STDMETHODIMP CommandExecuteImpl::AllowForegroundTransfer(void* reserved) { - AtlTrace("In %hs\n", __FUNCTION__); - return S_OK; -} - -// Returns false if chrome.exe cannot be found. -// static -bool CommandExecuteImpl::FindChromeExe(FilePath* chrome_exe) { - AtlTrace("In %hs\n", __FUNCTION__); - // Look for chrome.exe one folder above delegate_execute.exe (as expected in - // Chrome installs). Failing that, look for it alonside delegate_execute.exe. - FilePath dir_exe; - if (!PathService::Get(base::DIR_EXE, &dir_exe)) { - AtlTrace("Failed to get current exe path\n"); - return false; - } - - *chrome_exe = dir_exe.DirName().Append(chrome::kBrowserProcessExecutableName); - if (!file_util::PathExists(*chrome_exe)) { - *chrome_exe = dir_exe.Append(chrome::kBrowserProcessExecutableName); - if (!file_util::PathExists(*chrome_exe)) { - AtlTrace("Failed to find chrome exe file\n"); - return false; - } - } - - AtlTrace("Got chrome exe path as %ls\n", chrome_exe->value().c_str()); - return true; -} - -bool CommandExecuteImpl::GetLaunchScheme( - string16* display_name, INTERNET_SCHEME* scheme) { - if (!item_array_) - return false; - - ATLASSERT(display_name); - ATLASSERT(scheme); - - DWORD count = 0; - item_array_->GetCount(&count); - - if (count != 1) { - AtlTrace("Cannot handle %d elements in the IShellItemArray\n", count); - return false; - } - - CComPtr<IEnumShellItems> items; - item_array_->EnumItems(&items); - CComPtr<IShellItem> shell_item; - HRESULT hr = items->Next(1, &shell_item, &count); - if (hr != S_OK) { - AtlTrace("Failed to read element from the IShellItemsArray\n"); - return false; - } - - base::win::ScopedCoMem<wchar_t> name; - hr = shell_item->GetDisplayName(SIGDN_URL, &name); - if (hr != S_OK) { - AtlTrace("Failed to get display name\n"); - return false; - } - - AtlTrace("Display name is [%ls]\n", name); - - wchar_t scheme_name[16]; - URL_COMPONENTS components = {0}; - components.lpszScheme = scheme_name; - components.dwSchemeLength = sizeof(scheme_name)/sizeof(scheme_name[0]); - - components.dwStructSize = sizeof(components); - if (!InternetCrackUrlW(name, 0, 0, &components)) { - AtlTrace("Failed to crack url %ls\n", name); - return false; - } - - AtlTrace("Launch scheme is [%ls] (%d)\n", scheme_name, components.nScheme); - *display_name = name; - *scheme = components.nScheme; - return true; -} - -HRESULT CommandExecuteImpl::LaunchDesktopChrome() { - AtlTrace("In %hs\n", __FUNCTION__); - string16 display_name = display_name_; - - switch (launch_scheme_) { - case INTERNET_SCHEME_FILE: - // If anything other than chrome.exe is passed in the display name we - // should honor it. For e.g. If the user clicks on a html file when - // chrome is the default we should treat it as a parameter to be passed - // to chrome. - if (display_name.find(L"chrome.exe") != string16::npos) - display_name.clear(); - break; - - default: - break; - } - - string16 command_line = L"\""; - command_line += chrome_exe_.value(); - command_line += L"\""; - - if (!parameters_.empty()) { - AtlTrace("Adding parameters %ls to command line\n", parameters_.c_str()); - command_line += L" "; - command_line += parameters_.c_str(); - } - - if (!display_name.empty()) { - command_line += L" -- "; - command_line += display_name; - } - - AtlTrace("Formatted command line is %ls\n", command_line.c_str()); - - PROCESS_INFORMATION proc_info = {0}; - BOOL ret = CreateProcess(NULL, const_cast<LPWSTR>(command_line.c_str()), - NULL, NULL, FALSE, 0, NULL, NULL, &start_info_, - &proc_info); - if (ret) { - AtlTrace("Process id is %d\n", proc_info.dwProcessId); - CloseHandle(proc_info.hProcess); - CloseHandle(proc_info.hThread); - } else { - AtlTrace("Process launch failed, error %d\n", ::GetLastError()); - } - - return S_OK; -} - -EC_HOST_UI_MODE CommandExecuteImpl::GetLaunchMode() { - // We are to return chrome's mode if chrome exists else we query our embedder - // IServiceProvider and learn the mode from them. - static bool launch_mode_determined = false; - static EC_HOST_UI_MODE launch_mode = ECHUIM_DESKTOP; - - const char* modes[] = { "Desktop", "Inmmersive", "SysLauncher", "??" }; - - if (launch_mode_determined) - return launch_mode; - - if (chrome_mode_ != ECHUIM_SYSTEM_LAUNCHER) { - launch_mode = chrome_mode_; - AtlTrace("Launch mode is that of chrome, %s\n", modes[launch_mode]); - launch_mode_determined = true; - return launch_mode; - } - - if (parameters_ == ASCIIToWide(switches::kForceImmersive)) { - launch_mode = ECHUIM_IMMERSIVE; - AtlTrace("Launch mode forced to %s\n", modes[launch_mode]); - launch_mode_determined = true; - return launch_mode; - } - - CComPtr<IExecuteCommandHost> host; - CComQIPtr<IServiceProvider> service_provider = m_spUnkSite; - if (service_provider) { - service_provider->QueryService(IID_IExecuteCommandHost, &host); - if (host) { - host->GetUIMode(&launch_mode); - } else { - AtlTrace("Failed to get IID_IExecuteCommandHost. Assuming desktop\n"); - } - } else { - AtlTrace("Failed to get IServiceProvider. Assuming desktop mode\n"); - } - AtlTrace("Launch mode is %s\n", modes[launch_mode]); - launch_mode_determined = true; - return launch_mode; -} diff --git a/win8/delegate_execute/command_execute_impl.h b/win8/delegate_execute/command_execute_impl.h deleted file mode 100644 index 5a1a95c..0000000 --- a/win8/delegate_execute/command_execute_impl.h +++ /dev/null @@ -1,105 +0,0 @@ -// Copyright (c) 2012 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 <atlbase.h> -#include <atlcom.h> -#include <atlctl.h> -#include <ShObjIdl.h> -#include <WinInet.h> - -#include <string> - -#include "base/file_path.h" -#include "base/process_util.h" -#include "win8/delegate_execute/resource.h" // main symbols - -using namespace ATL; - -EXTERN_C const GUID CLSID_CommandExecuteImpl; - -// CommandExecuteImpl -// This class implements the IExecuteCommand and related interfaces for -// handling ShellExecute launches of the Chrome browser, i.e. whether to -// launch Chrome in metro mode or desktop mode. -#if defined(GOOGLE_CHROME_BUILD) -class ATL_NO_VTABLE DECLSPEC_UUID("5C65F4B0-3651-4514-B207-D10CB699B14B") - CommandExecuteImpl -#else // GOOGLE_CHROME_BUILD -class ATL_NO_VTABLE DECLSPEC_UUID("A2DF06F9-A21A-44A8-8A99-8B9C84F29160") - CommandExecuteImpl -#endif // GOOGLE_CHROME_BUILD - : public CComObjectRootEx<CComSingleThreadModel>, - public CComCoClass<CommandExecuteImpl, &CLSID_CommandExecuteImpl>, - public IExecuteCommand, - public IObjectWithSiteImpl<CommandExecuteImpl>, - public IInitializeCommand, - public IObjectWithSelection, - public IExecuteCommandApplicationHostEnvironment, - public IForegroundTransfer { - public: - CommandExecuteImpl(); - - DECLARE_REGISTRY_RESOURCEID(IDR_COMMANDEXECUTEIMPL) - - BEGIN_COM_MAP(CommandExecuteImpl) - COM_INTERFACE_ENTRY(IExecuteCommand) - COM_INTERFACE_ENTRY(IObjectWithSite) - COM_INTERFACE_ENTRY(IInitializeCommand) - COM_INTERFACE_ENTRY(IObjectWithSelection) - COM_INTERFACE_ENTRY(IExecuteCommandApplicationHostEnvironment) - COM_INTERFACE_ENTRY(IForegroundTransfer) - END_COM_MAP() - - DECLARE_PROTECT_FINAL_CONSTRUCT() - - HRESULT FinalConstruct() { - return S_OK; - } - - void FinalRelease() { - } - - public: - // IExecuteCommand - STDMETHOD(SetKeyState)(DWORD key_state); - STDMETHOD(SetParameters)(LPCWSTR params); - STDMETHOD(SetPosition)(POINT pt); - STDMETHOD(SetShowWindow)(int show); - STDMETHOD(SetNoShowUI)(BOOL no_show_ui); - STDMETHOD(SetDirectory)(LPCWSTR directory); - STDMETHOD(Execute)(void); - - // IInitializeCommand - STDMETHOD(Initialize)(LPCWSTR name, IPropertyBag* bag); - - // IObjectWithSelection - STDMETHOD(SetSelection)(IShellItemArray* item_array); - STDMETHOD(GetSelection)(REFIID riid, void** selection); - - // IExecuteCommandApplicationHostEnvironment - STDMETHOD(GetValue)(enum AHE_TYPE* pahe); - - // IForegroundTransfer - STDMETHOD(AllowForegroundTransfer)(void* reserved); - - private: - static bool FindChromeExe(FilePath* chrome_exe); - bool GetLaunchScheme(string16* display_name, INTERNET_SCHEME* scheme); - HRESULT LaunchDesktopChrome(); - // Returns the launch mode, i.e. desktop launch/metro launch, etc. - EC_HOST_UI_MODE GetLaunchMode(); - - CComPtr<IShellItemArray> item_array_; - string16 parameters_; - FilePath chrome_exe_; - STARTUPINFO start_info_; - string16 verb_; - string16 display_name_; - INTERNET_SCHEME launch_scheme_; - - base::IntegrityLevel integrity_level_; - EC_HOST_UI_MODE chrome_mode_; -}; - -OBJECT_ENTRY_AUTO(__uuidof(CommandExecuteImpl), CommandExecuteImpl) diff --git a/win8/delegate_execute/command_execute_impl.rgs b/win8/delegate_execute/command_execute_impl.rgs deleted file mode 100644 index 4f1aba3..0000000 --- a/win8/delegate_execute/command_execute_impl.rgs +++ /dev/null @@ -1,10 +0,0 @@ -HKCR { - NoRemove CLSID { - ForceRemove '%DELEGATE_EXECUTE_CLSID%' = s 'CommandExecuteImpl Class' { - ForceRemove Programmable - LocalServer32 = s '%MODULE%' { - val ServerExecutable = s '%MODULE_RAW%' - } - } - } -} diff --git a/win8/delegate_execute/delegate_execute.cc b/win8/delegate_execute/delegate_execute.cc deleted file mode 100644 index 9f3430c..0000000 --- a/win8/delegate_execute/delegate_execute.cc +++ /dev/null @@ -1,120 +0,0 @@ -// Copyright (c) 2012 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 <atlbase.h> -#include <atlcom.h> -#include <atlctl.h> -#include <initguid.h> -#include <shellapi.h> - -#include "base/at_exit.h" -#include "base/command_line.h" -#include "base/file_util.h" -#include "base/string16.h" -#include "base/string_number_conversions.h" -#include "base/utf_string_conversions.h" -#include "base/win/scoped_com_initializer.h" -#include "base/win/scoped_handle.h" -#include "chrome/common/chrome_switches.h" -#include "command_execute_impl.h" -#include "win8/delegate_execute/delegate_execute_operation.h" -#include "win8/delegate_execute/resource.h" - -using namespace ATL; - -class DelegateExecuteModule - : public ATL::CAtlExeModuleT< DelegateExecuteModule > { - public : - typedef ATL::CAtlExeModuleT<DelegateExecuteModule> ParentClass; - - DECLARE_REGISTRY_APPID_RESOURCEID(IDR_DELEGATEEXECUTE, - "{B1935DA1-112F-479A-975B-AB8588ABA636}") - - virtual HRESULT AddCommonRGSReplacements(IRegistrarBase* registrar) throw() { - AtlTrace(L"In %hs\n", __FUNCTION__); - HRESULT hr = ParentClass::AddCommonRGSReplacements(registrar); - if (FAILED(hr)) - return hr; - - wchar_t delegate_execute_clsid[MAX_PATH] = {0}; - if (!StringFromGUID2(__uuidof(CommandExecuteImpl), delegate_execute_clsid, - ARRAYSIZE(delegate_execute_clsid))) { - ATLASSERT(false); - return E_FAIL; - } - - hr = registrar->AddReplacement(L"DELEGATE_EXECUTE_CLSID", - delegate_execute_clsid); - ATLASSERT(SUCCEEDED(hr)); - return hr; - } -}; - -DelegateExecuteModule _AtlModule; - -// Relaunch metro Chrome by ShellExecute on |shortcut| with --force-immersive. -// |handle_value| is an optional handle on which this function will wait before -// performing the relaunch. -int RelaunchChrome(const FilePath& shortcut, const string16& handle_value) { - base::win::ScopedHandle handle; - - if (!handle_value.empty()) { - uint32 the_handle = 0; - if (!base::StringToUint(handle_value, &the_handle)) { - // Failed to parse the handle value. Skip the wait but proceed with the - // relaunch. - AtlTrace(L"Failed to parse handle value %ls\n", handle_value.c_str()); - } else { - handle.Set(reinterpret_cast<HANDLE>(the_handle)); - } - } - - if (handle.IsValid()) { - AtlTrace(L"Waiting for chrome.exe to exit.\n"); - DWORD result = ::WaitForSingleObject(handle, 10 * 1000); - AtlTrace(L"And we're back.\n"); - if (result != WAIT_OBJECT_0) { - AtlTrace(L"Failed to wait for parent to exit; result=%u.\n", result); - // This could mean that Chrome has hung. Conservatively proceed with - // the relaunch anyway. - } - handle.Close(); - } - - base::win::ScopedCOMInitializer com_initializer; - - AtlTrace(L"Launching Chrome via %ls.\n", shortcut.value().c_str()); - int ser = reinterpret_cast<int>( - ::ShellExecute(NULL, NULL, shortcut.value().c_str(), - ASCIIToWide(switches::kForceImmersive).c_str(), NULL, - SW_SHOWNORMAL)); - AtlTrace(L"ShellExecute returned %d.\n", ser); - return ser <= 32; -} - -// -extern "C" int WINAPI _tWinMain(HINSTANCE , HINSTANCE, - LPTSTR, int nShowCmd) { - using delegate_execute::DelegateExecuteOperation; - base::AtExitManager exit_manager; - - CommandLine::Init(0, NULL); - CommandLine* cmd_line = CommandLine::ForCurrentProcess(); - DelegateExecuteOperation operation; - - operation.Initialize(cmd_line); - switch (operation.operation_type()) { - case DelegateExecuteOperation::EXE_MODULE: - return _AtlModule.WinMain(nShowCmd); - - case DelegateExecuteOperation::RELAUNCH_CHROME: - return RelaunchChrome(operation.relaunch_shortcut(), - cmd_line->GetSwitchValueNative(switches::kWaitForHandle)); - - default: - NOTREACHED(); - } - - return 1; -} diff --git a/win8/delegate_execute/delegate_execute.gyp b/win8/delegate_execute/delegate_execute.gyp deleted file mode 100644 index e4feff4..0000000 --- a/win8/delegate_execute/delegate_execute.gyp +++ /dev/null @@ -1,46 +0,0 @@ -# Copyright (c) 2012 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. -{ - 'variables': { - 'chromium_code': 1, - }, - 'includes': [ - '../../build/win_precompile.gypi', - ], - 'targets': [ - { - 'target_name': 'delegate_execute', - 'type': 'executable', - 'dependencies': [ - '../../base/base.gyp:base', - '../../chrome/chrome.gyp:installer_util', - '../../google_update/google_update.gyp:google_update', - '../../win8/win8.gyp:check_sdk_patch', - ], - 'sources': [ - 'chrome_util.cc', - 'chrome_util.h', - 'command_execute_impl.cc', - 'command_execute_impl.h', - 'command_execute_impl.rgs', - 'delegate_execute.cc', - 'delegate_execute.rc', - 'delegate_execute.rgs', - 'delegate_execute_operation.cc', - 'delegate_execute_operation.h', - 'resource.h', - ], - 'defines': [ - # This define is required to pull in the new Win8 interfaces from - # system headers like ShObjIdl.h - 'NTDDI_VERSION=0x06020000', - ], - 'msvs_settings': { - 'VCLinkerTool': { - 'SubSystem': '2', # Set /SUBSYSTEM:WINDOWS - }, - }, - }, - ], -} diff --git a/win8/delegate_execute/delegate_execute.rgs b/win8/delegate_execute/delegate_execute.rgs deleted file mode 100644 index e7d3740..0000000 --- a/win8/delegate_execute/delegate_execute.rgs +++ /dev/null @@ -1,3 +0,0 @@ -HKCR -{ -} diff --git a/win8/delegate_execute/delegate_execute_operation.cc b/win8/delegate_execute/delegate_execute_operation.cc deleted file mode 100644 index e6823f0..0000000 --- a/win8/delegate_execute/delegate_execute_operation.cc +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (c) 2012 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 "win8/delegate_execute/delegate_execute_operation.h" - -#include "base/command_line.h" -#include "chrome/common/chrome_switches.h" - -namespace delegate_execute { - -DelegateExecuteOperation::DelegateExecuteOperation() - : operation_type_(EXE_MODULE) { -} - -DelegateExecuteOperation::~DelegateExecuteOperation() { - Clear(); -} - -void DelegateExecuteOperation::Initialize(const CommandLine* command_line) { - Clear(); - - // --relaunch-shortcut=PathToShortcut triggers the relaunch Chrome operation. - FilePath shortcut( - command_line->GetSwitchValuePath(switches::kRelaunchShortcut)); - if (!shortcut.empty()) { - relaunch_shortcut_ = shortcut; - operation_type_ = RELAUNCH_CHROME; - } -} - -void DelegateExecuteOperation::Clear() { - operation_type_ = EXE_MODULE; - relaunch_shortcut_.clear(); -} - -} // namespace delegate_execute diff --git a/win8/delegate_execute/delegate_execute_operation.h b/win8/delegate_execute/delegate_execute_operation.h deleted file mode 100644 index 59acfd7a..0000000 --- a/win8/delegate_execute/delegate_execute_operation.h +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright (c) 2012 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. - -#ifndef WIN8_DELEGATE_EXECUTE_DELEGATE_EXECUTE_OPERATION_H_ -#define WIN8_DELEGATE_EXECUTE_DELEGATE_EXECUTE_OPERATION_H_ - -#include <atldef.h> - -#include "base/basictypes.h" -#include "base/file_path.h" - -class CommandLine; - -namespace delegate_execute { - -// Parses a portion of the DelegateExecute handler's command line to determine -// the desired operation. -class DelegateExecuteOperation { - public: - enum OperationType { - EXE_MODULE, - RELAUNCH_CHROME, - }; - - DelegateExecuteOperation(); - ~DelegateExecuteOperation(); - - void Initialize(const CommandLine* command_line); - - OperationType operation_type() const { - return operation_type_; - } - - // Returns the argument to the --relaunch-shortcut switch. Valid only when - // the operation is RELAUNCH_CHROME. - const FilePath& relaunch_shortcut() const { - ATLASSERT(operation_type_ == RELAUNCH_CHROME); - return relaunch_shortcut_; - } - - private: - void Clear(); - - OperationType operation_type_; - FilePath relaunch_shortcut_; - DISALLOW_COPY_AND_ASSIGN(DelegateExecuteOperation); -}; - -} // namespace delegate_execute - -#endif // WIN8_DELEGATE_EXECUTE_DELEGATE_EXECUTE_OPERATION_H_ diff --git a/win8/delegate_execute/post_build.bat b/win8/delegate_execute/post_build.bat deleted file mode 100644 index 8aa9a76..0000000 --- a/win8/delegate_execute/post_build.bat +++ /dev/null @@ -1,3 +0,0 @@ -REM invoke as: post_build.bat OUTPUT_PATH_TO_EXE PATH_TO_CHROME_ROOT CONFIGURATION
-mkdir %2\build\%3
-copy %1 %2\build\%3\
diff --git a/win8/delegate_execute/resource.h b/win8/delegate_execute/resource.h deleted file mode 100644 index cb81bf0..0000000 --- a/win8/delegate_execute/resource.h +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) 2012 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. - -// {{NO_DEPENDENCIES}} -// Microsoft Visual C++ generated include file. -// Used by DelegateExecute.rc -// -#define IDS_PROJNAME 100 -#define IDR_DELEGATEEXECUTE 101 -#define IDR_COMMANDEXECUTEIMPL 106 - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 201 -#define _APS_NEXT_COMMAND_VALUE 32768 -#define _APS_NEXT_CONTROL_VALUE 201 -#define _APS_NEXT_SYMED_VALUE 107 -#endif -#endif diff --git a/win8/metro_driver/OWNERS b/win8/metro_driver/OWNERS deleted file mode 100644 index 3802937..0000000 --- a/win8/metro_driver/OWNERS +++ /dev/null @@ -1,5 +0,0 @@ -ananta@chromium.org -cpu@chromium.org -grt@chromium.org -mad@chromium.org -robertshield@chromium.org
\ No newline at end of file diff --git a/win8/metro_driver/chrome_app_view.cc b/win8/metro_driver/chrome_app_view.cc deleted file mode 100644 index 7d5580e..0000000 --- a/win8/metro_driver/chrome_app_view.cc +++ /dev/null @@ -1,1059 +0,0 @@ -// Copyright (c) 2012 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 "win8/metro_driver/stdafx.h" -#include "win8/metro_driver/chrome_app_view.h" - -#include <algorithm> -#include <windows.applicationModel.datatransfer.h> -#include <windows.foundation.h> - -#include "base/bind.h" -#include "base/message_loop.h" -#include "base/win/metro.h" - -// This include allows to send WM_SYSCOMMANDs to chrome. -#include "chrome/app/chrome_command_ids.h" -#include "win8/metro_driver/winrt_utils.h" -#include "ui/base/ui_base_switches.h" - -typedef winfoundtn::ITypedEventHandler< - winapp::Core::CoreApplicationView*, - winapp::Activation::IActivatedEventArgs*> ActivatedHandler; - -typedef winfoundtn::ITypedEventHandler< - winui::Core::CoreWindow*, - winui::Core::WindowSizeChangedEventArgs*> SizeChangedHandler; - -typedef winfoundtn::ITypedEventHandler< - winui::Input::EdgeGesture*, - winui::Input::EdgeGestureEventArgs*> EdgeEventHandler; - -typedef winfoundtn::ITypedEventHandler< - winapp::DataTransfer::DataTransferManager*, - winapp::DataTransfer::DataRequestedEventArgs*> ShareDataRequestedHandler; - -typedef winfoundtn::ITypedEventHandler< - winui::ViewManagement::InputPane*, - winui::ViewManagement::InputPaneVisibilityEventArgs*> - InputPaneEventHandler; - -struct Globals globals; - -// TODO(ananta) -// Remove this once we consolidate metro driver with chrome. -const wchar_t kMetroGetCurrentTabInfoMessage[] = - L"CHROME_METRO_GET_CURRENT_TAB_INFO"; - -static const int kFlipWindowsHotKeyId = 0x0000baba; - -static const int kAnimateWindowTimeoutMs = 200; - -static const int kCheckOSKDelayMs = 300; - -const wchar_t kOSKClassName[] = L"IPTip_Main_Window"; - -static const int kOSKAdjustmentOffset = 20; - -namespace { - -void AdjustToFitWindow(HWND hwnd, int flags) { - RECT rect = {0}; - ::GetWindowRect(globals.core_window, &rect); - int cx = rect.right - rect.left; - int cy = rect.bottom - rect.top; - - ::SetWindowPos(hwnd, HWND_TOP, - rect.left, rect.top, cx, cy, - SWP_NOZORDER | flags); -} - -void AdjustFrameWindowStyleForMetro(HWND hwnd) { - DVLOG(1) << __FUNCTION__; - // Ajust the frame so the live preview works and the frame buttons dissapear. - ::SetWindowLong(hwnd, GWL_STYLE, - WS_POPUP | (::GetWindowLong(hwnd, GWL_STYLE) & - ~(WS_MAXIMIZE | WS_CAPTION | WS_THICKFRAME | WS_SYSMENU))); - ::SetWindowLong(hwnd, GWL_EXSTYLE, - ::GetWindowLong(hwnd, GWL_EXSTYLE) & ~(WS_EX_DLGMODALFRAME | - WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE | WS_EX_STATICEDGE)); - AdjustToFitWindow(hwnd, SWP_FRAMECHANGED | SWP_NOACTIVATE); -} - -void SetFrameWindowInternal(HWND hwnd) { - DVLOG(1) << __FUNCTION__ << ", hwnd=" << LONG_PTR(hwnd); - - HWND current_top_frame = - !globals.host_windows.empty() ? globals.host_windows.front().first : NULL; - if (hwnd != current_top_frame && IsWindow(current_top_frame)) { - DVLOG(1) << "Hiding current top window, hwnd=" - << LONG_PTR(current_top_frame); - ::ShowWindow(current_top_frame, SW_HIDE); - } - - // If chrome opens a url in a foreground tab, it may call SetFrameWindow - // again. Ensure that we don't have dups. - globals.host_windows.remove_if([hwnd](std::pair<HWND, bool>& item) { - return (item.first == hwnd); - }); - - globals.host_windows.push_front(std::make_pair(hwnd, false)); - - AdjustFrameWindowStyleForMetro(hwnd); -} - -void CloseFrameWindowInternal(HWND hwnd) { - DVLOG(1) << __FUNCTION__ << ", hwnd=" << LONG_PTR(hwnd); - - globals.host_windows.remove_if([hwnd](std::pair<HWND, bool>& item) { - return (item.first == hwnd); - }); - - if (globals.host_windows.size() > 0) { - DVLOG(1) << "Making new top frame window visible:" - << reinterpret_cast<int>(globals.host_windows.front().first); - AdjustToFitWindow(globals.host_windows.front().first, SWP_SHOWWINDOW); - } else { - // time to quit - DVLOG(1) << "Last host window closed. Calling Exit()."; - globals.app_exit->Exit(); - } -} - -void FlipFrameWindowsInternal() { - DVLOG(1) << __FUNCTION__; - // Get the first window in the frame windows queue and push it to the end. - // Metroize the next window in the queue. - if (globals.host_windows.size() > 1) { - std::pair<HWND, bool> current_top_window = globals.host_windows.front(); - globals.host_windows.pop_front(); - - DVLOG(1) << "Making new top frame window visible:" - << reinterpret_cast<int>(globals.host_windows.front().first); - - AdjustToFitWindow(globals.host_windows.front().first, SWP_SHOWWINDOW); - - DVLOG(1) << "Hiding current top window:" - << reinterpret_cast<int>(current_top_window.first); - AnimateWindow(current_top_window.first, kAnimateWindowTimeoutMs, - AW_HIDE | AW_HOR_POSITIVE | AW_SLIDE); - - globals.host_windows.push_back(current_top_window); - } -} - -} // namespace - -HRESULT ChromeAppView::TileRequestCreateDone( - winfoundtn::IAsyncOperation<bool>* async, - AsyncStatus status) { - if (status == Completed) { - unsigned char result; - CheckHR(async->GetResults(&result)); - DVLOG(1) << __FUNCTION__ << " result " << static_cast<int>(result); - } else { - LOG(ERROR) << __FUNCTION__ << " Unexpected async status " << status; - } - - return S_OK; -} - -void ChromeAppView::DisplayNotification( - const ToastNotificationHandler::DesktopNotification& notification) { - DVLOG(1) << __FUNCTION__; - - if (IsValidNotification(notification.id)) { - NOTREACHED() << "Duplicate notification id passed in."; - return; - } - - base::AutoLock lock(notification_lock_); - - ToastNotificationHandler* notification_handler = - new ToastNotificationHandler; - - notification_map_[notification.id].reset(notification_handler); - notification_handler->DisplayNotification(notification); -} - -void ChromeAppView::CancelNotification(const std::string& notification) { - DVLOG(1) << __FUNCTION__; - - base::AutoLock lock(notification_lock_); - - NotificationMap::iterator index = notification_map_.find(notification); - if (index == notification_map_.end()) { - NOTREACHED() << "Invalid notification:" << notification.c_str(); - return; - } - - scoped_ptr<ToastNotificationHandler> notification_handler( - index->second.release()); - - notification_map_.erase(index); - - notification_handler->CancelNotification(); -} - -// Returns true if the notification passed in is valid. -bool ChromeAppView::IsValidNotification(const std::string& notification) { - DVLOG(1) << __FUNCTION__; - - base::AutoLock lock(notification_lock_); - return notification_map_.find(notification) != notification_map_.end(); -} - -void ChromeAppView::ShowDialogBox( - const MetroDialogBox::DialogBoxInfo& dialog_box_info) { - VLOG(1) << __FUNCTION__; - dialog_box_.Show(dialog_box_info); -} - -void ChromeAppView::DismissDialogBox() { - VLOG(1) << __FUNCTION__; - dialog_box_.Dismiss(); -} - -// static -HRESULT ChromeAppView::Unsnap() { - mswr::ComPtr<winui::ViewManagement::IApplicationViewStatics> view_statics; - HRESULT hr = winrt_utils::CreateActivationFactory( - RuntimeClass_Windows_UI_ViewManagement_ApplicationView, - view_statics.GetAddressOf()); - CheckHR(hr); - - winui::ViewManagement::ApplicationViewState state = - winui::ViewManagement::ApplicationViewState_FullScreenLandscape; - hr = view_statics->get_Value(&state); - CheckHR(hr); - - if (state == winui::ViewManagement::ApplicationViewState_Snapped) { - boolean success = FALSE; - hr = view_statics->TryUnsnap(&success); - - if (FAILED(hr) || !success) { - LOG(ERROR) << "Failed to unsnap. Error 0x" << hr; - if (SUCCEEDED(hr)) - hr = E_UNEXPECTED; - } - } - return hr; -} - -void ChromeAppView::SetFullscreen(bool fullscreen) { - VLOG(1) << __FUNCTION__; - - if (osk_offset_adjustment_) { - VLOG(1) << "Scrolling the window down by: " - << osk_offset_adjustment_; - - ::ScrollWindowEx(globals.host_windows.front().first, - 0, - osk_offset_adjustment_, - NULL, - NULL, - NULL, - NULL, - SW_INVALIDATE | SW_SCROLLCHILDREN); - osk_offset_adjustment_ = 0; - } -} - -void UnsnapHelper() { - ChromeAppView::Unsnap(); -} - -extern "C" __declspec(dllexport) -void MetroUnsnap() { - DVLOG(1) << __FUNCTION__; - globals.appview_msg_loop->PostTask( - FROM_HERE, base::Bind(&UnsnapHelper)); -} - -extern "C" __declspec(dllexport) -HWND GetRootWindow() { - DVLOG(1) << __FUNCTION__; - return globals.core_window; -} - -extern "C" __declspec(dllexport) -void SetFrameWindow(HWND hwnd) { - DVLOG(1) << __FUNCTION__ << ", hwnd=" << LONG_PTR(hwnd); - globals.appview_msg_loop->PostTask( - FROM_HERE, base::Bind(&SetFrameWindowInternal, hwnd)); -} - -// TODO(ananta) -// Handle frame window close by deleting it from the window list and making the -// next guy visible. -extern "C" __declspec(dllexport) - void CloseFrameWindow(HWND hwnd) { - DVLOG(1) << __FUNCTION__ << ", hwnd=" << LONG_PTR(hwnd); - - // This is a hack to ensure that the BrowserViewLayout code layout happens - // just at the right time to hide the switcher button if it is visible. - globals.appview_msg_loop->PostDelayedTask( - FROM_HERE, base::Bind(&CloseFrameWindowInternal, hwnd), - base::TimeDelta::FromMilliseconds(50)); -} - -// Returns the initial url. This returns a valid url only if we were launched -// into metro via a url navigation. -extern "C" __declspec(dllexport) -const wchar_t* GetInitialUrl() { - DVLOG(1) << __FUNCTION__; - bool was_initial_activation = globals.is_initial_activation; - globals.is_initial_activation = false; - if (!was_initial_activation || globals.navigation_url.empty()) - return L""; - - const wchar_t* initial_url = globals.navigation_url.c_str(); - DVLOG(1) << initial_url; - return initial_url; -} - -// Returns the initial search string. This returns a valid url only if we were -// launched into metro via the search charm -extern "C" __declspec(dllexport) -const wchar_t* GetInitialSearchString() { - DVLOG(1) << __FUNCTION__; - bool was_initial_activation = globals.is_initial_activation; - globals.is_initial_activation = false; - if (!was_initial_activation || globals.search_string.empty()) - return L""; - - const wchar_t* initial_search_string = globals.search_string.c_str(); - DVLOG(1) << initial_search_string; - return initial_search_string; -} - -// Returns the launch type. -extern "C" __declspec(dllexport) -base::win::MetroLaunchType GetLaunchType( - base::win::MetroPreviousExecutionState* previous_state) { - if (previous_state) { - *previous_state = static_cast<base::win::MetroPreviousExecutionState>( - globals.previous_state); - } - return static_cast<base::win::MetroLaunchType>( - globals.initial_activation_kind); -} - -extern "C" __declspec(dllexport) -void FlipFrameWindows() { - DVLOG(1) << __FUNCTION__; - globals.appview_msg_loop->PostTask( - FROM_HERE, base::Bind(&FlipFrameWindowsInternal)); -} - -extern "C" __declspec(dllexport) -void DisplayNotification(const char* origin_url, const char* icon_url, - const wchar_t* title, const wchar_t* body, - const wchar_t* display_source, - const char* notification_id) { - // TODO(ananta) - // Needs implementation. - DVLOG(1) << __FUNCTION__; - - ToastNotificationHandler::DesktopNotification notification(origin_url, - icon_url, - title, - body, - display_source, - notification_id); - globals.appview_msg_loop->PostTask( - FROM_HERE, base::Bind(&ChromeAppView::DisplayNotification, - globals.view, notification)); -} - -extern "C" __declspec(dllexport) -bool CancelNotification(const char* notification_id) { - // TODO(ananta) - // Needs implementation. - DVLOG(1) << __FUNCTION__; - - if (!globals.view->IsValidNotification(notification_id)) { - NOTREACHED() << "Invalid notification id :" << notification_id; - return false; - } - - globals.appview_msg_loop->PostTask( - FROM_HERE, base::Bind(&ChromeAppView::CancelNotification, - globals.view, std::string(notification_id))); - return true; -} - -// Returns command line switches if any to be used by metro chrome. -extern "C" __declspec(dllexport) -const wchar_t* GetMetroCommandLineSwitches() { - DVLOG(1) << __FUNCTION__; - // The metro_command_line_switches field should be filled up once. - // ideally in ChromeAppView::Activate. - return globals.metro_command_line_switches.c_str(); -} - -// Provides functionality to display a metro style dialog box with two buttons. -// Only one dialog box can be displayed at any given time. -extern "C" __declspec(dllexport) -void ShowDialogBox( - const wchar_t* title, - const wchar_t* content, - const wchar_t* button1_label, - const wchar_t* button2_label, - base::win::MetroDialogButtonPressedHandler button1_handler, - base::win::MetroDialogButtonPressedHandler button2_handler) { - VLOG(1) << __FUNCTION__; - - DCHECK(title); - DCHECK(content); - DCHECK(button1_label); - DCHECK(button2_label); - DCHECK(button1_handler); - DCHECK(button2_handler); - - MetroDialogBox::DialogBoxInfo dialog_box_info; - dialog_box_info.title = title; - dialog_box_info.content = content; - dialog_box_info.button1_label = button1_label; - dialog_box_info.button2_label = button2_label; - dialog_box_info.button1_handler = button1_handler; - dialog_box_info.button2_handler = button2_handler; - - globals.appview_msg_loop->PostTask( - FROM_HERE, base::Bind( - &ChromeAppView::ShowDialogBox, globals.view, dialog_box_info)); -} - -// Provides functionality to dismiss the previously displayed metro style -// dialog box. -extern "C" __declspec(dllexport) -void DismissDialogBox() { - VLOG(1) << __FUNCTION__; - - globals.appview_msg_loop->PostTask( - FROM_HERE, base::Bind( - &ChromeAppView::DismissDialogBox, - globals.view)); -} - -extern "C" __declspec(dllexport) -void SetFullscreen(bool fullscreen) { - VLOG(1) << __FUNCTION__; - - globals.appview_msg_loop->PostTask( - FROM_HERE, base::Bind( - &ChromeAppView::SetFullscreen, - globals.view, fullscreen)); -} - -BOOL CALLBACK CoreWindowFinder(HWND hwnd, LPARAM) { - char classname[128]; - if (::GetClassNameA(hwnd, classname, ARRAYSIZE(classname))) { - if (lstrcmpiA("Windows.UI.Core.CoreWindow", classname) == 0) { - globals.core_window = hwnd; - return FALSE; - } - } - return TRUE; -} - -template <typename ContainerT> -void CloseSecondaryWindows(ContainerT& windows) { - DVLOG(1) << "Closing secondary windows", windows.size(); - std::for_each(windows.begin(), windows.end(), [](HWND hwnd) { - ::PostMessageW(hwnd, WM_CLOSE, 0, 0); - }); - windows.clear(); -} - -void EndChromeSession() { - DVLOG(1) << "Sending chrome WM_ENDSESSION window message."; - ::SendMessage(globals.host_windows.front().first, WM_ENDSESSION, FALSE, - ENDSESSION_CLOSEAPP); -} - -DWORD WINAPI HostMainThreadProc(void*) { - // Test feature - devs have requested the ability to easily add metro-chrome - // command line arguments. This is hard since shortcut arguments are ignored, - // by Metro, so we instead read them directly from the pinned taskbar - // shortcut. This may call Coinitialize and there is tell of badness - // occurring if CoInitialize is called on a metro thread. - globals.metro_command_line_switches = - winrt_utils::ReadArgumentsFromPinnedTaskbarShortcut(); - - globals.g_core_proc = reinterpret_cast<WNDPROC>( - ::SetWindowLong(globals.core_window, GWL_WNDPROC, - reinterpret_cast<long>(ChromeAppView::CoreWindowProc))); - DWORD exit_code = globals.host_main(globals.host_context); - DVLOG(1) << "host thread done, exit_code=" << exit_code; - globals.app_exit->Exit(); - return exit_code; -} - -ChromeAppView::ChromeAppView() - : osk_visible_notification_received_(false), - osk_offset_adjustment_(0) { - globals.previous_state = - winapp::Activation::ApplicationExecutionState_NotRunning; -} - -ChromeAppView::~ChromeAppView() { - DVLOG(1) << __FUNCTION__; -} - -IFACEMETHODIMP -ChromeAppView::Initialize(winapp::Core::ICoreApplicationView* view) { - view_ = view; - DVLOG(1) << __FUNCTION__; - globals.main_thread_id = ::GetCurrentThreadId(); - - HRESULT hr = view_->add_Activated(mswr::Callback<ActivatedHandler>( - this, &ChromeAppView::OnActivate).Get(), - &activated_token_); - CheckHR(hr); - return hr; -} - -IFACEMETHODIMP -ChromeAppView::SetWindow(winui::Core::ICoreWindow* window) { - window_ = window; - DVLOG(1) << __FUNCTION__; - - HRESULT hr = url_launch_handler_.Initialize(); - CheckHR(hr, "Failed to initialize url launch handler."); - - // Register for size notifications. - hr = window_->add_SizeChanged(mswr::Callback<SizeChangedHandler>( - this, &ChromeAppView::OnSizeChanged).Get(), - &sizechange_token_); - CheckHR(hr); - - // Register for edge gesture notifications. - mswr::ComPtr<winui::Input::IEdgeGestureStatics> edge_gesture_statics; - hr = winrt_utils::CreateActivationFactory( - RuntimeClass_Windows_UI_Input_EdgeGesture, - edge_gesture_statics.GetAddressOf()); - CheckHR(hr, "Failed to activate IEdgeGestureStatics."); - - mswr::ComPtr<winui::Input::IEdgeGesture> edge_gesture; - hr = edge_gesture_statics->GetForCurrentView(&edge_gesture); - CheckHR(hr); - - hr = edge_gesture->add_Completed(mswr::Callback<EdgeEventHandler>( - this, &ChromeAppView::OnEdgeGestureCompleted).Get(), - &edgeevent_token_); - CheckHR(hr); - - // Register for share notifications. - mswr::ComPtr<winapp::DataTransfer::IDataTransferManagerStatics> - data_mgr_statics; - hr = winrt_utils::CreateActivationFactory( - RuntimeClass_Windows_ApplicationModel_DataTransfer_DataTransferManager, - data_mgr_statics.GetAddressOf()); - CheckHR(hr, "Failed to activate IDataTransferManagerStatics."); - - mswr::ComPtr<winapp::DataTransfer::IDataTransferManager> data_transfer_mgr; - hr = data_mgr_statics->GetForCurrentView(&data_transfer_mgr); - CheckHR(hr, "Failed to get IDataTransferManager for current view."); - - hr = data_transfer_mgr->add_DataRequested( - mswr::Callback<ShareDataRequestedHandler>( - this, &ChromeAppView::OnShareDataRequested).Get(), - &share_data_requested_token_); - CheckHR(hr); - - // TODO(ananta) - // The documented InputPane notifications don't fire on Windows 8 in metro - // chrome. Uncomment this once we figure out why they don't fire. - // RegisterInputPaneNotifications(); - - hr = winrt_utils::CreateActivationFactory( - RuntimeClass_Windows_UI_ViewManagement_ApplicationView, - app_view_.GetAddressOf()); - CheckHR(hr); - - DVLOG(1) << "Created appview instance."; - - hr = devices_handler_.Initialize(window); - // Don't check or return the failure here, we need to let the app - // initialization succeed. Even if we won't be able to access devices - // we still want to allow the app to start. - LOG_IF(ERROR, FAILED(hr)) << "Failed to initialize devices handler."; - return S_OK; -} - -IFACEMETHODIMP -ChromeAppView::Load(HSTRING entryPoint) { - DVLOG(1) << __FUNCTION__; - return S_OK; -} - -void RunMessageLoop(winui::Core::ICoreDispatcher* dispatcher) { - // We're entering a nested message loop, let's allow dispatching - // tasks while we're in there. - MessageLoop::current()->SetNestableTasksAllowed(true); - - // Enter main core message loop. There are several ways to exit it - // Nicely: - // 1 - User action like ALT-F4. - // 2 - Calling ICoreApplicationExit::Exit(). - // 3- Posting WM_CLOSE to the core window. - HRESULT hr = dispatcher->ProcessEvents( - winui::Core::CoreProcessEventsOption - ::CoreProcessEventsOption_ProcessUntilQuit); - - // Wind down the thread's chrome message loop. - MessageLoop::current()->Quit(); -} - -void ChromeAppView::CheckForOSKActivation() { - // Hack for checking if the OSK was displayed while we are in the foreground. - // The input pane notifications which are supposed to fire when the OSK is - // shown and hidden don't seem to be firing in Windows 8 metro for us. - // The current hack is supposed to workaround that issue till we figure it - // out. Logic is to find the OSK window and see if we are the foreground - // process. If yes then fire the notification once for when the OSK is shown - // and once for when it is hidden. - // TODO(ananta) - // Take this out when the documented input pane notifcation issues are - // addressed. - HWND osk = ::FindWindow(kOSKClassName, NULL); - if (::IsWindow(osk)) { - HWND foreground_window = ::GetForegroundWindow(); - if (globals.host_windows.size() > 0 && - foreground_window == globals.host_windows.front().first) { - RECT osk_rect = {0}; - ::GetWindowRect(osk, &osk_rect); - - if (::IsWindowVisible(osk) && ::IsWindowEnabled(osk)) { - if (!globals.view->osk_visible_notification_received()) { - DVLOG(1) << "Found KB window while we are in the forground."; - HandleInputPaneVisible(osk_rect); - } - } else if (osk_visible_notification_received()) { - DVLOG(1) << "KB window hidden while we are in the foreground."; - HandleInputPaneHidden(osk_rect); - } - } - } - MessageLoop::current()->PostDelayedTask( - FROM_HERE, - base::Bind(&ChromeAppView::CheckForOSKActivation, - base::Unretained(this)), - base::TimeDelta::FromMilliseconds(kCheckOSKDelayMs)); -} - -IFACEMETHODIMP -ChromeAppView::Run() { - DVLOG(1) << __FUNCTION__ << ", hwnd=" << LONG_PTR(window_.Get()); - mswr::ComPtr<winui::Core::ICoreDispatcher> dispatcher; - HRESULT hr = window_->get_Dispatcher(&dispatcher); - CheckHR(hr, "Dispatcher failed."); - - hr = window_->Activate(); - if (SUCCEEDED(hr)) { - // TODO(cpu): Draw something here. - } else { - DVLOG(1) << "Activate failed, hr=" << hr; - } - - // Create a message loop to allow message passing into this thread. - MessageLoop msg_loop(MessageLoop::TYPE_UI); - - // Announce our message loop to the world. - globals.appview_msg_loop = msg_loop.message_loop_proxy(); - - // And post the task that'll do the inner Metro message pumping to it. - msg_loop.PostTask(FROM_HERE, base::Bind(&RunMessageLoop, dispatcher.Get())); - - // Post the recurring task which checks for OSK activation in metro chrome. - // Please refer to the comments in the CheckForOSKActivation function for why - // this is needed. - // TODO(ananta) - // Take this out when the documented OSK notifications start working. - msg_loop.PostDelayedTask( - FROM_HERE, - base::Bind(&ChromeAppView::CheckForOSKActivation, - base::Unretained(this)), - base::TimeDelta::FromMilliseconds(kCheckOSKDelayMs)); - - msg_loop.Run(); - - globals.appview_msg_loop = NULL; - - DVLOG(0) << "ProcessEvents done, hr=" << hr; - - // We join here with chrome's main thread so that the chrome is not killed - // while a critical operation is still in progress. Now, if there are host - // windows active it is possible we end up stuck on the wait below therefore - // we tell chrome to close its windows. - if (!globals.host_windows.empty()) { - DVLOG(1) << "Chrome still has windows open!"; - EndChromeSession(); - } - DWORD wr = ::WaitForSingleObject(globals.host_thread, INFINITE); - if (wr != WAIT_OBJECT_0) { - DVLOG(1) << "Waiting for host thread failed : " << wr; - } - ::CloseHandle(globals.host_thread); - globals.host_thread = NULL; - - return hr; -} - -IFACEMETHODIMP -ChromeAppView::Uninitialize() { - DVLOG(1) << __FUNCTION__; - window_ = nullptr; - view_ = nullptr; - base::AutoLock lock(notification_lock_); - notification_map_.clear(); - return S_OK; -} - -HRESULT ChromeAppView::RegisterInputPaneNotifications() { - DVLOG(1) << __FUNCTION__; - - mswr::ComPtr<winui::ViewManagement::IInputPaneStatics> - input_pane_statics; - HRESULT hr = winrt_utils::CreateActivationFactory( - RuntimeClass_Windows_UI_ViewManagement_InputPane, - input_pane_statics.GetAddressOf()); - CheckHR(hr); - - hr = input_pane_statics->GetForCurrentView(&input_pane_); - CheckHR(hr); - DVLOG(1) << "Got input pane."; - - hr = input_pane_->add_Showing( - mswr::Callback<InputPaneEventHandler>( - this, &ChromeAppView::OnInputPaneVisible).Get(), - &input_pane_visible_token_); - CheckHR(hr); - - DVLOG(1) << "Added showing event handler for input pane", - input_pane_visible_token_.value; - - hr = input_pane_->add_Hiding( - mswr::Callback<InputPaneEventHandler>( - this, &ChromeAppView::OnInputPaneHiding).Get(), - &input_pane_hiding_token_); - CheckHR(hr); - - DVLOG(1) << "Added hiding event handler for input pane, value=" - << input_pane_hiding_token_.value; - return hr; -} - -HRESULT ChromeAppView::OnActivate(winapp::Core::ICoreApplicationView*, - winapp::Activation::IActivatedEventArgs* args) { - DVLOG(1) << __FUNCTION__; - - args->get_PreviousExecutionState(&globals.previous_state); - DVLOG(1) << "Previous Execution State: " << globals.previous_state; - - window_->Activate(); - url_launch_handler_.Activate(args); - - if (globals.previous_state == - winapp::Activation::ApplicationExecutionState_Running && - globals.host_thread) { - DVLOG(1) << "Already running. Skipping rest of OnActivate."; - return S_OK; - } - - do { - ::Sleep(10); - ::EnumThreadWindows(globals.main_thread_id, &CoreWindowFinder, 0); - } while (globals.core_window == NULL); - - DVLOG(1) << "CoreWindow found: " << std::hex << globals.core_window; - - if (!globals.host_thread) { - globals.host_thread = - ::CreateThread(NULL, 0, HostMainThreadProc, NULL, 0, NULL); - - if (!globals.host_thread) { - NOTREACHED() << "thread creation failed."; - return E_UNEXPECTED; - } - } - - if (RegisterHotKey(globals.core_window, kFlipWindowsHotKeyId, - MOD_CONTROL, VK_F12)) { - DVLOG(1) << "Registered flip window hotkey."; - } else { - VPLOG(1) << "Failed to register flip window hotkey."; - } - HRESULT hr = settings_handler_.Initialize(); - CheckHR(hr,"Failed to initialize settings handler."); - return hr; -} - -// We subclass the core window for moving the associated chrome window when the -// core window is moved around, typically in the snap view operation. The -// size changes are handled in the documented size changed event. -LRESULT CALLBACK ChromeAppView::CoreWindowProc( - HWND window, UINT message, WPARAM wp, LPARAM lp) { - - static const UINT kBrowserClosingMessage = - ::RegisterWindowMessage(L"DefaultBrowserClosing"); - - if (message == WM_WINDOWPOSCHANGED) { - WINDOWPOS* pos = reinterpret_cast<WINDOWPOS*>(lp); - if (!(pos->flags & SWP_NOMOVE)) { - DVLOG(1) << "WM_WINDOWPOSCHANGED. Moving the chrome window."; - globals.view->OnPositionChanged(pos->x, pos->y); - } - } else if (message == WM_HOTKEY && wp == kFlipWindowsHotKeyId) { - FlipFrameWindows(); - } else if (message == kBrowserClosingMessage) { - DVLOG(1) << "Received DefaultBrowserClosing window message."; - // Ensure that the view is uninitialized. The kBrowserClosingMessage - // means that the app is going to be terminated, i.e. the proper - // uninitialization sequence does not occur. - globals.view->Uninitialize(); - if (!globals.host_windows.empty()) { - EndChromeSession(); - } - } - return CallWindowProc(globals.g_core_proc, window, message, wp, lp); -} - -HRESULT ChromeAppView::OnSizeChanged(winui::Core::ICoreWindow* sender, - winui::Core::IWindowSizeChangedEventArgs* args) { - if (!globals.host_windows.size()) { - return S_OK; - } - - winfoundtn::Size size; - args->get_Size(&size); - - int cx = static_cast<int>(size.Width); - int cy = static_cast<int>(size.Height); - - if (!::SetWindowPos(globals.host_windows.front().first, NULL, 0, 0, cx, cy, - SWP_NOMOVE | SWP_NOZORDER | SWP_FRAMECHANGED)) { - DVLOG(1) << "SetWindowPos failed."; - } - DVLOG(1) << "size changed cx=" << cx; - DVLOG(1) << "size changed cy=" << cy; - - winui::ViewManagement::ApplicationViewState view_state = - winui::ViewManagement::ApplicationViewState_FullScreenLandscape; - app_view_->get_Value(&view_state); - - HWND top_level_frame = globals.host_windows.front().first; - if (view_state == winui::ViewManagement::ApplicationViewState_Snapped) { - DVLOG(1) << "Enabling metro snap mode."; - ::PostMessageW(top_level_frame, WM_SYSCOMMAND, IDC_METRO_SNAP_ENABLE, 0); - } else { - ::PostMessageW(top_level_frame, WM_SYSCOMMAND, IDC_METRO_SNAP_DISABLE, 0); - } - return S_OK; -} - -HRESULT ChromeAppView::OnPositionChanged(int x, int y) { - DVLOG(1) << __FUNCTION__; - - ::SetWindowPos(globals.host_windows.front().first, NULL, x, y, 0, 0, - SWP_NOZORDER | SWP_FRAMECHANGED | SWP_NOSIZE); - return S_OK; -} - -HRESULT ChromeAppView::OnEdgeGestureCompleted( - winui::Input::IEdgeGesture* gesture, - winui::Input::IEdgeGestureEventArgs* args) { - DVLOG(1) << "edge gesture completed."; - - winui::ViewManagement::ApplicationViewState view_state = - winui::ViewManagement::ApplicationViewState_FullScreenLandscape; - app_view_->get_Value(&view_state); - // We don't want fullscreen chrome unless we are fullscreen metro. - if ((view_state == winui::ViewManagement::ApplicationViewState_Filled) || - (view_state == winui::ViewManagement::ApplicationViewState_Snapped)) { - DVLOG(1) << "No full screen in snapped view state:" << view_state; - return S_OK; - } - - // Deactivate anything pending, e.g., the wrench or a context menu. - BOOL success = ::ReleaseCapture(); - DCHECK(success) << "Couldn't ReleaseCapture() before going full screen"; - - DVLOG(1) << "Going full screen."; - ::PostMessageW(globals.host_windows.front().first, WM_SYSCOMMAND, - IDC_FULLSCREEN, 0); - return S_OK; -} - -HRESULT ChromeAppView::OnShareDataRequested( - winapp::DataTransfer::IDataTransferManager* data_transfer_mgr, - winapp::DataTransfer::IDataRequestedEventArgs* event_args) { - - DVLOG(1) << "Share data requested."; - - // The current tab info is retrieved from Chrome via a registered window - // message. - - static const UINT get_current_tab_info = - RegisterWindowMessage(kMetroGetCurrentTabInfoMessage); - - static const int kGetTabInfoTimeoutMs = 1000; - - mswr::ComPtr<winapp::DataTransfer::IDataRequest> data_request; - HRESULT hr = event_args->get_Request(&data_request); - CheckHR(hr); - - mswr::ComPtr<winapp::DataTransfer::IDataPackage> data_package; - hr = data_request->get_Data(&data_package); - CheckHR(hr); - - base::win::CurrentTabInfo current_tab_info; - current_tab_info.title = NULL; - current_tab_info.url = NULL; - - DWORD_PTR result = 0; - - if (!SendMessageTimeout(globals.host_windows.front().first, - get_current_tab_info, - reinterpret_cast<WPARAM>(¤t_tab_info), - 0, - SMTO_ABORTIFHUNG, - kGetTabInfoTimeoutMs, - &result)) { - VPLOG(1) << "Failed to retrieve tab info from chrome."; - return E_FAIL; - } - - if (!current_tab_info.title || !current_tab_info.url) { - DVLOG(1) << "Failed to retrieve tab info from chrome."; - return E_FAIL; - } - - string16 current_title(current_tab_info.title); - string16 current_url(current_tab_info.url); - - LocalFree(current_tab_info.title); - LocalFree(current_tab_info.url); - - mswr::ComPtr<winapp::DataTransfer::IDataPackagePropertySet> data_properties; - hr = data_package->get_Properties(&data_properties); - - mswrw::HString title; - title.Attach(MakeHString(current_title)); - data_properties->put_Title(title.Get()); - - mswr::ComPtr<winfoundtn::IUriRuntimeClassFactory> uri_factory; - hr = winrt_utils::CreateActivationFactory( - RuntimeClass_Windows_Foundation_Uri, - uri_factory.GetAddressOf()); - CheckHR(hr); - - mswrw::HString url; - url.Attach(MakeHString(current_url)); - mswr::ComPtr<winfoundtn::IUriRuntimeClass> uri; - hr = uri_factory->CreateUri(url.Get(), &uri); - CheckHR(hr); - - hr = data_package->SetUri(uri.Get()); - CheckHR(hr); - - return S_OK; -} - -void ChromeAppView::HandleInputPaneVisible(const RECT& osk_rect) { - DCHECK(!osk_visible_notification_received_); - - DVLOG(1) << __FUNCTION__; - DVLOG(1) << "OSK width:" << osk_rect.right - osk_rect.left; - DVLOG(1) << "OSK height:" << osk_rect.bottom - osk_rect.top; - - globals.host_windows.front().second = false; - - POINT cursor_pos = {0}; - GetCursorPos(&cursor_pos); - - osk_offset_adjustment_ = 0; - - if (::PtInRect(&osk_rect, cursor_pos)) { - DVLOG(1) << "OSK covering focus point."; - int osk_height = osk_rect.bottom - osk_rect.top; - - osk_offset_adjustment_ = osk_height + kOSKAdjustmentOffset; - - DVLOG(1) << "Scrolling window by offset: " << osk_offset_adjustment_; - ::ScrollWindowEx(globals.host_windows.front().first, - 0, - -osk_offset_adjustment_, - NULL, - NULL, - NULL, - NULL, - SW_INVALIDATE | SW_SCROLLCHILDREN); - - globals.host_windows.front().second = true; - } - osk_visible_notification_received_ = true; -} - -void ChromeAppView::HandleInputPaneHidden(const RECT& osk_rect) { - DCHECK(osk_visible_notification_received_); - DVLOG(1) << __FUNCTION__; - DVLOG(1) << "OSK width:" << osk_rect.right - osk_rect.left; - DVLOG(1) << "OSK height:" << osk_rect.bottom - osk_rect.top; - osk_visible_notification_received_ = false; - if (globals.host_windows.front().second == true) { - - if (osk_offset_adjustment_) { - DVLOG(1) << "Restoring scrolled window offset: " - << osk_offset_adjustment_; - - ::ScrollWindowEx(globals.host_windows.front().first, - 0, - osk_offset_adjustment_, - NULL, - NULL, - NULL, - NULL, - SW_INVALIDATE | SW_SCROLLCHILDREN); - } - - globals.host_windows.front().second = false; - } -} - -HRESULT ChromeAppView::OnInputPaneVisible( - winui::ViewManagement::IInputPane* input_pane, - winui::ViewManagement::IInputPaneVisibilityEventArgs* event_args) { - DVLOG(1) << __FUNCTION__; - return S_OK; -} - -HRESULT ChromeAppView::OnInputPaneHiding( - winui::ViewManagement::IInputPane* input_pane, - winui::ViewManagement::IInputPaneVisibilityEventArgs* event_args) { - DVLOG(1) << __FUNCTION__; - return S_OK; -} - -/////////////////////////////////////////////////////////////////////////////// - -ChromeAppViewFactory::ChromeAppViewFactory( - winapp::Core::ICoreApplication* icore_app, - LPTHREAD_START_ROUTINE host_main, - void* host_context) { - globals.host_main = host_main; - globals.host_context = host_context; - mswr::ComPtr<winapp::Core::ICoreApplication> core_app(icore_app); - mswr::ComPtr<winapp::Core::ICoreApplicationExit> app_exit; - CheckHR(core_app.As(&app_exit)); - globals.app_exit = app_exit.Detach(); -} - -IFACEMETHODIMP -ChromeAppViewFactory::CreateView(winapp::Core::IFrameworkView** view) { - globals.view = mswr::Make<ChromeAppView>().Detach(); - *view = globals.view; - return (*view) ? S_OK : E_OUTOFMEMORY; -} diff --git a/win8/metro_driver/chrome_app_view.h b/win8/metro_driver/chrome_app_view.h deleted file mode 100644 index 80f309d..0000000 --- a/win8/metro_driver/chrome_app_view.h +++ /dev/null @@ -1,177 +0,0 @@ -// Copyright (c) 2012 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. - -#ifndef CHROME_BROWSER_UI_METRO_DRIVER_CHROME_APP_VIEW_H_ -#define CHROME_BROWSER_UI_METRO_DRIVER_CHROME_APP_VIEW_H_ - -#include <windows.applicationmodel.core.h> -#include <windows.ui.core.h> -#include <windows.ui.input.h> -#include <windows.ui.viewmanagement.h> - -#include <list> -#include <map> -#include <string> -#include <utility> - -#include "base/memory/scoped_ptr.h" -#include "base/message_loop.h" -#include "base/synchronization/lock.h" -#include "win8/metro_driver/chrome_url_launch_handler.h" -#include "win8/metro_driver/devices_handler.h" -#include "win8/metro_driver/metro_dialog_box.h" -#include "win8/metro_driver/settings_handler.h" -#include "win8/metro_driver/toast_notification_handler.h" - -class ChromeAppView - : public mswr::RuntimeClass<winapp::Core::IFrameworkView> { - public: - ChromeAppView(); - ~ChromeAppView(); - - // IViewProvider overrides. - IFACEMETHOD(Initialize)(winapp::Core::ICoreApplicationView* view); - IFACEMETHOD(SetWindow)(winui::Core::ICoreWindow* window); - IFACEMETHOD(Load)(HSTRING entryPoint); - IFACEMETHOD(Run)(); - IFACEMETHOD(Uninitialize)(); - - static LRESULT CALLBACK CoreWindowProc(HWND window, UINT message, WPARAM wp, - LPARAM lp); - - HRESULT TileRequestCreateDone(winfoundtn::IAsyncOperation<bool>* async, - AsyncStatus status); - - bool osk_visible_notification_received() const { - return osk_visible_notification_received_; - } - - // Displays the notification. - void DisplayNotification( - const ToastNotificationHandler::DesktopNotification& notification); - - // Cancels the notification. - void CancelNotification(const std::string& notification); - - // Returns true if the notification passed in is valid. - bool IsValidNotification(const std::string& notification); - - // Displays a dialog box. - void ShowDialogBox(const MetroDialogBox::DialogBoxInfo& dialog_box_info); - // Dismisses the dialog box. - void DismissDialogBox(); - - // Helper function to unsnap the chrome metro app if it is snapped. - // Returns S_OK on success. - static HRESULT Unsnap(); - - // Notification from chrome that a full screen operation is being performed. - void SetFullscreen(bool fullscreen); - - private: - HRESULT OnActivate(winapp::Core::ICoreApplicationView* view, - winapp::Activation::IActivatedEventArgs* args); - - HRESULT OnSizeChanged(winui::Core::ICoreWindow* sender, - winui::Core::IWindowSizeChangedEventArgs* args); - - HRESULT OnEdgeGestureCompleted(winui::Input::IEdgeGesture* gesture, - winui::Input::IEdgeGestureEventArgs* args); - - HRESULT OnShareDataRequested( - winapp::DataTransfer::IDataTransferManager* data_transfer_mgr, - winapp::DataTransfer::IDataRequestedEventArgs* event_args); - - HRESULT OnInputPaneVisible( - winui::ViewManagement::IInputPane* input_pane, - winui::ViewManagement::IInputPaneVisibilityEventArgs* event_args); - - HRESULT OnInputPaneHiding( - winui::ViewManagement::IInputPane* input_pane, - winui::ViewManagement::IInputPaneVisibilityEventArgs* event_args); - - HRESULT OnPositionChanged(int x, int y); - - void CheckForOSKActivation(); - - HRESULT RegisterInputPaneNotifications(); - - void HandleInputPaneVisible(const RECT& osk_rect); - void HandleInputPaneHidden(const RECT& osk_rect); - - mswr::ComPtr<winui::Core::ICoreWindow> window_; - mswr::ComPtr<winapp::Core::ICoreApplicationView> view_; - EventRegistrationToken activated_token_; - EventRegistrationToken edgeevent_token_; - EventRegistrationToken sizechange_token_; - EventRegistrationToken share_data_requested_token_; - EventRegistrationToken input_pane_visible_token_; - EventRegistrationToken input_pane_hiding_token_; - EventRegistrationToken app_exit_token_; - - ChromeUrlLaunchHandler url_launch_handler_; - metro_driver::DevicesHandler devices_handler_; - SettingsHandler settings_handler_; - mswr::ComPtr<winui::ViewManagement::IInputPane> input_pane_; - mswr::ComPtr<winui::ViewManagement::IApplicationViewStatics> app_view_; - - bool osk_visible_notification_received_; - - // map of notification id to the ToastNotificationHandler instance. - typedef std::map<std::string, scoped_ptr<ToastNotificationHandler> > - NotificationMap; - NotificationMap notification_map_; - - // Synchronizes access to the notification_map_ member. - base::Lock notification_lock_; - - // If the OSK covers the input area we scroll the window by the height of the - // OSK + an additional offset. This member holds this offset. Set to 0 if the - // window was not scrolled. - int osk_offset_adjustment_; - - MetroDialogBox dialog_box_; -}; - -class ChromeAppViewFactory - : public mswr::RuntimeClass<winapp::Core::IFrameworkViewSource> { - public: - ChromeAppViewFactory(winapp::Core::ICoreApplication* icore_app, - LPTHREAD_START_ROUTINE host_main, - void* host_context); - IFACEMETHOD(CreateView)(winapp::Core::IFrameworkView** view); -}; - -// This function is exported by chrome.exe. -typedef int (__cdecl *BreakpadExceptionHandler)(EXCEPTION_POINTERS* info); - -// Global information used across the metro driver. -struct Globals { - LPTHREAD_START_ROUTINE host_main; - void* host_context; - HWND core_window; - // The pair below contains the HWND and a bool which indicates whether the - // window was displaced to ensure that the focused region is visible when - // the OSK is displayed. - std::list<std::pair<HWND, bool> > host_windows; - HANDLE host_thread; - DWORD main_thread_id; - ChromeAppView* view; - WNDPROC g_core_proc; - string16 navigation_url; - string16 search_string; - winapp::Activation::ApplicationExecutionState previous_state; - winapp::Activation::ActivationKind initial_activation_kind; - bool is_initial_activation; - // This message loop lives in the app view's thread. Some operations have - // to be initiated from that thread, notably spawning file pickers. - base::MessageLoopProxy* appview_msg_loop; - winapp::Core::ICoreApplicationExit* app_exit; - BreakpadExceptionHandler breakpad_exception_handler; - string16 metro_command_line_switches; -}; - -extern Globals globals; - -#endif // CHROME_BROWSER_UI_METRO_DRIVER_CHROME_APP_VIEW_H_ diff --git a/win8/metro_driver/chrome_url_launch_handler.cc b/win8/metro_driver/chrome_url_launch_handler.cc deleted file mode 100644 index 866bccc..0000000 --- a/win8/metro_driver/chrome_url_launch_handler.cc +++ /dev/null @@ -1,201 +0,0 @@ -// Copyright (c) 2012 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 "stdafx.h" -#include "chrome_url_launch_handler.h" -#include "chrome_app_view.h" - -#include <assert.h> -#include <shellapi.h> -#include <shlobj.h> -#include <string> - -#include "base/string_tokenizer.h" - -#include "winrt_utils.h" - -typedef winfoundtn::ITypedEventHandler< - winapp::Search::SearchPane*, - winapp::Search::SearchPaneQuerySubmittedEventArgs*> QuerySubmittedHandler; - -ChromeUrlLaunchHandler::ChromeUrlLaunchHandler() { - globals.is_initial_activation = true; - globals.initial_activation_kind = winapp::Activation::ActivationKind_Launch; - DVLOG(1) << __FUNCTION__; -} - -// TODO(ananta) -// Remove this once we consolidate metro driver with chrome. -const wchar_t kMetroNavigationAndSearchMessage[] = - L"CHROME_METRO_NAV_SEARCH_REQUEST"; - -ChromeUrlLaunchHandler::~ChromeUrlLaunchHandler() { - DVLOG(1) << __FUNCTION__; - search_pane_->remove_QuerySubmitted(query_submitted_token_); -} - -HRESULT ChromeUrlLaunchHandler::Initialize() { - mswr::ComPtr<winapp::Search::ISearchPaneStatics> search_pane_statics; - HRESULT hr = winrt_utils::CreateActivationFactory( - RuntimeClass_Windows_ApplicationModel_Search_SearchPane, - search_pane_statics.GetAddressOf()); - CheckHR(hr, "Failed to activate ISearchPaneStatics"); - - hr = search_pane_statics->GetForCurrentView(&search_pane_); - if (FAILED(hr)) { - LOG(ERROR) << "Failed to get search pane for current view"; - return hr; - } - - hr = search_pane_->add_QuerySubmitted(mswr::Callback<QuerySubmittedHandler>( - this, - &ChromeUrlLaunchHandler::OnQuerySubmitted).Get(), - &query_submitted_token_); - if (FAILED(hr)) { - LOG(ERROR) << "Failed to register for Query Submitted event"; - return hr; - } - return hr; -} - -HRESULT ChromeUrlLaunchHandler::OnQuerySubmitted( - winapp::Search::ISearchPane* search_pane, - winapp::Search::ISearchPaneQuerySubmittedEventArgs* args) { - DVLOG(1) << "OnQuerySubmitted"; - HandleSearchRequest(args); - return S_OK; -} - -template<class T> -void ChromeUrlLaunchHandler::HandleSearchRequest(T* args) { - DVLOG(1) << __FUNCTION__; - mswrw::HString search_string; - args->get_QueryText(search_string.GetAddressOf()); - string16 search_text(MakeStdWString(search_string.Get())); - globals.search_string = search_text; - DVLOG(1) << search_text.c_str(); - // If this is the initial activation then we wait for Chrome to initiate the - // navigation. In all other cases navigate right away. - if (!globals.is_initial_activation) - InitiateNavigationOrSearchRequest(NULL, globals.search_string.c_str()); -} - -void ChromeUrlLaunchHandler::HandleProtocolLaunch( - winapp::Activation::IProtocolActivatedEventArgs* args) { - DVLOG(1) << __FUNCTION__; - mswr::ComPtr<winfoundtn::IUriRuntimeClass> uri; - args->get_Uri(&uri); - mswrw::HString url; - uri->get_AbsoluteUri(url.GetAddressOf()); - string16 actual_url(MakeStdWString(url.Get())); - globals.navigation_url = actual_url; - - // If this is the initial activation then we wait for Chrome to initiate the - // navigation. In all other cases navigate right away. - if (!globals.is_initial_activation) - InitiateNavigationOrSearchRequest(globals.navigation_url.c_str(), 0); -} - -// The LaunchArgs are in a semi-color separated key_name=key_value list. At -// the moment the only key_name understaood is "url". -string16 ChromeUrlLaunchHandler::GetUrlFromLaunchArgs( - const string16& launch_args) { - WStringTokenizer tokenizer(launch_args, L";="); - bool next_is_url = false; - while (tokenizer.GetNext()) { - if (next_is_url) - return tokenizer.token(); - if (tokenizer.token() == L"url") - next_is_url = true; - } - if (launch_args == L"opennewwindow") { - DVLOG(1) << "Returning new tab url"; - return L"chrome://newtab"; - } - return string16(); -} - -void ChromeUrlLaunchHandler::HandleLaunch( - winapp::Activation::ILaunchActivatedEventArgs* args) { - mswrw::HString launch_args; - args->get_Arguments(launch_args.GetAddressOf()); - string16 actual_launch_args(MakeStdWString(launch_args.Get())); - globals.navigation_url = GetUrlFromLaunchArgs(actual_launch_args); - DVLOG(1) << __FUNCTION__ << ", launch_args=" << actual_launch_args - << ", url=" << globals.navigation_url - << ", is_initial_activation=" << globals.is_initial_activation; - - // If this is the initial launch then we wait for Chrome to initiate the - // navigation. In all other cases navigate right away. - if (!globals.is_initial_activation) - InitiateNavigationOrSearchRequest(globals.navigation_url.c_str(), 0); -} - -void ChromeUrlLaunchHandler::Activate( - winapp::Activation::IActivatedEventArgs* args) { - winapp::Activation::ActivationKind activation_kind; - CheckHR(args->get_Kind(&activation_kind)); - - DVLOG(1) << __FUNCTION__ << ", activation_kind=" << activation_kind; - - if (globals.is_initial_activation) - globals.initial_activation_kind = activation_kind; - - if (activation_kind == winapp::Activation::ActivationKind_Launch) { - mswr::ComPtr<winapp::Activation::ILaunchActivatedEventArgs> launch_args; - if (args->QueryInterface(winapp::Activation::IID_ILaunchActivatedEventArgs, - &launch_args) == S_OK) { - DVLOG(1) << "Activate: ActivationKind_Launch"; - HandleLaunch(launch_args.Get()); - } - } else if (activation_kind == - winapp::Activation::ActivationKind_Search) { - mswr::ComPtr<winapp::Activation::ISearchActivatedEventArgs> search_args; - if (args->QueryInterface(winapp::Activation::IID_ISearchActivatedEventArgs, - &search_args) == S_OK) { - DVLOG(1) << "Activate: ActivationKind_Search"; - HandleSearchRequest(search_args.Get()); - } - } else if (activation_kind == - winapp::Activation::ActivationKind_Protocol) { - mswr::ComPtr<winapp::Activation::IProtocolActivatedEventArgs> - protocol_args; - if (args->QueryInterface( - winapp::Activation::IID_IProtocolActivatedEventArgs, - &protocol_args) == S_OK) { - DVLOG(1) << "Activate: ActivationKind_Protocol"; - HandleProtocolLaunch(protocol_args.Get()); - } - } else { - DVLOG(1) << "Activate: Unhandled mode: " << activation_kind; - } -} - -void ChromeUrlLaunchHandler::InitiateNavigationOrSearchRequest( - const wchar_t* url, const wchar_t* search_string) { - DVLOG(1) << __FUNCTION__; - if (!url && !search_string) { - NOTREACHED(); - return; - } - - DVLOG(1) << (url ? url : L"NULL url"); - DVLOG(1) << (search_string ? search_string : L"NULL search string"); - - // Custom registered message to navigate or search in chrome. WPARAM - // points to the URL and LPARAM contains the search string. They are - // mutually exclusive. - static const UINT navigation_search_message = - RegisterWindowMessage(kMetroNavigationAndSearchMessage); - - if (url) { - VLOG(1) << "Posting url:" << url; - PostMessage(globals.host_windows.front().first, navigation_search_message, - reinterpret_cast<WPARAM>(url), 0); - } else { - VLOG(1) << "Posting search string:" << search_string; - PostMessage(globals.host_windows.front().first, navigation_search_message, - 0, reinterpret_cast<LPARAM>(search_string)); - } -} diff --git a/win8/metro_driver/chrome_url_launch_handler.h b/win8/metro_driver/chrome_url_launch_handler.h deleted file mode 100644 index d8c7ed0..0000000 --- a/win8/metro_driver/chrome_url_launch_handler.h +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright (c) 2012 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. - -#ifndef CHROME_BROWSER_UI_METRO_DRIVER_CHROME_URL_LAUNCH_HANDLER_H_ -#define CHROME_BROWSER_UI_METRO_DRIVER_CHROME_URL_LAUNCH_HANDLER_H_ - -#include <string> -#include <windows.applicationmodel.core.h> -#include <Windows.applicationModel.search.h> -#include <windows.ui.core.h> - -#include "winrt_utils.h" - -// This class handles the various flavors of URL launches in metro, i.e. -// via the search charm, via a url being navigated from a metro app, etc. -class ChromeUrlLaunchHandler { - public: - ChromeUrlLaunchHandler(); - ~ChromeUrlLaunchHandler(); - - HRESULT Initialize(); - - // If metro chrome was launched due to a URL navigation/search request then - // the navigation should be done when the frame window is initialized. This - // function is called to complete the pending navigation when we receive a - // notification from chrome that the frame window is initialized. - void PerformPendingNavigation(); - - void Activate(winapp::Activation::IActivatedEventArgs* args); - - private: - // Invoked when we receive search notifications in metro chrome. - template<class T> void HandleSearchRequest(T* args); - - HRESULT OnQuerySubmitted( - winapp::Search::ISearchPane* search_pane, - winapp::Search::ISearchPaneQuerySubmittedEventArgs* args); - - string16 GetUrlFromLaunchArgs(const string16& launch_args); - - // Invoked when a url is navigated from a metro app or in the metro - // shelf. - void HandleProtocolLaunch( - winapp::Activation::IProtocolActivatedEventArgs* args); - - // Invoked when the app is launched normally - void HandleLaunch(winapp::Activation::ILaunchActivatedEventArgs* args); - - // Helper function to initiate a navigation or search request in chrome. - void InitiateNavigationOrSearchRequest(const wchar_t* url, - const wchar_t* search_string); - - Microsoft::WRL::ComPtr<winapp::Search::ISearchPane> search_pane_; - EventRegistrationToken query_submitted_token_; -}; - -#endif // CHROME_BROWSER_UI_METRO_DRIVER_CHROME_URL_LAUNCH_HANDLER_H_ diff --git a/win8/metro_driver/devices_handler.cc b/win8/metro_driver/devices_handler.cc deleted file mode 100644 index 20fd413..0000000 --- a/win8/metro_driver/devices_handler.cc +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) 2012 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 "stdafx.h" -#include "win8/metro_driver/devices_handler.h" - -#include "base/logging.h" - -namespace metro_driver { - -DevicesHandler::DevicesHandler() { -} - -DevicesHandler::~DevicesHandler() { -} - -HRESULT DevicesHandler::Initialize(winui::Core::ICoreWindow* window) { - HRESULT hr = print_handler_.Initialize(window); - return hr; -} - -} // namespace metro_driver diff --git a/win8/metro_driver/devices_handler.h b/win8/metro_driver/devices_handler.h deleted file mode 100644 index fdb2226..0000000 --- a/win8/metro_driver/devices_handler.h +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (c) 2012 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. - -#ifndef CHROME_BROWSER_UI_METRO_DRIVER_DEVICES_HANDLER_H_ -#define CHROME_BROWSER_UI_METRO_DRIVER_DEVICES_HANDLER_H_ - -#include <windows.ui.core.h> - -#include "base/basictypes.h" -#include "win8/metro_driver/print_handler.h" - -namespace metro_driver { - -// This class handles the devices charm. -class DevicesHandler { - public: - DevicesHandler(); - ~DevicesHandler(); - - HRESULT Initialize(winui::Core::ICoreWindow* window); - - private: - PrintHandler print_handler_; - - DISALLOW_COPY_AND_ASSIGN(DevicesHandler); -}; - -} // namespace metro_driver - -#endif // CHROME_BROWSER_UI_METRO_DRIVER_DEVICES_HANDLER_H_ diff --git a/win8/metro_driver/file_picker.cc b/win8/metro_driver/file_picker.cc deleted file mode 100644 index 4977be6..0000000 --- a/win8/metro_driver/file_picker.cc +++ /dev/null @@ -1,618 +0,0 @@ -// Copyright (c) 2012 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 "stdafx.h" -#include "win8/metro_driver/file_picker.h" - -#include <windows.storage.pickers.h> - -#include "base/bind.h" -#include "base/file_path.h" -#include "base/logging.h" -#include "base/message_loop.h" -#include "base/string_util.h" -#include "base/synchronization/waitable_event.h" -#include "base/win/scoped_comptr.h" -#include "base/win/metro.h" -#include "win8/metro_driver/chrome_app_view.h" -#include "win8/metro_driver/winrt_utils.h" - -namespace { - -namespace winstorage = ABI::Windows::Storage; -typedef winfoundtn::Collections::IVector<HSTRING> StringVectorItf; - -// TODO(siggi): Complete this implementation and move it to a common place. -class StringVectorImpl : public mswr::RuntimeClass<StringVectorItf> { - public: - ~StringVectorImpl() { - std::for_each(strings_.begin(), strings_.end(), ::WindowsDeleteString); - } - - HRESULT RuntimeClassInitialize(const std::vector<string16>& list) { - for (size_t i = 0; i < list.size(); ++i) - strings_.push_back(MakeHString(list[i])); - - return S_OK; - } - - // IVector<HSTRING> implementation. - STDMETHOD(GetAt)(unsigned index, HSTRING* item) { - if (index >= strings_.size()) - return E_INVALIDARG; - - return ::WindowsDuplicateString(strings_[index], item); - } - STDMETHOD(get_Size)(unsigned *size) { - *size = strings_.size(); - return S_OK; - } - STDMETHOD(GetView)(winfoundtn::Collections::IVectorView<HSTRING> **view) { - return E_NOTIMPL; - } - STDMETHOD(IndexOf)(HSTRING value, unsigned *index, boolean *found) { - return E_NOTIMPL; - } - - // write methods - STDMETHOD(SetAt)(unsigned index, HSTRING item) { - return E_NOTIMPL; - } - STDMETHOD(InsertAt)(unsigned index, HSTRING item) { - return E_NOTIMPL; - } - STDMETHOD(RemoveAt)(unsigned index) { - return E_NOTIMPL; - } - STDMETHOD(Append)(HSTRING item) { - return E_NOTIMPL; - } - STDMETHOD(RemoveAtEnd)() { - return E_NOTIMPL; - } - STDMETHOD(Clear)() { - return E_NOTIMPL; - } - - private: - std::vector<HSTRING> strings_; -}; - -class FilePickerSessionBase { - public: - // Creates a file picker for open_file_name. - explicit FilePickerSessionBase(OPENFILENAME* open_file_name); - - // Runs the picker, returns true on success. - bool Run(); - - protected: - // Creates, configures and starts a file picker. - // If the HRESULT returned is a failure code the file picker has not started, - // so no callbacks should be expected. - virtual HRESULT StartFilePicker() = 0; - - // The parameters to our picker. - OPENFILENAME* open_file_name_; - // The event Run waits on. - base::WaitableEvent event_; - // True iff a file picker has successfully finished. - bool success_; - - private: - // Initiate a file picker, must be called on the metro dispatcher's thread. - void DoFilePicker(); - - DISALLOW_COPY_AND_ASSIGN(FilePickerSessionBase); -}; - -class OpenFilePickerSession : public FilePickerSessionBase { - public: - explicit OpenFilePickerSession(OPENFILENAME* open_file_name); - - private: - virtual HRESULT StartFilePicker() OVERRIDE; - - typedef winfoundtn::IAsyncOperation<winstorage::StorageFile*> - SingleFileAsyncOp; - typedef winfoundtn::Collections::IVectorView< - winstorage::StorageFile*> StorageFileVectorCollection; - typedef winfoundtn::IAsyncOperation<StorageFileVectorCollection*> - MultiFileAsyncOp; - - // Called asynchronously when a single file picker is done. - HRESULT SinglePickerDone(SingleFileAsyncOp* async, AsyncStatus status); - - // Called asynchronously when a multi file picker is done. - HRESULT MultiPickerDone(MultiFileAsyncOp* async, AsyncStatus status); - - // Composes a multi-file result string suitable for returning to a - // from a storage file collection. - static HRESULT ComposeMultiFileResult(StorageFileVectorCollection* files, - string16* result); - private: - DISALLOW_COPY_AND_ASSIGN(OpenFilePickerSession); -}; - -class SaveFilePickerSession : public FilePickerSessionBase { - public: - explicit SaveFilePickerSession(OPENFILENAME* open_file_name); - - private: - virtual HRESULT StartFilePicker() OVERRIDE; - - typedef winfoundtn::IAsyncOperation<winstorage::StorageFile*> - SaveFileAsyncOp; - - // Called asynchronously when the save file picker is done. - HRESULT FilePickerDone(SaveFileAsyncOp* async, AsyncStatus status); -}; - -FilePickerSessionBase::FilePickerSessionBase(OPENFILENAME* open_file_name) - : open_file_name_(open_file_name), - event_(true, false), - success_(false) { -} - -bool FilePickerSessionBase::Run() { - DCHECK(globals.appview_msg_loop != NULL); - - // Post the picker request over to the metro thread. - bool posted = globals.appview_msg_loop->PostTask(FROM_HERE, - base::Bind(&FilePickerSessionBase::DoFilePicker, base::Unretained(this))); - if (!posted) - return false; - - // Wait for the file picker to complete. - event_.Wait(); - - return success_; -} - -void FilePickerSessionBase::DoFilePicker() { - // The file picker will fail if spawned from a snapped application, - // so let's attempt to unsnap first if we're in that state. - HRESULT hr = ChromeAppView::Unsnap(); - if (FAILED(hr)) { - LOG(ERROR) << "Failed to unsnap for file picker, error 0x" << hr; - } - - if (SUCCEEDED(hr)) - hr = StartFilePicker(); - - if (FAILED(hr)) { - LOG(ERROR) << "Failed to start file picker, error 0x" - << std::hex << hr; - - event_.Signal(); - } -} - -OpenFilePickerSession::OpenFilePickerSession(OPENFILENAME* open_file_name) - : FilePickerSessionBase(open_file_name) { -} - -HRESULT OpenFilePickerSession::SinglePickerDone(SingleFileAsyncOp* async, - AsyncStatus status) { - if (status == Completed) { - mswr::ComPtr<winstorage::IStorageFile> file; - HRESULT hr = async->GetResults(file.GetAddressOf()); - - if (file) { - mswr::ComPtr<winstorage::IStorageItem> storage_item; - if (SUCCEEDED(hr)) - hr = file.As(&storage_item); - - mswrw::HString file_path; - if (SUCCEEDED(hr)) - hr = storage_item->get_Path(file_path.GetAddressOf()); - - if (SUCCEEDED(hr)) { - size_t path_len = 0; - const wchar_t* path_str = - ::WindowsGetStringRawBuffer(file_path.Get(), &path_len); - - // If the selected file name is longer than the supplied buffer, - // we return false as per GetOpenFileName documentation. - if (path_len < open_file_name_->nMaxFile) { - base::wcslcpy(open_file_name_->lpstrFile, - path_str, - open_file_name_->nMaxFile); - success_ = true; - } - } - } else { - LOG(ERROR) << "NULL IStorageItem"; - } - } else { - LOG(ERROR) << "Unexpected async status " << status; - } - - event_.Signal(); - - return S_OK; -} - -HRESULT OpenFilePickerSession::MultiPickerDone(MultiFileAsyncOp* async, - AsyncStatus status) { - if (status == Completed) { - mswr::ComPtr<StorageFileVectorCollection> files; - HRESULT hr = async->GetResults(files.GetAddressOf()); - - if (files) { - string16 result; - if (SUCCEEDED(hr)) - hr = ComposeMultiFileResult(files.Get(), &result); - - if (SUCCEEDED(hr)) { - if (result.size() + 1 < open_file_name_->nMaxFile) { - // Because the result has embedded nulls, we must memcpy. - memcpy(open_file_name_->lpstrFile, - result.c_str(), - (result.size() + 1) * sizeof(result[0])); - success_ = true; - } - } - } else { - LOG(ERROR) << "NULL StorageFileVectorCollection"; - } - } else { - LOG(ERROR) << "Unexpected async status " << status; - } - - event_.Signal(); - - return S_OK; -} - -HRESULT OpenFilePickerSession::StartFilePicker() { - DCHECK(globals.appview_msg_loop->BelongsToCurrentThread()); - DCHECK(open_file_name_ != NULL); - - mswrw::HStringReference class_name( - RuntimeClass_Windows_Storage_Pickers_FileOpenPicker); - - // Create the file picker. - mswr::ComPtr<winstorage::Pickers::IFileOpenPicker> picker; - HRESULT hr = ::Windows::Foundation::ActivateInstance( - class_name.Get(), picker.GetAddressOf()); - CheckHR(hr); - - // Set the file type filter - mswr::ComPtr<winfoundtn::Collections::IVector<HSTRING>> filter; - hr = picker->get_FileTypeFilter(filter.GetAddressOf()); - if (FAILED(hr)) - return hr; - - if (open_file_name_->lpstrFilter == NULL) { - hr = filter->Append(mswrw::HStringReference(L"*").Get()); - if (FAILED(hr)) - return hr; - } else { - // The filter is a concatenation of zero terminated string pairs, - // where each pair is {description, extension}. The concatenation ends - // with a zero length string - e.g. a double zero terminator. - const wchar_t* walk = open_file_name_->lpstrFilter; - while (*walk != L'\0') { - // Walk past the description. - walk += wcslen(walk) + 1; - - // We should have an extension, but bail on malformed filters. - if (*walk == L'\0') - break; - - // There can be a single extension, or a list of semicolon-separated ones. - std::vector<string16> extensions_win32_style; - size_t extension_count = Tokenize(walk, L";", &extensions_win32_style); - DCHECK_EQ(extension_count, extensions_win32_style.size()); - - // Metro wants suffixes only, not patterns. - mswrw::HString extension; - std::vector<string16> extensions; - for (size_t i = 0; i < extensions_win32_style.size(); ++i) { - if (extensions_win32_style[i] == L"*.*") { - // The wildcard filter is "*" for Metro. The string "*.*" produces - // an "invalid parameter" error. - hr = extension.Set(L"*"); - } else { - // Metro wants suffixes only, not patterns. - string16 ext = FilePath(extensions_win32_style[i]).Extension(); - if ((ext.size() < 2) || - (ext.find_first_of(L"*?") != string16::npos)) { - continue; - } - hr = extension.Set(ext.c_str()); - } - if (SUCCEEDED(hr)) - hr = filter->Append(extension.Get()); - if (FAILED(hr)) - return hr; - } - - // Walk past the extension. - walk += wcslen(walk) + 1; - } - } - - // Spin up a single or multi picker as appropriate. - if (open_file_name_->Flags & OFN_ALLOWMULTISELECT) { - mswr::ComPtr<MultiFileAsyncOp> completion; - hr = picker->PickMultipleFilesAsync(&completion); - if (FAILED(hr)) - return hr; - - // Create the callback method. - typedef winfoundtn::IAsyncOperationCompletedHandler< - StorageFileVectorCollection*> HandlerDoneType; - mswr::ComPtr<HandlerDoneType> handler(mswr::Callback<HandlerDoneType>( - this, &OpenFilePickerSession::MultiPickerDone)); - DCHECK(handler.Get() != NULL); - hr = completion->put_Completed(handler.Get()); - - return hr; - } else { - mswr::ComPtr<SingleFileAsyncOp> completion; - hr = picker->PickSingleFileAsync(&completion); - if (FAILED(hr)) - return hr; - - // Create the callback method. - typedef winfoundtn::IAsyncOperationCompletedHandler< - winstorage::StorageFile*> HandlerDoneType; - mswr::ComPtr<HandlerDoneType> handler(mswr::Callback<HandlerDoneType>( - this, &OpenFilePickerSession::SinglePickerDone)); - DCHECK(handler.Get() != NULL); - hr = completion->put_Completed(handler.Get()); - - return hr; - } -} - -HRESULT OpenFilePickerSession::ComposeMultiFileResult( - StorageFileVectorCollection* files, string16* result) { - DCHECK(files != NULL); - DCHECK(result != NULL); - - // Empty the output string. - result->clear(); - - size_t num_files = 0; - HRESULT hr = files->get_Size(&num_files); - if (FAILED(hr)) - return hr; - - // Make sure we return an error on an empty collection. - if (num_files == 0) { - DLOG(ERROR) << "Empty collection on input."; - return E_UNEXPECTED; - } - - // This stores the base path that should be the parent of all the files. - FilePath base_path; - - // Iterate through the collection and append the file paths to the result. - for (size_t i = 0; i < num_files; ++i) { - mswr::ComPtr<winstorage::IStorageFile> file; - hr = files->GetAt(i, file.GetAddressOf()); - if (FAILED(hr)) - return hr; - - mswr::ComPtr<winstorage::IStorageItem> storage_item; - hr = file.As(&storage_item); - if (FAILED(hr)) - return hr; - - mswrw::HString file_path_str; - hr = storage_item->get_Path(file_path_str.GetAddressOf()); - if (FAILED(hr)) - return hr; - - FilePath file_path(MakeStdWString(file_path_str.Get())); - if (base_path.empty()) { - DCHECK(result->empty()); - base_path = file_path.DirName(); - - // Append the path, including the terminating zero. - // We do this only for the first file. - result->append(base_path.value().c_str(), base_path.value().size() + 1); - } - DCHECK(!result->empty()); - DCHECK(!base_path.empty()); - DCHECK(base_path == file_path.DirName()); - - // Append the base name, including the terminating zero. - FilePath base_name = file_path.BaseName(); - result->append(base_name.value().c_str(), base_name.value().size() + 1); - } - - DCHECK(!result->empty()); - - return S_OK; -} - -SaveFilePickerSession::SaveFilePickerSession(OPENFILENAME* open_file_name) - : FilePickerSessionBase(open_file_name) { -} - -HRESULT SaveFilePickerSession::StartFilePicker() { - DCHECK(globals.appview_msg_loop->BelongsToCurrentThread()); - DCHECK(open_file_name_ != NULL); - - mswrw::HStringReference class_name( - RuntimeClass_Windows_Storage_Pickers_FileSavePicker); - - // Create the file picker. - mswr::ComPtr<winstorage::Pickers::IFileSavePicker> picker; - HRESULT hr = ::Windows::Foundation::ActivateInstance( - class_name.Get(), picker.GetAddressOf()); - CheckHR(hr); - - typedef winfoundtn::Collections::IMap<HSTRING, StringVectorItf*> - StringVectorMap; - mswr::ComPtr<StringVectorMap> choices; - hr = picker->get_FileTypeChoices(choices.GetAddressOf()); - if (FAILED(hr)) - return hr; - - if (open_file_name_->lpstrFilter) { - // The filter is a concatenation of zero terminated string pairs, - // where each pair is {description, extension list}. The concatenation ends - // with a zero length string - e.g. a double zero terminator. - const wchar_t* walk = open_file_name_->lpstrFilter; - while (*walk != L'\0') { - mswrw::HString description; - hr = description.Set(walk); - if (FAILED(hr)) - return hr; - - // Walk past the description. - walk += wcslen(walk) + 1; - - // We should have an extension, but bail on malformed filters. - if (*walk == L'\0') - break; - - // There can be a single extension, or a list of semicolon-separated ones. - std::vector<string16> extensions_win32_style; - size_t extension_count = Tokenize(walk, L";", &extensions_win32_style); - DCHECK_EQ(extension_count, extensions_win32_style.size()); - - // Metro wants suffixes only, not patterns. Also, metro does not support - // the all files ("*") pattern in the save picker. - std::vector<string16> extensions; - for (size_t i = 0; i < extensions_win32_style.size(); ++i) { - string16 ext = FilePath(extensions_win32_style[i]).Extension(); - if ((ext.size() < 2) || - (ext.find_first_of(L"*?") != string16::npos)) - continue; - extensions.push_back(ext); - } - - if (!extensions.empty()) { - // Convert to a Metro collection class. - mswr::ComPtr<StringVectorItf> list; - hr = mswr::MakeAndInitialize<StringVectorImpl>( - list.GetAddressOf(), extensions); - if (FAILED(hr)) - return hr; - - // Finally set the filter. - boolean replaced = FALSE; - hr = choices->Insert(description.Get(), list.Get(), &replaced); - if (FAILED(hr)) - return hr; - DCHECK_EQ(FALSE, replaced); - } - - // Walk past the extension(s). - walk += wcslen(walk) + 1; - } - } - - // The save picker requires at least one choice. Callers are strongly advised - // to provide sensible choices. If none were given, fallback to .dat. - uint32 num_choices = 0; - hr = choices->get_Size(&num_choices); - if (FAILED(hr)) - return hr; - - if (num_choices == 0) { - mswrw::HString description; - // TODO(grt): Get a properly translated string. This can't be done from - // within metro_driver. Consider preprocessing the filter list in Chrome - // land to ensure it has this entry if all others are patterns. In that - // case, this whole block of code can be removed. - hr = description.Set(L"Data File"); - if (FAILED(hr)) - return hr; - - mswr::ComPtr<StringVectorItf> list; - hr = mswr::MakeAndInitialize<StringVectorImpl>( - list.GetAddressOf(), std::vector<string16>(1, L".dat")); - if (FAILED(hr)) - return hr; - - boolean replaced = FALSE; - hr = choices->Insert(description.Get(), list.Get(), &replaced); - if (FAILED(hr)) - return hr; - DCHECK_EQ(FALSE, replaced); - } - - if (open_file_name_->lpstrFile != NULL) { - hr = picker->put_SuggestedFileName( - mswrw::HStringReference( - const_cast<const wchar_t*>(open_file_name_->lpstrFile)).Get()); - if (FAILED(hr)) - return hr; - } - - mswr::ComPtr<SaveFileAsyncOp> completion; - hr = picker->PickSaveFileAsync(&completion); - if (FAILED(hr)) - return hr; - - // Create the callback method. - typedef winfoundtn::IAsyncOperationCompletedHandler< - winstorage::StorageFile*> HandlerDoneType; - mswr::ComPtr<HandlerDoneType> handler(mswr::Callback<HandlerDoneType>( - this, &SaveFilePickerSession::FilePickerDone)); - DCHECK(handler.Get() != NULL); - hr = completion->put_Completed(handler.Get()); - - return hr; -} - -HRESULT SaveFilePickerSession::FilePickerDone(SaveFileAsyncOp* async, - AsyncStatus status) { - if (status == Completed) { - mswr::ComPtr<winstorage::IStorageFile> file; - HRESULT hr = async->GetResults(file.GetAddressOf()); - - if (file) { - mswr::ComPtr<winstorage::IStorageItem> storage_item; - if (SUCCEEDED(hr)) - hr = file.As(&storage_item); - - mswrw::HString file_path; - if (SUCCEEDED(hr)) - hr = storage_item->get_Path(file_path.GetAddressOf()); - - if (SUCCEEDED(hr)) { - string16 path_str = MakeStdWString(file_path.Get()); - - // If the selected file name is longer than the supplied buffer, - // we return false as per GetOpenFileName documentation. - if (path_str.size() < open_file_name_->nMaxFile) { - base::wcslcpy(open_file_name_->lpstrFile, - path_str.c_str(), - open_file_name_->nMaxFile); - success_ = true; - } - } - } else { - LOG(ERROR) << "NULL IStorageItem"; - } - } else { - LOG(ERROR) << "Unexpected async status " << status; - } - - event_.Signal(); - - return S_OK; -} - -} // namespace - -BOOL MetroGetOpenFileName(OPENFILENAME* open_file_name) { - OpenFilePickerSession session(open_file_name); - - return session.Run(); -} - -BOOL MetroGetSaveFileName(OPENFILENAME* open_file_name) { - SaveFilePickerSession session(open_file_name); - - return session.Run(); -} diff --git a/win8/metro_driver/file_picker.h b/win8/metro_driver/file_picker.h deleted file mode 100644 index ef56cb3..0000000 --- a/win8/metro_driver/file_picker.h +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright (c) 2012 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. -#ifndef CHROME_BROWSER_UI_METRO_DRIVER_FILE_PICKER_H_ -#define CHROME_BROWSER_UI_METRO_DRIVER_FILE_PICKER_H_ - -#include <commdlg.h> - -// This function behaves similarly to GetOpenFileName, except it uses a -// Metro file picker to pick a single or multiple file names. -extern "C" __declspec(dllexport) -BOOL MetroGetOpenFileName(OPENFILENAME* open_file_name); - -extern "C" __declspec(dllexport) -BOOL MetroGetSaveFileName(OPENFILENAME* open_file_name); - -#endif // CHROME_BROWSER_UI_METRO_DRIVER_FILE_PICKER_H_ - diff --git a/win8/metro_driver/metro_dialog_box.cc b/win8/metro_driver/metro_dialog_box.cc deleted file mode 100644 index 25e7082..0000000 --- a/win8/metro_driver/metro_dialog_box.cc +++ /dev/null @@ -1,160 +0,0 @@ -// Copyright (c) 2012 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 "win8/metro_driver/stdafx.h" - -#include "win8/metro_driver/chrome_app_view.h" -#include "win8/metro_driver/metro_dialog_box.h" -#include "win8/metro_driver/winrt_utils.h" - -typedef winfoundtn::Collections:: - IVector<ABI::Windows::UI::Popups::IUICommand*> WindowsUICommands; - -typedef winfoundtn::IAsyncOperation<ABI::Windows::UI::Popups::IUICommand*> - AsyncCommandStatus; - -MetroDialogBox::MetroDialogBox() { - DVLOG(1) << __FUNCTION__; - dialog_box_info_.button1_handler = NULL; - dialog_box_info_.button2_handler = NULL; -} - -MetroDialogBox::~MetroDialogBox() { - DVLOG(1) << __FUNCTION__; -} - -void MetroDialogBox::Show( - const DialogBoxInfo& dialog_box_info) { - DVLOG(1) << __FUNCTION__; - - // Only one dialog can be displayed at a given time. - DCHECK(dialog_box_.Get() == NULL); - - // The message dialog display does not work correctly in snapped mode. - mswr::ComPtr<winui::Popups::IMessageDialogFactory> message_dialog_factory; - HRESULT hr = winrt_utils::CreateActivationFactory( - RuntimeClass_Windows_UI_Popups_MessageDialog, - message_dialog_factory.GetAddressOf()); - CheckHR(hr, "Failed to activate IMessageDialogFactory"); - - mswrw::HString message_title; - message_title.Attach(MakeHString(dialog_box_info.title)); - - mswrw::HString message_content; - message_content.Attach(MakeHString(dialog_box_info.content)); - - hr = message_dialog_factory->CreateWithTitle( - message_content.Get(), - message_title.Get(), - dialog_box_.GetAddressOf()); - CheckHR(hr, "Failed to create message dialog"); - - mswr::ComPtr<WindowsUICommands> commands; - hr = dialog_box_->get_Commands(commands.GetAddressOf()); - CheckHR(hr, "Failed to create ui command collection"); - - mswr::ComPtr<winui::Popups::IUICommandFactory> ui_command_factory; - hr = winrt_utils::CreateActivationFactory( - RuntimeClass_Windows_UI_Popups_UICommand, - ui_command_factory.GetAddressOf()); - CheckHR(hr, "Failed to activate IUICommandFactory"); - - mswrw::HString label1; - label1.Attach(MakeHString(dialog_box_info.button1_label)); - - mswr::ComPtr<winui::Popups::IUICommand> label1_command; - hr = ui_command_factory->CreateWithHandler( - label1.Get(), this, label1_command.GetAddressOf()); - CheckHR(hr, "Failed to add button1"); - - mswrw::HString label2; - label2.Attach(MakeHString(dialog_box_info.button2_label)); - - mswr::ComPtr<winui::Popups::IUICommand> label2_command; - hr = ui_command_factory->CreateWithHandler(label2.Get(), this, - label2_command.GetAddressOf()); - CheckHR(hr, "Failed to add button2"); - - commands->Append(label1_command.Get()); - commands->Append(label2_command.Get()); - - mswr::ComPtr<AsyncCommandStatus> ret; - hr = dialog_box_->ShowAsync(ret.GetAddressOf()); - CheckHR(hr, "Failed to show dialog"); - - dialog_box_info_ = dialog_box_info; -} - -// The dialog box displayed via the MessageDialog interface has the class name -// 'Shell_Dialog'. The dialog box is top level window. To find it we enumerate -// all top level windows and compare the class names. If we find a matching -// window class we compare its process id with ours and return the same. -BOOL CALLBACK DialogBoxFinder(HWND hwnd, LPARAM lparam) { - char classname[MAX_PATH] = {0}; - - if (::GetClassNameA(hwnd, classname, ARRAYSIZE(classname))) { - if (lstrcmpiA("Shell_Dialog", classname) == 0) { - if (GetWindowLong(hwnd, GWL_EXSTYLE) & WS_EX_TOPMOST) { - DVLOG(1) << "Found top most dialog box: " << classname; - DVLOG(1) << "HWND: " << hwnd; - DWORD window_pid = 0; - DWORD window_tid = GetWindowThreadProcessId(hwnd, &window_pid); - DVLOG(1) << "Window tid: " << window_tid; - DVLOG(1) << "Window pid: " << window_pid; - - if (window_pid == ::GetCurrentProcessId()) { - HWND* dialog_window = reinterpret_cast<HWND*>(lparam); - *dialog_window = hwnd; - return FALSE; - } - } - } - } - return TRUE; -} - -void MetroDialogBox::Dismiss() { - DVLOG(1) << __FUNCTION__; - if (!dialog_box_) - return; - - dialog_box_info_.button1_handler = NULL; - dialog_box_info_.button2_handler = NULL; - dialog_box_info_.button1_label.clear(); - dialog_box_info_.button2_label.clear(); - dialog_box_.Reset(); - - // We don't have a good way to dismiss the dialog box. Hack for now is to - // find the dialog box class in our process and close it via the WM_CLOSE - // message. - HWND dialog_box = NULL; - ::EnumWindows(&DialogBoxFinder, reinterpret_cast<LPARAM>(&dialog_box)); - if (::IsWindow(dialog_box)) - PostMessage(dialog_box, WM_CLOSE, 0, 0); -} - -HRESULT STDMETHODCALLTYPE MetroDialogBox::Invoke( - winui::Popups::IUICommand* command) { - DVLOG(1) << __FUNCTION__; - - mswrw::HString label; - command->get_Label(label.GetAddressOf()); - - string16 button_label = MakeStdWString(label.Get()); - DVLOG(1) << "Clicked button label is : " << button_label; - if (button_label == dialog_box_info_.button1_label) { - DVLOG(1) << "Button1 clicked"; - DCHECK(dialog_box_info_.button1_handler); - dialog_box_info_.button1_handler(); - } else if (button_label == dialog_box_info_.button2_label) { - DVLOG(1) << "Button2 clicked"; - DCHECK(dialog_box_info_.button2_handler); - dialog_box_info_.button2_handler(); - } - // The dialog box is destroyed once we return from invoke. Go ahead and - // dismiss it. - Dismiss(); - return S_OK; -} - diff --git a/win8/metro_driver/metro_dialog_box.h b/win8/metro_driver/metro_dialog_box.h deleted file mode 100644 index 5a6a94d..0000000 --- a/win8/metro_driver/metro_dialog_box.h +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright (c) 2012 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. - -#ifndef CHROME_BROWSER_UI_METRO_DRIVER_METRO_DIALOG_BOX_H_ -#define CHROME_BROWSER_UI_METRO_DRIVER_METRO_DIALOG_BOX_H_ - -#include <windows.ui.popups.h> -#include <string> - -#include "base/logging.h" -#include "base/memory/ref_counted.h" -#include "base/win/metro.h" - -// Provides functionality to display a dialog box -class MetroDialogBox : public winui::Popups::IUICommandInvokedHandler { - public: - struct DialogBoxInfo { - string16 title; - string16 content; - string16 button1_label; - string16 button2_label; - base::win::MetroDialogButtonPressedHandler button1_handler; - base::win::MetroDialogButtonPressedHandler button2_handler; - }; - - MetroDialogBox(); - ~MetroDialogBox(); - - // Displays the dialog box. - void Show(const DialogBoxInfo& dialog_box_info); - - // Dismisses the dialog box. - void Dismiss(); - - // IUICommandInvokedHandler implementation. - // Dummy implementation of IUnknown. This is fine as the lifetime of this - // class is tied to the lifetime of the ChromeAppView instance. - virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void** object) { - DVLOG(1) << __FUNCTION__; - CHECK(false); - return E_NOINTERFACE; - } - - virtual ULONG STDMETHODCALLTYPE AddRef(void) { - DVLOG(1) << __FUNCTION__; - return 1; - } - - virtual ULONG STDMETHODCALLTYPE Release(void) { - DVLOG(1) << __FUNCTION__; - return 1; - } - - virtual HRESULT STDMETHODCALLTYPE Invoke(winui::Popups::IUICommand* command); - - private: - // The actual dialog box. - mswr::ComPtr<winui::Popups::IMessageDialog> dialog_box_; - DialogBoxInfo dialog_box_info_; -}; - -#endif // CHROME_BROWSER_UI_METRO_DRIVER_METRO_DIALOG_BOX_H_ - diff --git a/win8/metro_driver/metro_driver.cc b/win8/metro_driver/metro_driver.cc deleted file mode 100644 index 89bd35a..0000000 --- a/win8/metro_driver/metro_driver.cc +++ /dev/null @@ -1,211 +0,0 @@ -// Copyright (c) 2012 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 "stdafx.h" - -#include <roerrorapi.h> -#include <shobjidl.h> - -#include "base/at_exit.h" -#include "base/command_line.h" -#include "base/logging.h" -#include "base/logging_win.h" -#include "base/win/scoped_comptr.h" -#include "win8/metro_driver/chrome_app_view.h" -#include "win8/metro_driver/winrt_utils.h" -#include "sandbox/win/src/sidestep/preamble_patcher.h" - -// TODO(siggi): Move this to GYP. -#pragma comment(lib, "runtimeobject.lib") - -namespace { - -LONG WINAPI ErrorReportingHandler(EXCEPTION_POINTERS* ex_info) { - // See roerrorapi.h for a description of the - // exception codes and parameters. - DWORD code = ex_info->ExceptionRecord->ExceptionCode; - ULONG_PTR* info = ex_info->ExceptionRecord->ExceptionInformation; - if (code == EXCEPTION_RO_ORIGINATEERROR) { - string16 msg(reinterpret_cast<wchar_t*>(info[2]), info[1]); - LOG(ERROR) << "VEH: Metro error 0x" << std::hex << info[0] << ": " << msg; - } else if (code == EXCEPTION_RO_TRANSFORMERROR) { - string16 msg(reinterpret_cast<wchar_t*>(info[3]), info[2]); - LOG(ERROR) << "VEH: Metro old error 0x" << std::hex << info[0] - << " new error 0x" << info[1] << ": " << msg; - } - - return EXCEPTION_CONTINUE_SEARCH; -} - -// TODO(robertshield): This GUID is hard-coded in a bunch of places that -// don't allow explicit includes. Find a single place for it to live. -// {7FE69228-633E-4f06-80C1-527FEA23E3A7} -const GUID kChromeTraceProviderName = { - 0x7fe69228, 0x633e, 0x4f06, - { 0x80, 0xc1, 0x52, 0x7f, 0xea, 0x23, 0xe3, 0xa7 } }; - -} -// Required for base initialization. -// TODO(siggi): This should be handled better, as this way our at exit -// registrations will run under the loader's lock. However, -// once metro_driver is merged into Chrome.dll, this will go away anyhow. -base::AtExitManager at_exit; - -namespace Hacks { - -typedef BOOL (WINAPI* IsImmersiveFunctionPtr)(HANDLE process); -char* g_real_is_immersive_proc_stub = NULL; - -HMODULE g_webrtc_quartz_dll_handle = NULL; -bool g_fake_is_immersive_process_ret = false; - -BOOL WINAPI MetroChromeIsImmersiveIntercept(HANDLE process) { - if (g_fake_is_immersive_process_ret && process == ::GetCurrentProcess()) - return FALSE; - - IsImmersiveFunctionPtr real_proc = - reinterpret_cast<IsImmersiveFunctionPtr>( - static_cast<char*>(g_real_is_immersive_proc_stub)); - return real_proc(process); -} - -void MetroSpecificHacksInitialize() { - // The quartz dll which is used by the webrtc code in Chrome fails in a metro - // app. It checks this via the IsImmersiveProcess export in user32. We - // intercept the same and spoof the value as false. This is ok as technically - // a metro browser is not a real metro application. The webrtc functionality - // works fine with this hack. - // TODO(tommi) - // BUG:- https://code.google.com/p/chromium/issues/detail?id=140545 - // We should look into using media foundation on windows 8 in metro chrome. - IsImmersiveFunctionPtr is_immersive_func_address = - reinterpret_cast<IsImmersiveFunctionPtr>(::GetProcAddress( - ::GetModuleHandle(L"user32.dll"), "IsImmersiveProcess")); - DCHECK(is_immersive_func_address); - - // Allow the function to be patched by changing the protections on the page. - DWORD old_protect = 0; - ::VirtualProtect(is_immersive_func_address, 5, PAGE_EXECUTE_READWRITE, - &old_protect); - - DCHECK(g_real_is_immersive_proc_stub == NULL); - g_real_is_immersive_proc_stub = reinterpret_cast<char*>(VirtualAllocEx( - ::GetCurrentProcess(), NULL, sidestep::kMaxPreambleStubSize, - MEM_COMMIT, PAGE_EXECUTE_READWRITE)); - DCHECK(g_real_is_immersive_proc_stub); - - sidestep::SideStepError patch_result = - sidestep::PreamblePatcher::Patch( - is_immersive_func_address, MetroChromeIsImmersiveIntercept, - g_real_is_immersive_proc_stub, sidestep::kMaxPreambleStubSize); - - DCHECK(patch_result == sidestep::SIDESTEP_SUCCESS); - - // Restore the permissions on the page in user32 containing the - // IsImmersiveProcess function code. - DWORD dummy = 0; - ::VirtualProtect(is_immersive_func_address, 5, old_protect, &dummy); - - // Mimic the original page permissions from the IsImmersiveProcess page - // on our stub. - ::VirtualProtect(g_real_is_immersive_proc_stub, - sidestep::kMaxPreambleStubSize, - old_protect, - &old_protect); - - g_fake_is_immersive_process_ret = true; - g_webrtc_quartz_dll_handle = LoadLibrary(L"quartz.dll"); - g_fake_is_immersive_process_ret = false; - - DCHECK(g_webrtc_quartz_dll_handle); - if (!g_webrtc_quartz_dll_handle) { - DVLOG(1) << "Quartz dll load failed with error: " << GetLastError(); - } else { - // Pin the quartz module to protect against it being inadvarently unloaded. - ::GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_PIN, L"quartz.dll", - &g_webrtc_quartz_dll_handle); - } -} - -} // namespace Hacks - -extern "C" __declspec(dllexport) -int InitMetro(LPTHREAD_START_ROUTINE thread_proc, void* context) { - // Initialize the command line. - CommandLine::Init(0, NULL); - logging::InitLogging( - NULL, - logging::LOG_ONLY_TO_SYSTEM_DEBUG_LOG, - logging::LOCK_LOG_FILE, - logging::DELETE_OLD_LOG_FILE, - logging::DISABLE_DCHECK_FOR_NON_OFFICIAL_RELEASE_BUILDS); - -#if defined(NDEBUG) - logging::SetMinLogLevel(logging::LOG_ERROR); - // Bind to the breakpad handling function. - globals.breakpad_exception_handler = - reinterpret_cast<BreakpadExceptionHandler>( - ::GetProcAddress(::GetModuleHandle(NULL), - "CrashForException")); - if (!globals.breakpad_exception_handler) { - DVLOG(0) << "CrashForException export not found"; - } -#else - logging::SetMinLogLevel(logging::LOG_VERBOSE); - // Set the error reporting flags to always raise an exception, - // which is then processed by our vectored exception handling - // above to log the error message. - winfoundtn::Diagnostics::SetErrorReportingFlags( - winfoundtn::Diagnostics::UseSetErrorInfo | - winfoundtn::Diagnostics::ForceExceptions); - - HANDLE registration = - ::AddVectoredExceptionHandler(TRUE, ErrorReportingHandler); -#endif - - // Enable trace control and transport through event tracing for Windows. - logging::LogEventProvider::Initialize(kChromeTraceProviderName); - - DVLOG(1) << "InitMetro"; - - mswrw::RoInitializeWrapper ro_initializer(RO_INIT_MULTITHREADED); - CheckHR(ro_initializer, "RoInitialize failed"); - - mswr::ComPtr<winapp::Core::ICoreApplication> core_app; - HRESULT hr = winrt_utils::CreateActivationFactory( - RuntimeClass_Windows_ApplicationModel_Core_CoreApplication, - core_app.GetAddressOf()); - CheckHR(hr, "Failed to create app factory"); - if (FAILED(hr)) - return 1; - - // The metro specific hacks code assumes that there is only one thread active - // at the moment. This better be the case or we may have race conditions. - Hacks::MetroSpecificHacksInitialize(); - - auto view_factory = mswr::Make<ChromeAppViewFactory>( - core_app.Get(), thread_proc, context); - hr = core_app->Run(view_factory.Get()); - DVLOG(1) << "exiting InitMetro, hr=" << hr; - -#if !defined(NDEBUG) - ::RemoveVectoredExceptionHandler(registration); -#endif - - return hr; -} - -// Activates the application known by |app_id|. Returns, among other things, -// E_APPLICATION_NOT_REGISTERED if |app_id| identifies Chrome and Chrome is not -// the default browser. -extern "C" __declspec(dllexport) -HRESULT ActivateApplication(const wchar_t* app_id) { - base::win::ScopedComPtr<IApplicationActivationManager> activator; - HRESULT hr = activator.CreateInstance(CLSID_ApplicationActivationManager); - if (SUCCEEDED(hr)) { - DWORD pid = 0; - hr = activator->ActivateApplication(app_id, L"", AO_NONE, &pid); - } - return hr; -} diff --git a/win8/metro_driver/metro_driver.gyp b/win8/metro_driver/metro_driver.gyp deleted file mode 100644 index 266c4b6..0000000 --- a/win8/metro_driver/metro_driver.gyp +++ /dev/null @@ -1,98 +0,0 @@ -# Copyright (c) 2012 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. -{ - 'conditions': [ - ['OS=="win" and (MSVS_VERSION=="2010" or MSVS_VERSION=="2010e")', { - 'variables': { - 'chromium_code': 1, - }, - 'includes': [ - '../../build/win_precompile.gypi', - ], - 'target_defaults': { - 'defines': [ - # This define is required to pull in the new Win8 interfaces from - # system headers like ShObjIdl.h - 'NTDDI_VERSION=0x06020000', - ], - 'msvs_settings': { - 'VCLinkerTool': { - 'AdditionalDependencies': [ - 'D2D1.lib', - 'D3D11.lib', - ], - }, - }, - }, - 'targets': [ - { - 'target_name': 'metro_driver', - 'type': 'shared_library', - 'dependencies': [ - '../../base/base.gyp:base', - '../../crypto/crypto.gyp:crypto', - '../../sandbox/sandbox.gyp:sandbox', - '../../google_update/google_update.gyp:google_update', - '../win8.gyp:check_sdk_patch', - ], - 'sources': [ - 'chrome_app_view.cc', - 'chrome_app_view.h', - 'chrome_url_launch_handler.cc', - 'chrome_url_launch_handler.h', - '../delegate_execute/chrome_util.cc', - '../win8/delegate_execute/chrome_util.h', - 'devices_handler.cc', - 'devices_handler.h', - 'file_picker.h', - 'file_picker.cc', - 'metro_dialog_box.cc', - 'metro_dialog_box.h', - 'metro_driver.cc', - 'print_handler.cc', - 'print_handler.h', - 'print_document_source.cc', - 'print_document_source.h', - 'secondary_tile.h', - 'secondary_tile.cc', - 'settings_handler.cc', - 'settings_handler.h', - 'stdafx.h', - 'toast_notification_handler.cc', - 'toast_notification_handler.h', - 'winrt_utils.cc', - 'winrt_utils.h', - ], - 'copies': [ - { - 'destination': '<(PRODUCT_DIR)', - 'files': [ - 'resources/Logo.png', - 'resources/SecondaryTile.png', - 'resources/SmallLogo.png', - 'resources/splash-620x300.png', - 'resources/VisualElementsManifest.xml', - ], - }, - ], - }, - { - 'target_name': 'metro_driver_unittests', - 'type': 'executable', - 'dependencies': [ - '../../base/base.gyp:base', - '../../testing/gtest.gyp:gtest', - 'metro_driver', - ], - 'sources': [ - 'run_all_unittests.cc', - 'winrt_utils.cc', - 'winrt_utils.h', - 'winrt_utils_unittest.cc', - ], - }, - ], - },], - ], -} diff --git a/win8/metro_driver/metro_driver_win7.cc b/win8/metro_driver/metro_driver_win7.cc deleted file mode 100644 index 253e527..0000000 --- a/win8/metro_driver/metro_driver_win7.cc +++ /dev/null @@ -1,139 +0,0 @@ -// Copyright (c) 2012 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 "stdafx.h" - -EXTERN_C IMAGE_DOS_HEADER __ImageBase; - -struct Globals { - LPTHREAD_START_ROUTINE host_main; - void* host_context; - HWND core_window; - HWND host_window; - HANDLE host_thread; - DWORD main_thread_id; -} globals; - - -void ODS(const char* str, LONG_PTR val = 0) { - char buf[80]; - size_t len = strlen(str); - if (len > 50) { - ::OutputDebugStringA("ODS: buffer too long"); - return; - } - - if (str[0] == '!') { - // Fatal error. - DWORD gle = ::GetLastError(); - if (::IsDebuggerPresent()) - __debugbreak(); - wsprintfA(buf, "ODS:fatal %s (%p) gle=0x%x", str, val, gle); - ::MessageBoxA(NULL, buf, "!!!", MB_OK); - ::ExitProcess(gle); - } else { - // Just information. - wsprintfA(buf, "ODS:%s (%p)\n", str, val); - ::OutputDebugStringA(buf); - } -} - -LRESULT CALLBACK WndProc(HWND hwnd, UINT message, - WPARAM wparam, LPARAM lparam) { - PAINTSTRUCT ps; - HDC hdc; - switch (message) { - case WM_PAINT: - hdc = BeginPaint(hwnd, &ps); - EndPaint(hwnd, &ps); - break; - case WM_DESTROY: - PostQuitMessage(0); - ODS("Metro WM_DESTROY received"); - break; - default: - return DefWindowProc(hwnd, message, wparam, lparam); - } - return 0; -} - -HWND CreateMetroTopLevelWindow() { - HINSTANCE hInst = reinterpret_cast<HINSTANCE>(&__ImageBase); - WNDCLASSEXW wcex; - wcex.cbSize = sizeof(wcex); - wcex.style = CS_HREDRAW | CS_VREDRAW; - wcex.lpfnWndProc = WndProc; - wcex.cbClsExtra = 0; - wcex.cbWndExtra = 0; - wcex.hInstance = hInst; - wcex.hIcon = 0; - wcex.hCursor = LoadCursor(NULL, IDC_ARROW); - wcex.hbrBackground = (HBRUSH)(COLOR_INACTIVECAPTION+1); - wcex.lpszMenuName = 0; - wcex.lpszClassName = L"Windows.UI.Core.CoreWindow"; - wcex.hIconSm = 0; - - HWND hwnd = ::CreateWindowExW(0, - MAKEINTATOM(::RegisterClassExW(&wcex)), - L"metro_metro", - WS_POPUP, - 0, 0, 0, 0, - NULL, NULL, hInst, NULL); - return hwnd; -} - -DWORD WINAPI HostThread(void*) { - // The sleeps simulates the delay we have in the actual metro code - // which takes in account the corewindow being created and some other - // unknown machinations of metro. - ODS("Chrome main thread", ::GetCurrentThreadId()); - ::Sleep(30); - return globals.host_main(globals.host_context); -} - -extern "C" __declspec(dllexport) -int InitMetro(LPTHREAD_START_ROUTINE thread_proc, void* context) { - ODS("InitMetro [Win7 emulation]"); - HWND window = CreateMetroTopLevelWindow(); - if (!window) - return 1; - // This magic incatation tells windows that the window is going fullscreen - // so the taskbar gets out of the wait automatically. - ::SetWindowPos(window, - HWND_TOP, - 0,0, - GetSystemMetrics(SM_CXSCREEN), - GetSystemMetrics(SM_CYSCREEN), - SWP_SHOWWINDOW); - - // Ready to start our caller. - globals.core_window = window; - globals.host_main = thread_proc; - globals.host_context = context; - HANDLE thread = ::CreateThread(NULL, 0, &HostThread, NULL, 0, NULL); - - // Main message loop. - MSG msg = {0}; - while (GetMessage(&msg, NULL, 0, 0)) { - TranslateMessage(&msg); - DispatchMessage(&msg); - } - - return (int) msg.wParam; -} - -extern "C" _declspec(dllexport) HWND GetRootWindow() { - ODS("GetRootWindow", ULONG_PTR(globals.core_window)); - return globals.core_window; -} - -extern "C" _declspec(dllexport) void SetFrameWindow(HWND window) { - ODS("SetFrameWindow", ULONG_PTR(window)); - globals.host_window = window; -} - -extern "C" __declspec(dllexport) const wchar_t* GetInitialUrl() { - return L""; -} - diff --git a/win8/metro_driver/print_document_source.cc b/win8/metro_driver/print_document_source.cc deleted file mode 100644 index 7469597..0000000 --- a/win8/metro_driver/print_document_source.cc +++ /dev/null @@ -1,525 +0,0 @@ -// Copyright (c) 2012 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 "stdafx.h" -#include "win8/metro_driver/print_document_source.h" - -#include <windows.graphics.display.h> - -#include "base/logging.h" - - -namespace { - -class D2DFactoryAutoLock { - public: - explicit D2DFactoryAutoLock(ID2D1Factory* d2d_factory) { - HRESULT hr = d2d_factory->QueryInterface(IID_PPV_ARGS(&d2d_multithread_)); - if (d2d_multithread_.Get()) - d2d_multithread_->Enter(); - else - NOTREACHED() << "Failed to QI for ID2D1Multithread " << std::hex << hr; - } - - ~D2DFactoryAutoLock() { - if (d2d_multithread_.Get()) - d2d_multithread_->Leave(); - } - - private: - mswr::ComPtr<ID2D1Multithread> d2d_multithread_; -}; - -// TODO(mad): remove once we don't run mixed SDK/OS anymore. -const GUID kOldPackageTargetGuid = - {0xfb2a33c0, 0x8c35, 0x465f, - {0xbe, 0xd5, 0x9f, 0x36, 0x89, 0x51, 0x77, 0x52}}; -const GUID kNewPackageTargetGuid = - {0x1a6dd0ad, 0x1e2a, 0x4e99, - {0xa5, 0xba, 0x91, 0xf1, 0x78, 0x18, 0x29, 0x0e}}; - - -} // namespace - -namespace metro_driver { - -PrintDocumentSource::PrintDocumentSource() - : page_count_ready_(true, false), - parent_lock_(NULL), - height_(0), - width_(0), - dpi_(96), - aborted_(false), - using_old_preview_interface_(false) { -} - -HRESULT PrintDocumentSource::RuntimeClassInitialize( - const DirectXContext& directx_context, - base::Lock* parent_lock) { - DCHECK(parent_lock != NULL); - DCHECK(directx_context.d2d_context.Get() != NULL); - DCHECK(directx_context.d2d_device.Get() != NULL); - DCHECK(directx_context.d2d_factory.Get() != NULL); - DCHECK(directx_context.d3d_device.Get() != NULL); - DCHECK(directx_context.wic_factory.Get() != NULL); - directx_context_ = directx_context; - - // No other method can be called before RuntimeClassInitialize which is called - // during the construction via mswr::MakeAndInitialize(), so it's safe for all - // other methods to use the parent_lock_ without checking if it's NULL. - DCHECK(parent_lock_ == NULL); - parent_lock_ = parent_lock; - - return S_OK; -} - -void PrintDocumentSource::Abort() { - base::AutoLock lock(*parent_lock_); - aborted_ = true; - if (page_count_ready_.IsSignaled()) { - pages_.clear(); - for (size_t i = 0; i < pages_ready_state_.size(); ++i) - pages_ready_state_[i]->Broadcast(); - } else { - DCHECK(pages_.empty() && pages_ready_state_.empty()); - } -} - -STDMETHODIMP PrintDocumentSource::GetPreviewPageCollection( - IPrintDocumentPackageTarget* package_target, - IPrintPreviewPageCollection** page_collection) { - DVLOG(1) << __FUNCTION__; - DCHECK(package_target != NULL); - DCHECK(page_collection != NULL); - - HRESULT hr = package_target->GetPackageTarget( - __uuidof(IPrintPreviewDxgiPackageTarget), - IID_PPV_ARGS(&dxgi_preview_target_)); - if (FAILED(hr)) { - // TODO(mad): remove once we don't run mixed SDK/OS anymore. - // The IID changed from one version of the SDK to another, so try the other - // one in case we are running a build from a different SDK than the one - // related to the OS version we are running. - GUID package_target_uuid = kNewPackageTargetGuid; - if (package_target_uuid == __uuidof(IPrintPreviewDxgiPackageTarget)) { - package_target_uuid = kOldPackageTargetGuid; - using_old_preview_interface_ = true; - } - hr = package_target->GetPackageTarget(package_target_uuid, - package_target_uuid, - &dxgi_preview_target_); - if (FAILED(hr)) { - LOG(ERROR) << "Failed to get IPrintPreviewDXGIPackageTarget " << std::hex - << hr; - return hr; - } - } else { - using_old_preview_interface_ = (__uuidof(IPrintPreviewDxgiPackageTarget) == - kOldPackageTargetGuid); - } - - mswr::ComPtr<IPrintPreviewPageCollection> preview_page_collection; - mswr::ComPtr<PrintDocumentSource> print_document_source(this); - hr = print_document_source.As(&preview_page_collection); - if (FAILED(hr)) { - LOG(ERROR) << "Failed to get preview_page_collection " << std::hex << hr; - return hr; - } - - hr = preview_page_collection.CopyTo(page_collection); - if (FAILED(hr)) { - LOG(ERROR) << "Failed to copy preview_page_collection " << std::hex << hr; - return hr; - } - return hr; -} - -STDMETHODIMP PrintDocumentSource::MakeDocument( - IInspectable* options, - IPrintDocumentPackageTarget* package_target) { - DVLOG(1) << __FUNCTION__; - DCHECK(options != NULL); - DCHECK(package_target != NULL); - - mswr::ComPtr<wingfx::Printing::IPrintTaskOptionsCore> print_task_options; - HRESULT hr = options->QueryInterface( - wingfx::Printing::IID_IPrintTaskOptionsCore, - reinterpret_cast<void**>(print_task_options.GetAddressOf())); - if (FAILED(hr)) { - LOG(ERROR) << "Failed to QI for IPrintTaskOptionsCore " << std::hex << hr; - return hr; - } - - // Use the first page's description for the whole document. Page numbers - // are 1-based in this context. - // TODO(mad): Check if it would be useful to use per page descriptions. - wingfx::Printing::PrintPageDescription page_desc = {}; - hr = print_task_options->GetPageDescription(1 /* page */, &page_desc); - if (FAILED(hr)) { - LOG(ERROR) << "Failed to GetPageDescription " << std::hex << hr; - return hr; - } - - D2D1_PRINT_CONTROL_PROPERTIES print_control_properties; - if (page_desc.DpiX > page_desc.DpiY) - print_control_properties.rasterDPI = static_cast<float>(page_desc.DpiY); - else - print_control_properties.rasterDPI = static_cast<float>(page_desc.DpiX); - - // Color space for vector graphics in D2D print control. - print_control_properties.colorSpace = D2D1_COLOR_SPACE_SRGB; - print_control_properties.fontSubset = D2D1_PRINT_FONT_SUBSET_MODE_DEFAULT; - - mswr::ComPtr<ID2D1PrintControl> print_control; - hr = directx_context_.d2d_device->CreatePrintControl( - directx_context_.wic_factory.Get(), - package_target, - print_control_properties, - print_control.GetAddressOf()); - if (FAILED(hr)) { - LOG(ERROR) << "Failed to CreatePrintControl " << std::hex << hr; - return hr; - } - - D2D1_SIZE_F page_size = D2D1::SizeF(page_desc.PageSize.Width, - page_desc.PageSize.Height); - - // Wait for the number of pages to be available. - // If an abort occured, we'll get 0 and won't enter the loop below. - size_t page_count = WaitAndGetPageCount(); - - mswr::ComPtr<ID2D1GdiMetafile> gdi_metafile; - for (size_t page = 0; page < page_count; ++page) { - gdi_metafile.Reset(); - hr = WaitAndGetPage(page, gdi_metafile.GetAddressOf()); - LOG_IF(ERROR, FAILED(hr)) << "Failed to get page's metafile " << std::hex - << hr; - // S_FALSE means we got aborted. - if (hr == S_FALSE || FAILED(hr)) - break; - hr = PrintPage(print_control.Get(), gdi_metafile.Get(), page_size); - if (FAILED(hr)) - break; - } - - HRESULT close_hr = print_control->Close(); - if (FAILED(close_hr) && SUCCEEDED(hr)) - return close_hr; - else - return hr; -} - -STDMETHODIMP PrintDocumentSource::Paginate(uint32 page, - IInspectable* options) { - DVLOG(1) << __FUNCTION__ << ", page = " << page; - DCHECK(options != NULL); - // GetPreviewPageCollection must have been successfuly called. - DCHECK(dxgi_preview_target_.Get() != NULL); - - // Get print settings from PrintTaskOptions for preview, such as page - // description, which contains page size, imageable area, DPI. - // TODO(mad): obtain other print settings in the same way, such as ColorMode, - // NumberOfCopies, etc... - mswr::ComPtr<wingfx::Printing::IPrintTaskOptionsCore> print_options; - HRESULT hr = options->QueryInterface( - wingfx::Printing::IID_IPrintTaskOptionsCore, - reinterpret_cast<void**>(print_options.GetAddressOf())); - if (FAILED(hr)) { - LOG(ERROR) << "Failed to QI for IPrintTaskOptionsCore " << std::hex << hr; - return hr; - } - - wingfx::Printing::PrintPageDescription page_desc = {}; - hr = print_options->GetPageDescription(1 /* page */, &page_desc); - if (FAILED(hr)) { - LOG(ERROR) << "Failed to GetPageDescription " << std::hex << hr; - return hr; - } - - width_ = page_desc.PageSize.Width; - height_ = page_desc.PageSize.Height; - - hr = dxgi_preview_target_->InvalidatePreview(); - if (FAILED(hr)) { - LOG(ERROR) << "Failed to InvalidatePreview " << std::hex << hr; - return hr; - } - - size_t page_count = WaitAndGetPageCount(); - // A page_count of 0 means abort... - if (page_count == 0) - return S_FALSE; - hr = dxgi_preview_target_->SetJobPageCount(PageCountType::FinalPageCount, - page_count); - if (FAILED(hr)) { - LOG(ERROR) << "Failed to SetJobPageCount " << std::hex << hr; - return hr; - } - return hr; -} - -STDMETHODIMP PrintDocumentSource::MakePage(uint32 job_page, - float width, - float height) { - DVLOG(1) << __FUNCTION__ << ", width: " << width << ", height: " << height - << ", job_page: " << job_page; - DCHECK(width > 0 && height > 0); - // Paginate must have been called before this. - if (width_ <= 0.0 || height_ <= 0.0) - return S_FALSE; - - // When job_page is JOB_PAGE_APPLICATION_DEFINED, it means a new preview - // begins. TODO(mad): Double check if we need to cancel pending resources. - if (job_page == JOB_PAGE_APPLICATION_DEFINED) - job_page = 1; - - winfoundtn::Size preview_size; - preview_size.Width = width; - preview_size.Height = height; - float scale = width_ / width; - - mswr::ComPtr<ID2D1Factory> factory; - directx_context_.d2d_device->GetFactory(&factory); - - mswr::ComPtr<ID2D1GdiMetafile> gdi_metafile; - HRESULT hr = WaitAndGetPage(job_page - 1, gdi_metafile.GetAddressOf()); - LOG_IF(ERROR, FAILED(hr)) << "Failed to get page's metafile " << std::hex - << hr; - // Again, S_FALSE means we got aborted. - if (hr == S_FALSE || FAILED(hr)) - return hr; - - // We are accessing D3D resources directly without D2D's knowledge, so we - // must manually acquire the D2D factory lock. - D2DFactoryAutoLock factory_lock(directx_context_.d2d_factory.Get()); - - CD3D11_TEXTURE2D_DESC texture_desc( - DXGI_FORMAT_B8G8R8A8_UNORM, - static_cast<UINT32>(ceil(width * dpi_ / 96)), - static_cast<UINT32>(ceil(height * dpi_ / 96)), - 1, - 1, - D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE - ); - mswr::ComPtr<ID3D11Texture2D> texture; - hr = directx_context_.d3d_device->CreateTexture2D( - &texture_desc, NULL, &texture); - if (FAILED(hr)) { - LOG(ERROR) << "Failed to create a 2D texture " << std::hex << hr; - return hr; - } - - mswr::ComPtr<IDXGISurface> dxgi_surface; - hr = texture.As<IDXGISurface>(&dxgi_surface); - if (FAILED(hr)) { - LOG(ERROR) << "Failed to QI for IDXGISurface " << std::hex << hr; - return hr; - } - - // D2D device contexts are stateful, and hence a unique device context must - // be used on each call. - mswr::ComPtr<ID2D1DeviceContext> d2d_context; - hr = directx_context_.d2d_device->CreateDeviceContext( - D2D1_DEVICE_CONTEXT_OPTIONS_NONE, &d2d_context); - - d2d_context->SetDpi(dpi_, dpi_); - - mswr::ComPtr<ID2D1Bitmap1> d2dSurfaceBitmap; - hr = d2d_context->CreateBitmapFromDxgiSurface(dxgi_surface.Get(), - NULL, // default properties. - &d2dSurfaceBitmap); - if (FAILED(hr)) { - LOG(ERROR) << "Failed to CreateBitmapFromDxgiSurface " << std::hex << hr; - return hr; - } - - d2d_context->SetTarget(d2dSurfaceBitmap.Get()); - d2d_context->BeginDraw(); - d2d_context->Clear(); - d2d_context->SetTransform(D2D1::Matrix3x2F(1/scale, 0, 0, 1/scale, 0, 0)); - d2d_context->DrawGdiMetafile(gdi_metafile.Get()); - - hr = d2d_context->EndDraw(); - if (FAILED(hr)) { - LOG(ERROR) << "Failed to EndDraw " << std::hex << hr; - return hr; - } - -// TODO(mad): remove once we don't run mixed SDK/OS anymore. -#ifdef __IPrintPreviewDxgiPackageTarget_FWD_DEFINED__ - FLOAT dpi = dpi_; - if (using_old_preview_interface_) { - // We compiled with the new API but run on the old OS, so we must cheat - // and send something that looks like a float but has a UINT32 value. - *reinterpret_cast<UINT32*>(&dpi) = static_cast<UINT32>(dpi_); - } -#else - UINT32 dpi = static_cast<UINT32>(dpi_); - if (!using_old_preview_interface_) { - // We compiled with the old API but run on the new OS, so we must cheat - // and send something that looks like a UINT32 but has a float value. - *reinterpret_cast<FLOAT*>(&dpi) = dpi_; - } -#endif // __IPrintPreviewDxgiPackageTarget_FWD_DEFINED__ - hr = dxgi_preview_target_->DrawPage(job_page, dxgi_surface.Get(), dpi, dpi); - if (FAILED(hr)) { - LOG(ERROR) << "Failed to DrawPage " << std::hex << hr; - return hr; - } - return hr; -} - -void PrintDocumentSource::ResetDpi(float dpi) { - { - base::AutoLock lock(*parent_lock_); - if (dpi == dpi_) - return; - dpi_ = dpi; - } - directx_context_.d2d_context->SetDpi(dpi, dpi); -} - -void PrintDocumentSource::SetPageCount(size_t page_count) { - DCHECK(page_count > 0); - { - base::AutoLock lock(*parent_lock_); - DCHECK(!page_count_ready_.IsSignaled()); - DCHECK(pages_.empty() && pages_ready_state_.empty()); - - pages_.resize(page_count); - pages_ready_state_.resize(page_count); - - for (size_t i = 0; i < page_count; ++i) - pages_ready_state_[i].reset(new base::ConditionVariable(parent_lock_)); - } - page_count_ready_.Signal(); -} - -void PrintDocumentSource::AddPage(size_t page_number, - IStream* metafile_stream) { - DCHECK(metafile_stream != NULL); - base::AutoLock lock(*parent_lock_); - - DCHECK(page_count_ready_.IsSignaled()); - DCHECK(page_number < pages_.size()); - - pages_[page_number] = metafile_stream; - pages_ready_state_[page_number]->Signal(); -} - -HRESULT PrintDocumentSource::PrintPage(ID2D1PrintControl* print_control, - ID2D1GdiMetafile* gdi_metafile, - D2D1_SIZE_F page_size) { - DVLOG(1) << __FUNCTION__ << ", page_size: (" << page_size.width << ", " - << page_size.height << ")"; - DCHECK(print_control != NULL); - DCHECK(gdi_metafile != NULL); - - // D2D device contexts are stateful, and hence a unique device context must - // be used on each call. - mswr::ComPtr<ID2D1DeviceContext> d2d_context; - HRESULT hr = directx_context_.d2d_device->CreateDeviceContext( - D2D1_DEVICE_CONTEXT_OPTIONS_NONE, &d2d_context); - if (FAILED(hr)) { - LOG(ERROR) << "Failed to CreateDeviceContext " << std::hex << hr; - return hr; - } - - mswr::ComPtr<ID2D1CommandList> print_command_list; - hr = d2d_context->CreateCommandList(&print_command_list); - if (FAILED(hr)) { - LOG(ERROR) << "Failed to CreateCommandList " << std::hex << hr; - return hr; - } - - d2d_context->SetTarget(print_command_list.Get()); - - d2d_context->BeginDraw(); - d2d_context->DrawGdiMetafile(gdi_metafile); - hr = d2d_context->EndDraw(); - LOG_IF(ERROR, FAILED(hr)) << "Failed to EndDraw " << std::hex << hr; - - // Make sure to always close the command list. - HRESULT close_hr = print_command_list->Close(); - LOG_IF(ERROR, FAILED(close_hr)) << "Failed to close command list " << std::hex - << hr; - if (SUCCEEDED(hr) && SUCCEEDED(close_hr)) - hr = print_control->AddPage(print_command_list.Get(), page_size, NULL); - if (FAILED(hr)) - return hr; - else - return close_hr; -} - -size_t PrintDocumentSource::WaitAndGetPageCount() { - // Properly protect the wait/access to the page count. - { - base::AutoLock lock(*parent_lock_); - if (aborted_) - return 0; - DCHECK(pages_.size() == pages_ready_state_.size()); - if (!pages_.empty()) - return pages_.size(); - } - page_count_ready_.Wait(); - { - base::AutoLock lock(*parent_lock_); - if (!aborted_) { - DCHECK(pages_.size() == pages_ready_state_.size()); - return pages_.size(); - } - } - // A page count of 0 means abort. - return 0; -} - -HRESULT PrintDocumentSource::WaitAndGetPage(size_t page_number, - ID2D1GdiMetafile** gdi_metafile) { - // Properly protect the wait/access to the page data. - base::AutoLock lock(*parent_lock_); - // Make sure we weren't canceled before getting here. - // And the page count should have been received before we get here too. - if (aborted_) - return S_FALSE; - - // We shouldn't be asked for a page until we got the page count. - DCHECK(page_count_ready_.IsSignaled()); - DCHECK(page_number <= pages_ready_state_.size()); - DCHECK(pages_.size() == pages_ready_state_.size()); - while (!aborted_ && pages_[page_number].Get() == NULL) - pages_ready_state_[page_number]->Wait(); - - // Make sure we weren't aborted while we waited unlocked. - if (aborted_) - return S_FALSE; - DCHECK(page_number < pages_.size()); - - mswr::ComPtr<ID2D1Factory> factory; - directx_context_.d2d_device->GetFactory(&factory); - - mswr::ComPtr<ID2D1Factory1> factory1; - HRESULT hr = factory.As(&factory1); - if (FAILED(hr)) { - LOG(ERROR) << "Failed to QI for ID2D1Factory1 " << std::hex << hr; - return hr; - } - - ULARGE_INTEGER result; - LARGE_INTEGER seek_pos; - seek_pos.QuadPart = 0; - hr = pages_[page_number]->Seek(seek_pos, STREAM_SEEK_SET, &result); - if (FAILED(hr)) { - LOG(ERROR) << "Failed to Seek page stream " << std::hex << hr; - return hr; - } - - hr = factory1->CreateGdiMetafile(pages_[page_number].Get(), gdi_metafile); - if (FAILED(hr)) { - LOG(ERROR) << "Failed to CreateGdiMetafile " << std::hex << hr; - return hr; - } - return hr; -} - -} // namespace metro_driver diff --git a/win8/metro_driver/print_document_source.h b/win8/metro_driver/print_document_source.h deleted file mode 100644 index fed333e..0000000 --- a/win8/metro_driver/print_document_source.h +++ /dev/null @@ -1,164 +0,0 @@ -// Copyright (c) 2012 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. - -#ifndef CHROME_BROWSER_UI_METRO_DRIVER_PRINT_DOCUMENT_SOURCE_H_ -#define CHROME_BROWSER_UI_METRO_DRIVER_PRINT_DOCUMENT_SOURCE_H_ - -#include <documentsource.h> -#include <printpreview.h> -#include <windows.graphics.printing.h> - -#include <vector> - -#include "base/basictypes.h" -#include "base/memory/ref_counted.h" -#include "base/memory/scoped_ptr.h" -#include "base/synchronization/condition_variable.h" -#include "base/synchronization/waitable_event.h" -#include "win8/metro_driver/winrt_utils.h" - -// Hack to be removed once we don't need to build with an SDK earlier than -// 8441 where the name of the interface has been changed. -// TODO(mad): remove once we don't run mixed SDK/OS anymore. -#ifndef __IPrintPreviewDxgiPackageTarget_FWD_DEFINED__ -typedef IPrintPreviewDXGIPackageTarget IPrintPreviewDxgiPackageTarget; -#endif - - -namespace base { -class Lock; -}; // namespace base - -namespace metro_driver { - -// This class is given to Metro as a source for print documents. -// The methodless IPrintDocumentSource interface is used to identify it as such. -// Then, the other interfaces are used to generate preview and print documents. -// It also exposes a few methods for the print handler to control the document. -class PrintDocumentSource - : public mswr::RuntimeClass< - mswr::RuntimeClassFlags<mswr::WinRtClassicComMix>, - wingfx::Printing::IPrintDocumentSource, - IPrintDocumentPageSource, - IPrintPreviewPageCollection> { - public: - // A set of interfaces for the DirectX context that our parent owns - // and that don't need to change from document to document. - struct DirectXContext { - DirectXContext() {} - DirectXContext(ID3D11Device1* device_3d, - ID2D1Factory1* factory_2d, - ID2D1Device* device_2d, - ID2D1DeviceContext* context_2d, - IWICImagingFactory2* factory_wic) - : d3d_device(device_3d), - d2d_factory(factory_2d), - d2d_device(device_2d), - d2d_context(context_2d), - wic_factory(factory_wic) { - } - DirectXContext(const DirectXContext& other) - : d3d_device(other.d3d_device), - d2d_factory(other.d2d_factory), - d2d_device(other.d2d_device), - d2d_context(other.d2d_context), - wic_factory(other.wic_factory) { - } - mswr::ComPtr<ID3D11Device1> d3d_device; - mswr::ComPtr<ID2D1Factory1> d2d_factory; - mswr::ComPtr<ID2D1Device> d2d_device; - mswr::ComPtr<ID2D1DeviceContext> d2d_context; - mswr::ComPtr<IWICImagingFactory2> wic_factory; - }; - - // Construction / Initialization. - explicit PrintDocumentSource(); - HRESULT RuntimeClassInitialize(const DirectXContext& directx_context, - base::Lock* parent_lock); - // Aborts any pending asynchronous operation. - void Abort(); - - // classic COM interface IPrintDocumentPageSource methods - STDMETHOD(GetPreviewPageCollection) ( - IPrintDocumentPackageTarget* package_target, - IPrintPreviewPageCollection** page_collection); - STDMETHOD(MakeDocument)(IInspectable* options, - IPrintDocumentPackageTarget* package_target); - - // classic COM interface IPrintPreviewPageCollection methods - STDMETHOD(Paginate)(uint32 page, IInspectable* options); - STDMETHOD(MakePage)(uint32 desired_page, float width, float height); - - // If the screen DPI changes, we must be warned here. - void ResetDpi(float dpi); - - // When the page count is known, this is called and we can setup our data. - void SetPageCount(size_t page_count); - - // Every time a page is ready, this is called and we can read the data if - // we were waiting for it, or store it for later use. - void AddPage(size_t page_number, IStream* metafile_stream); - - private: - // Print the page given in the metafile stream to the given print control. - HRESULT PrintPage(ID2D1PrintControl* print_control, - ID2D1GdiMetafile* metafile_stream, - D2D1_SIZE_F pageSize); - - // Helper function to wait for the page count to be ready. - // Returns 0 when aborted. - size_t WaitAndGetPageCount(); - - // Helper function to wait for a given page to be ready. - // Returns S_FALSE when aborted. - HRESULT WaitAndGetPage(size_t page_number, - ID2D1GdiMetafile** metafile_stream); - - DirectXContext directx_context_; - - // Once page data is available, it's added to this vector. - std::vector<mswr::ComPtr<IStream>> pages_; - - // When page count is set, the size of this vector is set to that number. - // Then, every time page data is added to pages_, the associated condition - // variable in this vector is signaled. This is only filled when we receive - // the page count, so we must wait on page_count_ready_ before accessing - // the content of this vector. - std::vector<scoped_ptr<base::ConditionVariable> > pages_ready_state_; - - // This event is signaled when we receive a page count from Chrome. We should - // not receive any page data before the count, so we can check this event - // while waiting for pages too, in case we ask for page data before we got - // the count, so before we properly initialized pages_ready_state_. - base::WaitableEvent page_count_ready_; - - // The preview target interface set from within GetPreviewPageCollection - // but used from within MakePage. - mswr::ComPtr<IPrintPreviewDxgiPackageTarget> dxgi_preview_target_; - - // Our parent's lock (to make sure it is initialized and destroyed early - // enough), which we use to protect access to our data members. - base::Lock* parent_lock_; - - // The width/height requested in Paginate and used in MakePage. - // TODO(mad): Height is currently not used, and width is only used for - // scaling. We need to add a way to specify width and height when we request - // pages from Chrome. - float height_; - float width_; - - // The DPI is set by Windows and we need to give it to DirectX. - float dpi_; - - // A flag identiying that we have been aborted. Needed to properly handle - // asynchronous callbacks. - bool aborted_; - - // TODO(mad): remove once we don't run mixed SDK/OS anymore. - bool using_old_preview_interface_; -}; - -} // namespace metro_driver - -#endif // CHROME_BROWSER_UI_METRO_DRIVER_PRINT_DOCUMENT_SOURCE_H_ diff --git a/win8/metro_driver/print_handler.cc b/win8/metro_driver/print_handler.cc deleted file mode 100644 index dce321a..0000000 --- a/win8/metro_driver/print_handler.cc +++ /dev/null @@ -1,487 +0,0 @@ -// Copyright (c) 2012 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 "stdafx.h" -#include "win8/metro_driver/print_handler.h" - -#include <windows.graphics.display.h> - -#include "base/bind.h" -#include "base/logging.h" -#include "chrome/app/chrome_command_ids.h" -#include "win8/metro_driver/chrome_app_view.h" -#include "win8/metro_driver/winrt_utils.h" - -namespace { - -typedef winfoundtn::ITypedEventHandler< - wingfx::Printing::PrintManager*, - wingfx::Printing::PrintTaskRequestedEventArgs*> PrintRequestedHandler; - -typedef winfoundtn::ITypedEventHandler< - wingfx::Printing::PrintTask*, - wingfx::Printing::PrintTaskCompletedEventArgs*> PrintTaskCompletedHandler; - -typedef winfoundtn::ITypedEventHandler< - wingfx::Printing::PrintTask*, IInspectable*> PrintTaskInspectableHandler; - -typedef winfoundtn::ITypedEventHandler< - wingfx::Printing::PrintTask*, - wingfx::Printing::PrintTaskProgressingEventArgs*> - PrintTaskProgressingHandler; - -} // namespace - -namespace metro_driver { - -mswr::ComPtr<PrintDocumentSource> PrintHandler::current_document_source_; -bool PrintHandler::printing_enabled_ = false; -base::Lock* PrintHandler::lock_ = NULL; -base::Thread* PrintHandler::thread_ = NULL; - -PrintHandler::PrintHandler() { - DCHECK(lock_ == NULL); - lock_ = new base::Lock(); - - DCHECK(thread_ == NULL); - thread_ = new base::Thread("Metro Print Handler"); - thread_->Start(); -} - -PrintHandler::~PrintHandler() { - ClearPrintTask(); - DCHECK(current_document_source_.Get() == NULL); - - // Get all pending tasks to complete cleanly by Stopping the thread. - // They should complete quickly since current_document_source_ is NULL. - DCHECK(thread_ != NULL); - DCHECK(thread_->IsRunning()); - thread_->Stop(); - delete thread_; - thread_ = NULL; - - DCHECK(lock_ != NULL); - delete lock_; - lock_ = NULL; -} - -HRESULT PrintHandler::Initialize(winui::Core::ICoreWindow* window) { - // Register for Print notifications. - mswr::ComPtr<wingfx::Printing::IPrintManagerStatic> print_mgr_static; - HRESULT hr = winrt_utils::CreateActivationFactory( - RuntimeClass_Windows_Graphics_Printing_PrintManager, - print_mgr_static.GetAddressOf()); - if (FAILED(hr)) { - LOG(ERROR) << "Failed to create PrintManagerStatic " << std::hex << hr; - return hr; - } - - mswr::ComPtr<wingfx::Printing::IPrintManager> print_mgr; - hr = print_mgr_static->GetForCurrentView(&print_mgr); - if (FAILED(hr)) { - LOG(ERROR) << "Failed to get PrintManager for current view " << std::hex - << hr; - return hr; - } - - hr = print_mgr->add_PrintTaskRequested( - mswr::Callback<PrintRequestedHandler>( - this, &PrintHandler::OnPrintRequested).Get(), - &print_requested_token_); - LOG_IF(ERROR, FAILED(hr)) << "Failed to register PrintTaskRequested " - << std::hex << hr; - - mswr::ComPtr<wingfx::Display::IDisplayPropertiesStatics> display_properties; - hr = winrt_utils::CreateActivationFactory( - RuntimeClass_Windows_Graphics_Display_DisplayProperties, - display_properties.GetAddressOf()); - if (FAILED(hr)) { - LOG(ERROR) << "Failed to create DisplayPropertiesStatics " << std::hex - << hr; - return hr; - } - - hr = display_properties->add_LogicalDpiChanged( - mswr::Callback< - wingfx::Display::IDisplayPropertiesEventHandler, - PrintHandler>(this, &PrintHandler::LogicalDpiChanged).Get(), - &dpi_change_token_); - LOG_IF(ERROR, FAILED(hr)) << "Failed to register LogicalDpiChanged " - << std::hex << hr; - - // This flag adds support for surfaces with a different color channel - // ordering than the API default. It is recommended usage, and is required - // for compatibility with Direct2D. - UINT creation_flags = D3D11_CREATE_DEVICE_BGRA_SUPPORT; -#if defined(_DEBUG) - creation_flags |= D3D11_CREATE_DEVICE_DEBUG; -#endif - - // This array defines the set of DirectX hardware feature levels we support. - // The ordering MUST be preserved. All applications are assumed to support - // 9.1 unless otherwise stated by the application, which is not our case. - D3D_FEATURE_LEVEL feature_levels[] = { - D3D_FEATURE_LEVEL_11_1, - D3D_FEATURE_LEVEL_11_0, - D3D_FEATURE_LEVEL_10_1, - D3D_FEATURE_LEVEL_10_0, - D3D_FEATURE_LEVEL_9_3, - D3D_FEATURE_LEVEL_9_2, - D3D_FEATURE_LEVEL_9_1 }; - - mswr::ComPtr<ID3D11Device> device; - mswr::ComPtr<ID3D11DeviceContext> context; - hr = D3D11CreateDevice( - NULL, // Specify null to use the default adapter. - D3D_DRIVER_TYPE_HARDWARE, - 0, // Leave as 0 unless software device. - creation_flags, - feature_levels, - ARRAYSIZE(feature_levels), - D3D11_SDK_VERSION, // Must always use this value in Metro apps. - &device, - NULL, // Returns feature level of device created. - &context); - if (hr == DXGI_ERROR_UNSUPPORTED) { - // The hardware is not supported, try a reference driver instead. - hr = D3D11CreateDevice( - NULL, // Specify null to use the default adapter. - D3D_DRIVER_TYPE_REFERENCE, - 0, // Leave as 0 unless software device. - creation_flags, - feature_levels, - ARRAYSIZE(feature_levels), - D3D11_SDK_VERSION, // Must always use this value in Metro apps. - &device, - NULL, // Returns feature level of device created. - &context); - } - if (FAILED(hr)) { - LOG(ERROR) << "Failed to create D3D11 device/context " << std::hex << hr; - return hr; - } - - hr = device.As(&directx_context_.d3d_device); - if (FAILED(hr)) { - LOG(ERROR) << "Failed to QI D3D11 device " << std::hex << hr; - return hr; - } - - D2D1_FACTORY_OPTIONS options; - ZeroMemory(&options, sizeof(D2D1_FACTORY_OPTIONS)); - -#if defined(_DEBUG) - options.debugLevel = D2D1_DEBUG_LEVEL_INFORMATION; -#endif - - hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_MULTI_THREADED, - __uuidof(ID2D1Factory1), - &options, - &directx_context_.d2d_factory); - if (FAILED(hr)) { - LOG(ERROR) << "Failed to create D2D1 factory " << std::hex << hr; - return hr; - } - - mswr::ComPtr<IDXGIDevice> dxgi_device; - hr = directx_context_.d3d_device.As(&dxgi_device); - if (FAILED(hr)) { - LOG(ERROR) << "Failed to QI for IDXGIDevice " << std::hex << hr; - return hr; - } - - hr = directx_context_.d2d_factory->CreateDevice( - dxgi_device.Get(), &directx_context_.d2d_device); - if (FAILED(hr)) { - LOG(ERROR) << "Failed to Create D2DDevice " << std::hex << hr; - return hr; - } - - hr = directx_context_.d2d_device->CreateDeviceContext( - D2D1_DEVICE_CONTEXT_OPTIONS_NONE, - &directx_context_.d2d_context); - if (FAILED(hr)) { - LOG(ERROR) << "Failed to Create D2DDeviceContext " << std::hex << hr; - return hr; - } - - hr = CoCreateInstance(CLSID_WICImagingFactory, - NULL, - CLSCTX_INPROC_SERVER, - IID_PPV_ARGS(&directx_context_.wic_factory)); - if (FAILED(hr)) { - LOG(ERROR) << "Failed to CoCreate WICImagingFactory " << std::hex << hr; - return hr; - } - return hr; -} - -void PrintHandler::EnablePrinting(bool printing_enabled) { - thread_->message_loop()->PostTask( - FROM_HERE, - base::Bind(&PrintHandler::OnEnablePrinting, printing_enabled)); -} - -void PrintHandler::SetPageCount(size_t page_count) { - thread_->message_loop()->PostTask( - FROM_HERE, - base::Bind(&PrintHandler::OnSetPageCount, page_count)); -} - -void PrintHandler::AddPage(size_t page_number, IStream* metafile_stream) { - thread_->message_loop()->PostTask( - FROM_HERE, - base::Bind(&PrintHandler::OnAddPage, - page_number, - mswr::ComPtr<IStream>(metafile_stream))); -} - -void PrintHandler::ShowPrintUI() { - // Post the print UI request over to the metro thread. - DCHECK(globals.appview_msg_loop != NULL); - bool posted = globals.appview_msg_loop->PostTask( - FROM_HERE, base::Bind(&metro_driver::PrintHandler::OnShowPrintUI)); - DCHECK(posted); -} - -HRESULT PrintHandler::OnPrintRequested( - wingfx::Printing::IPrintManager* print_mgr, - wingfx::Printing::IPrintTaskRequestedEventArgs* event_args) { - DVLOG(1) << __FUNCTION__; - - HRESULT hr = S_OK; - if (printing_enabled_) { - mswr::ComPtr<wingfx::Printing::IPrintTaskRequest> print_request; - hr = event_args->get_Request(print_request.GetAddressOf()); - if (FAILED(hr)) { - LOG(ERROR) << "Failed to get the Print Task request " << std::hex << hr; - return hr; - } - - mswrw::HString title; - title.Attach(MakeHString(L"Printing")); - hr = print_request->CreatePrintTask( - title.Get(), - mswr::Callback< - wingfx::Printing::IPrintTaskSourceRequestedHandler, - PrintHandler>(this, &PrintHandler::OnPrintTaskSourceRequest).Get(), - print_task_.GetAddressOf()); - if (FAILED(hr)) { - LOG(ERROR) << "Failed to create the Print Task " << std::hex << hr; - return hr; - } - - hr = print_task_->add_Completed( - mswr::Callback<PrintTaskCompletedHandler>( - this, &PrintHandler::OnCompleted).Get(), &print_completed_token_); - LOG_IF(ERROR, FAILED(hr)) << "Failed to create the Print Task " << std::hex - << hr; - } - return hr; -} - -HRESULT PrintHandler::OnPrintTaskSourceRequest( - wingfx::Printing::IPrintTaskSourceRequestedArgs* args) { - DVLOG(1) << __FUNCTION__; - mswr::ComPtr<PrintDocumentSource> print_document_source; - HRESULT hr = mswr::MakeAndInitialize<PrintDocumentSource>( - &print_document_source, directx_context_, lock_); - if (FAILED(hr)) { - LOG(ERROR) << "Failed to create document source " << std::hex << hr; - return hr; - } - - print_document_source->ResetDpi(GetLogicalDpi()); - - mswr::ComPtr<wingfx::Printing::IPrintDocumentSource> print_source; - hr = print_document_source.As(&print_source); - if (FAILED(hr)) { - LOG(ERROR) << "Failed to cast document Source " << std::hex << hr; - return hr; - } - - hr = args->SetSource(print_source.Get()); - if (FAILED(hr)) { - LOG(ERROR) << "Failed to set document Source " << std::hex << hr; - return hr; - } - - thread_->message_loop()->PostTask( - FROM_HERE, - base::Bind(&PrintHandler::SetPrintDocumentSource, - print_document_source)); - - return hr; -} - -HRESULT PrintHandler::OnCompleted( - wingfx::Printing::IPrintTask* task, - wingfx::Printing::IPrintTaskCompletedEventArgs* args) { - DVLOG(1) << __FUNCTION__; - DCHECK(globals.appview_msg_loop->BelongsToCurrentThread()); - ClearPrintTask(); - thread_->message_loop()->PostTask( - FROM_HERE, - base::Bind(&PrintHandler::ReleasePrintDocumentSource)); - - return S_OK; -} - -void PrintHandler::ClearPrintTask() { - if (!print_task_.Get()) - return; - - HRESULT hr = print_task_->remove_Completed(print_completed_token_); - LOG_IF(ERROR, FAILED(hr)) << "Failed to remove completed event from Task " - << std::hex << hr; - print_task_.Reset(); -} - -float PrintHandler::GetLogicalDpi() { - mswr::ComPtr<wingfx::Display::IDisplayPropertiesStatics> display_properties; - HRESULT hr = winrt_utils::CreateActivationFactory( - RuntimeClass_Windows_Graphics_Display_DisplayProperties, - display_properties.GetAddressOf()); - if (FAILED(hr)) { - LOG(ERROR) << "Failed to get display properties " << std::hex << hr; - return 0.0; - } - - FLOAT dpi = 0.0; - hr = display_properties->get_LogicalDpi(&dpi); - LOG_IF(ERROR, FAILED(hr)) << "Failed to get Logical DPI " << std::hex << hr; - - return dpi; -} - -HRESULT PrintHandler::LogicalDpiChanged(IInspectable *sender) { - DVLOG(1) << __FUNCTION__; - thread_->message_loop()->PostTask( - FROM_HERE, - base::Bind(&PrintHandler::OnLogicalDpiChanged, GetLogicalDpi())); - return S_OK; -} - -void PrintHandler::OnLogicalDpiChanged(float dpi) { - DCHECK(MessageLoop::current() == thread_->message_loop()); - // No need to protect the access to the static variable, - // since it's set/released in this same thread. - if (current_document_source_.Get() != NULL) - current_document_source_->ResetDpi(dpi); -} - -void PrintHandler::SetPrintDocumentSource( - const mswr::ComPtr<PrintDocumentSource>& print_document_source) { - DCHECK(MessageLoop::current() == thread_->message_loop()); - DCHECK(current_document_source_.Get() == NULL); - { - // Protect against the other thread which might try to access it. - base::AutoLock lock(*lock_); - current_document_source_ = print_document_source; - } - // Start generating the images to print. - // TODO(mad): Use a registered message with more information about the print - // request, and at a more appropriate time too, and maybe one page at a time. - ::PostMessageW(globals.host_windows.front().first, - WM_SYSCOMMAND, - IDC_PRINT_TO_DESTINATION, - 0); -} - -void PrintHandler::ReleasePrintDocumentSource() { - DCHECK(MessageLoop::current() == thread_->message_loop()); - mswr::ComPtr<PrintDocumentSource> print_document_source; - { - // Must wait for other thread to be done with the pointer first. - base::AutoLock lock(*lock_); - current_document_source_.Swap(print_document_source); - } - // This may happen before we get a chance to set the value. - if (print_document_source.Get() != NULL) - print_document_source->Abort(); -} - -void PrintHandler::OnEnablePrinting(bool printing_enabled) { - DCHECK(MessageLoop::current() == thread_->message_loop()); - base::AutoLock lock(*lock_); - printing_enabled_ = printing_enabled; - // Don't abort if we are being disabled since we may be finishing a previous - // print request which was valid and should be finished. We just need to - // prevent any new print requests. And don't assert that we are NOT printing - // if we are becoming enabled since we may be finishing a long print while - // we got disabled and then enabled again... -} - -void PrintHandler::OnSetPageCount(size_t page_count) { - DCHECK(MessageLoop::current() == thread_->message_loop()); - // No need to protect the access to the static variable, - // since it's set/released in this same thread. - if (current_document_source_.Get() != NULL) - current_document_source_->SetPageCount(page_count); -} - -void PrintHandler::OnAddPage(size_t page_number, - mswr::ComPtr<IStream> metafile_stream) { - DCHECK(MessageLoop::current() == thread_->message_loop()); - // No need to protect the access to the static variable, - // since it's set/released in this same thread. - if (current_document_source_.Get() != NULL) - current_document_source_->AddPage(page_number, metafile_stream.Get()); -} - -void PrintHandler::OnShowPrintUI() { - DCHECK(globals.appview_msg_loop->BelongsToCurrentThread()); - mswr::ComPtr<wingfx::Printing::IPrintManagerStatic> print_mgr_static; - HRESULT hr = winrt_utils::CreateActivationFactory( - RuntimeClass_Windows_Graphics_Printing_PrintManager, - print_mgr_static.GetAddressOf()); - if (SUCCEEDED(hr)) { - DCHECK(print_mgr_static.Get() != NULL); - // Note that passing NULL to ShowPrintUIAsync crashes, - // so we need to setup a temp pointer. - mswr::ComPtr<winfoundtn::IAsyncOperation<bool>> unused_async_op; - hr = print_mgr_static->ShowPrintUIAsync(unused_async_op.GetAddressOf()); - LOG_IF(ERROR, FAILED(hr)) << "Failed to ShowPrintUIAsync " - << std::hex << std::showbase << hr; - } else { - LOG(ERROR) << "Failed to create PrintManagerStatic " - << std::hex << std::showbase << hr; - } -} - -} // namespace metro_driver - -void MetroEnablePrinting(BOOL printing_enabled) { - metro_driver::PrintHandler::EnablePrinting(!!printing_enabled); -} - -void MetroSetPrintPageCount(size_t page_count) { - DVLOG(1) << __FUNCTION__ << " Page count: " << page_count; - metro_driver::PrintHandler::SetPageCount(page_count); -} - -void MetroSetPrintPageContent(size_t page_number, - void* data, - size_t data_size) { - DVLOG(1) << __FUNCTION__ << " Page number: " << page_number; - DCHECK(data != NULL); - DCHECK(data_size > 0); - mswr::ComPtr<IStream> metafile_stream; - HRESULT hr = ::CreateStreamOnHGlobal( - NULL, TRUE, metafile_stream.GetAddressOf()); - if (metafile_stream.Get() != NULL) { - ULONG bytes_written = 0; - hr = metafile_stream->Write(data, data_size, &bytes_written); - LOG_IF(ERROR, FAILED(hr)) << "Failed to Write to Stream " << std::hex << hr; - DCHECK(bytes_written == data_size); - - metro_driver::PrintHandler::AddPage(page_number, metafile_stream.Get()); - } else { - NOTREACHED() << "Failed to CreateStreamOnHGlobal " << std::hex << hr; - } -} - -void MetroShowPrintUI() { - metro_driver::PrintHandler::ShowPrintUI(); -} diff --git a/win8/metro_driver/print_handler.h b/win8/metro_driver/print_handler.h deleted file mode 100644 index f0779cf..0000000 --- a/win8/metro_driver/print_handler.h +++ /dev/null @@ -1,116 +0,0 @@ -// Copyright (c) 2012 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. - -#ifndef CHROME_BROWSER_UI_METRO_DRIVER_PRINT_HANDLER_H_ -#define CHROME_BROWSER_UI_METRO_DRIVER_PRINT_HANDLER_H_ - -#include <windows.media.playto.h> -#include <windows.graphics.printing.h> -#include <windows.ui.core.h> - -#include "base/synchronization/lock.h" -#include "base/threading/thread.h" -#include "win8/metro_driver/print_document_source.h" -#include "win8/metro_driver/winrt_utils.h" - -namespace base { - -class Lock; - -} // namespace base - -namespace metro_driver { - -// This class handles the print aspect of the devices charm. -class PrintHandler { - public: - PrintHandler(); - ~PrintHandler(); - - HRESULT Initialize(winui::Core::ICoreWindow* window); - - // Called by the exported C functions. - static void EnablePrinting(bool printing_enabled); - static void SetPageCount(size_t page_count); - static void AddPage(size_t page_number, IStream* metafile_stream); - static void ShowPrintUI(); - - private: - // Callbacks from Metro. - HRESULT OnPrintRequested( - wingfx::Printing::IPrintManager* print_mgr, - wingfx::Printing::IPrintTaskRequestedEventArgs* event_args); - - HRESULT OnPrintTaskSourceRequest( - wingfx::Printing::IPrintTaskSourceRequestedArgs* args); - - HRESULT OnCompleted(wingfx::Printing::IPrintTask* task, - wingfx::Printing::IPrintTaskCompletedEventArgs* args); - // Utility methods. - void ClearPrintTask(); - float GetLogicalDpi(); - - // Callback from Metro and entry point called on lockable thread. - HRESULT LogicalDpiChanged(IInspectable *sender); - static void OnLogicalDpiChanged(float dpi); - - // Called on the lockable thread to set/release the doc. - static void SetPrintDocumentSource( - const mswr::ComPtr<PrintDocumentSource>& print_document_source); - static void ReleasePrintDocumentSource(); - - // Called on the lockable thread for the exported C functions. - static void OnEnablePrinting(bool printing_enabled); - static void OnSetPageCount(size_t page_count); - static void OnAddPage(size_t page_number, - mswr::ComPtr<IStream> metafile_stream); - - // Opens the prit device charm. Must be called from the metro thread. - static void OnShowPrintUI(); - - mswr::ComPtr<wingfx::Printing::IPrintTask> print_task_; - EventRegistrationToken print_requested_token_; - EventRegistrationToken print_completed_token_; - EventRegistrationToken dpi_change_token_; - - mswr::ComPtr<wingfx::Printing::IPrintManager> print_manager_; - PrintDocumentSource::DirectXContext directx_context_; - - // Hack to give access to the Print Document from the C style entry points. - // This will go away once we can pass a pointer to this interface down to - // the Chrome Browser as we send the command to print. - static mswr::ComPtr<PrintDocumentSource> current_document_source_; - - // Another hack to enable/disable printing from an exported C function. - // TODO(mad): Find a better way to do this... - static bool printing_enabled_; - - // This is also a temporary hack until we can pass down the print document - // to Chrome so it can call directly into it. We need to lock the access to - // current_document_source_. - static base::Lock* lock_; - - // This thread is used to send blocking jobs - // out of threads we don't want to block. - static base::Thread* thread_; -}; - -} // namespace metro_driver - -// Exported C functions for Chrome to call into the Metro module. -extern "C" __declspec(dllexport) -void MetroEnablePrinting(BOOL printing_enabled); - -extern "C" __declspec(dllexport) -void MetroSetPrintPageCount(size_t page_count); - -extern "C" __declspec(dllexport) -void MetroSetPrintPageContent(size_t current_page, - void* data, - size_t data_size); - -extern "C" __declspec(dllexport) -void MetroShowPrintUI(); - -#endif // CHROME_BROWSER_UI_METRO_DRIVER_PRINT_HANDLER_H_ diff --git a/win8/metro_driver/run_all_unittests.cc b/win8/metro_driver/run_all_unittests.cc deleted file mode 100644 index 4c6a548..0000000 --- a/win8/metro_driver/run_all_unittests.cc +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright (c) 2012 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 "stdafx.h" - -#include "base/at_exit.h" -#include "testing/gtest/include/gtest/gtest.h" - -#pragma comment(lib, "runtimeobject.lib") - -base::AtExitManager at_exit; - -int main(int argc, char** argv) { - mswrw::RoInitializeWrapper ro_init(RO_INIT_SINGLETHREADED); - - testing::InitGoogleTest(&argc, argv); - - return RUN_ALL_TESTS(); -} diff --git a/win8/metro_driver/secondary_tile.cc b/win8/metro_driver/secondary_tile.cc deleted file mode 100644 index 8a54bd7..0000000 --- a/win8/metro_driver/secondary_tile.cc +++ /dev/null @@ -1,155 +0,0 @@ -// Copyright (c) 2012 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 "stdafx.h" -#include "secondary_tile.h" - -#include <windows.ui.startscreen.h> - -#include "base/base_paths.h" -#include "base/bind.h" -#include "base/file_path.h" -#include "base/logging.h" -#include "base/path_service.h" -#include "base/string_number_conversions.h" -#include "base/utf_string_conversions.h" -#include "crypto/sha2.h" -#include "win8/metro_driver/chrome_app_view.h" -#include "win8/metro_driver/winrt_utils.h" - -namespace { - -string16 GenerateTileId(const string16& url_str) { - uint8 hash[crypto::kSHA256Length]; - crypto::SHA256HashString(UTF16ToUTF8(url_str), hash, sizeof(hash)); - std::string hash_str = base::HexEncode(hash, sizeof(hash)); - return UTF8ToUTF16(hash_str); -} - -string16 GetLogoUrlString() { - FilePath module_path; - PathService::Get(base::DIR_MODULE, &module_path); - string16 scheme(L"ms-appx:///"); - return scheme.append(module_path.BaseName().value()) - .append(L"/SecondaryTile.png"); -} - -BOOL IsPinnedToStartScreen(const string16& url_str) { - mswr::ComPtr<winui::StartScreen::ISecondaryTileStatics> tile_statics; - HRESULT hr = winrt_utils::CreateActivationFactory( - RuntimeClass_Windows_UI_StartScreen_SecondaryTile, - tile_statics.GetAddressOf()); - CheckHR(hr, "Failed to create instance of ISecondaryTileStatics"); - - boolean exists; - hr = tile_statics->Exists(MakeHString(GenerateTileId(url_str)), &exists); - CheckHR(hr, "ISecondaryTileStatics.Exists failed"); - return exists; -} - -void DeleteTileFromStartScreen(const string16& url_str) { - DVLOG(1) << __FUNCTION__; - mswr::ComPtr<winui::StartScreen::ISecondaryTileFactory> tile_factory; - HRESULT hr = winrt_utils::CreateActivationFactory( - RuntimeClass_Windows_UI_StartScreen_SecondaryTile, - tile_factory.GetAddressOf()); - CheckHR(hr, "Failed to create instance of ISecondaryTileFactory"); - - mswrw::HString id; - id.Attach(MakeHString(GenerateTileId(url_str))); - - mswr::ComPtr<winui::StartScreen::ISecondaryTile> tile; - hr = tile_factory->CreateWithId(id.Get(), tile.GetAddressOf()); - CheckHR(hr, "Failed to create tile"); - - mswr::ComPtr<winfoundtn::IAsyncOperation<bool>> completion; - hr = tile->RequestDeleteAsync(completion.GetAddressOf()); - CheckHR(hr, "RequestDeleteAsync failed"); - - typedef winfoundtn::IAsyncOperationCompletedHandler<bool> RequestDoneType; - mswr::ComPtr<RequestDoneType> handler(mswr::Callback<RequestDoneType>( - globals.view, &ChromeAppView::TileRequestCreateDone)); - DCHECK(handler.Get() != NULL); - hr = completion->put_Completed(handler.Get()); - CheckHR(hr, "Failed to put_Completed"); -} - -void CreateTileOnStartScreen(const string16& title_str, - const string16& url_str) { - VLOG(1) << __FUNCTION__; - mswr::ComPtr<winui::StartScreen::ISecondaryTileFactory> tile_factory; - HRESULT hr = winrt_utils::CreateActivationFactory( - RuntimeClass_Windows_UI_StartScreen_SecondaryTile, - tile_factory.GetAddressOf()); - CheckHR(hr, "Failed to create instance of ISecondaryTileFactory"); - - winui::StartScreen::TileOptions options = - winui::StartScreen::TileOptions_ShowNameOnLogo; - mswrw::HString title; - title.Attach(MakeHString(title_str)); - mswrw::HString id; - id.Attach(MakeHString(GenerateTileId(url_str))); - mswrw::HString args; - args.Attach(MakeHString(string16(L"url=").append(url_str))); - - mswr::ComPtr<winfoundtn::IUriRuntimeClassFactory> uri_factory; - hr = winrt_utils::CreateActivationFactory( - RuntimeClass_Windows_Foundation_Uri, - uri_factory.GetAddressOf()); - CheckHR(hr, "Failed to create URIFactory"); - - mswrw::HString logo_url; - logo_url.Attach(MakeHString(GetLogoUrlString())); - mswr::ComPtr<winfoundtn::IUriRuntimeClass> uri; - hr = uri_factory->CreateUri(logo_url.Get(), &uri); - CheckHR(hr, "Failed to create URI"); - - mswr::ComPtr<winui::StartScreen::ISecondaryTile> tile; - hr = tile_factory->CreateTile(id.Get(), - title.Get(), - title.Get(), - args.Get(), - options, - uri.Get(), - tile.GetAddressOf()); - CheckHR(hr, "Failed to create tile"); - - hr = tile->put_ForegroundText(winui::StartScreen::ForegroundText_Light); - CheckHR(hr, "Failed to change foreground text color"); - - mswr::ComPtr<winfoundtn::IAsyncOperation<bool>> completion; - hr = tile->RequestCreateAsync(completion.GetAddressOf()); - CheckHR(hr, "RequestCreateAsync failed"); - - typedef winfoundtn::IAsyncOperationCompletedHandler<bool> RequestDoneType; - mswr::ComPtr<RequestDoneType> handler(mswr::Callback<RequestDoneType>( - globals.view, &ChromeAppView::TileRequestCreateDone)); - DCHECK(handler.Get() != NULL); - hr = completion->put_Completed(handler.Get()); - CheckHR(hr, "Failed to put_Completed"); -} - -void TogglePinnedToStartScreen(const string16& title_str, - const string16& url_str) { - if (IsPinnedToStartScreen(url_str)) { - DeleteTileFromStartScreen(url_str); - return; - } - - CreateTileOnStartScreen(title_str, url_str); -} - -} // namespace - -BOOL MetroIsPinnedToStartScreen(const string16& url) { - VLOG(1) << __FUNCTION__ << " url: " << url; - return IsPinnedToStartScreen(url); -} - -void MetroTogglePinnedToStartScreen(const string16& title, - const string16& url) { - DVLOG(1) << __FUNCTION__ << " title:" << title << " url: " << url; - globals.appview_msg_loop->PostTask( - FROM_HERE, base::Bind(&TogglePinnedToStartScreen, title, url)); -} diff --git a/win8/metro_driver/secondary_tile.h b/win8/metro_driver/secondary_tile.h deleted file mode 100644 index 796e881..0000000 --- a/win8/metro_driver/secondary_tile.h +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) 2012 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. -#ifndef CHROME_BROWSER_UI_METRO_DRIVER_SECONDARY_TILE_H_ -#define CHROME_BROWSER_UI_METRO_DRIVER_SECONDARY_TILE_H_ - -#include "base/string16.h" - -extern "C" __declspec(dllexport) -BOOL MetroIsPinnedToStartScreen(const string16& url); - -extern "C" __declspec(dllexport) -void MetroTogglePinnedToStartScreen(const string16& title, const string16& url); - -#endif // CHROME_BROWSER_UI_METRO_DRIVER_SECONDARY_TILE_H_ - diff --git a/win8/metro_driver/settings_handler.cc b/win8/metro_driver/settings_handler.cc deleted file mode 100644 index 6feae24..0000000 --- a/win8/metro_driver/settings_handler.cc +++ /dev/null @@ -1,175 +0,0 @@ -// Copyright (c) 2012 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 "stdafx.h" -#include "settings_handler.h" - -// This include allows to send WM_SYSCOMMANDs to chrome. -#include "chrome/app/chrome_command_ids.h" -#include "chrome_app_view.h" -#include "winrt_utils.h" - -typedef winfoundtn::ITypedEventHandler< - winui::ApplicationSettings::SettingsPane*, - winui::ApplicationSettings::SettingsPaneCommandsRequestedEventArgs*> - CommandsRequestedHandler; - -namespace { - -// String identifiers for the settings pane commands. -const wchar_t* kSettingsId = L"settings"; -const wchar_t* kHelpId = L"help"; -const wchar_t* kAboutId = L"about"; - -} - -SettingsHandler::SettingsHandler() { - DVLOG(1) << __FUNCTION__; -} - -SettingsHandler::~SettingsHandler() { - DVLOG(1) << __FUNCTION__; -} - -HRESULT SettingsHandler::Initialize() { - mswr::ComPtr<winui::ApplicationSettings::ISettingsPaneStatics> - settings_pane_statics; - HRESULT hr = winrt_utils::CreateActivationFactory( - RuntimeClass_Windows_UI_ApplicationSettings_SettingsPane, - settings_pane_statics.GetAddressOf()); - CheckHR(hr, "Failed to activate ISettingsPaneStatics"); - - mswr::ComPtr<winui::ApplicationSettings::ISettingsPane> settings_pane; - hr = settings_pane_statics->GetForCurrentView(&settings_pane); - CheckHR(hr, "Failed to get ISettingsPane"); - - hr = settings_pane->add_CommandsRequested( - mswr::Callback<CommandsRequestedHandler>( - this, - &SettingsHandler::OnSettingsCommandsRequested).Get(), - &settings_token_); - CheckHR(hr, "Failed to add CommandsRequested"); - - return hr; -} - -HRESULT SettingsHandler::OnSettingsCommandsRequested( - winui::ApplicationSettings::ISettingsPane* settings_pane, - winui::ApplicationSettings::ISettingsPaneCommandsRequestedEventArgs* args) { - mswr::ComPtr<winui::ApplicationSettings::ISettingsCommandFactory> - settings_command_factory; - HRESULT hr = winrt_utils::CreateActivationFactory( - RuntimeClass_Windows_UI_ApplicationSettings_SettingsCommand, - settings_command_factory.GetAddressOf()); - CheckHR(hr, "Failed to activate ISettingsCommandFactory"); - - mswr::ComPtr<winui::ApplicationSettings::ISettingsPaneCommandsRequest> - settings_command_request; - hr = args->get_Request(&settings_command_request); - CheckHR(hr, "Failed to get_Request"); - - mswr::ComPtr<SettingsHandler::ISettingsCommandVector> application_commands; - hr = settings_command_request->get_ApplicationCommands(&application_commands); - CheckHR(hr, "Failed to get_ApplicationCommands"); - - // TODO(mad): Internationalize the hard coded user visible strings. - hr = AppendNewSettingsCommand( - kSettingsId, L"Settings", settings_command_factory.Get(), - application_commands.Get()); - CheckHR(hr, "Failed to append new settings command"); - - hr = AppendNewSettingsCommand( - kHelpId, L"Help", settings_command_factory.Get(), - application_commands.Get()); - CheckHR(hr, "Failed to append new help command"); - - hr = AppendNewSettingsCommand( - kAboutId, L"About", settings_command_factory.Get(), - application_commands.Get()); - CheckHR(hr, "Failed to append new about command"); - - return hr; -} - -HRESULT SettingsHandler::AppendNewSettingsCommand( - const wchar_t* id, - const wchar_t* name, - winui::ApplicationSettings::ISettingsCommandFactory* - settings_command_factory, - SettingsHandler::ISettingsCommandVector* settings_command_vector) { - mswr::ComPtr<winfoundtn::IPropertyValue> settings_id; - HRESULT hr = GetSettingsId(id, &settings_id); - CheckHR(hr, "Can't get settings id"); - - mswrw::HString settings_name; - settings_name.Attach(MakeHString(name)); - mswr::ComPtr<winui::Popups::IUICommand> command; - hr = settings_command_factory->CreateSettingsCommand( - settings_id.Get(), - settings_name.Get(), - mswr::Callback<winui::Popups::IUICommandInvokedHandler>( - &SettingsHandler::OnSettings).Get(), - command.GetAddressOf()); - CheckHR(hr, "Can't create settings command"); - - hr = settings_command_vector->Append(command.Get()); - CheckHR(hr, "Failed to append settings command"); - - return hr; -} - -HRESULT SettingsHandler::OnSettings(winui::Popups::IUICommand* command) { - mswr::ComPtr<winfoundtn::IPropertyValue> settings_id; - HRESULT hr = GetSettingsId(kSettingsId, &settings_id); - CheckHR(hr, "Failed to get settings id"); - - mswr::ComPtr<winfoundtn::IPropertyValue> help_id; - hr = GetSettingsId(kHelpId, &help_id); - CheckHR(hr, "Failed to get settings id"); - - mswr::ComPtr<winfoundtn::IPropertyValue> about_id; - hr = GetSettingsId(kAboutId, &about_id); - CheckHR(hr, "Failed to get settings id"); - - mswr::ComPtr<winfoundtn::IPropertyValue> command_id; - hr = command->get_Id(&command_id); - CheckHR(hr, "Failed to get command id"); - - INT32 result = -1; - hr = winrt_utils::CompareProperties( - command_id.Get(), settings_id.Get(), &result); - CheckHR(hr, "Failed to compare ids"); - - HWND chrome_window = globals.host_windows.front().first; - - if (result == 0) { - ::PostMessageW(chrome_window, WM_SYSCOMMAND, IDC_OPTIONS, 0); - return S_OK; - } - - hr = winrt_utils::CompareProperties(command_id.Get(), help_id.Get(), &result); - CheckHR(hr, "Failed to compare ids"); - if (result == 0) { - ::PostMessageW(chrome_window, WM_SYSCOMMAND, IDC_HELP_PAGE_VIA_MENU, 0); - return S_OK; - } - - hr = winrt_utils::CompareProperties( - command_id.Get(), about_id.Get(), &result); - CheckHR(hr, "Failed to compare ids"); - if (result == 0) { - ::PostMessageW(chrome_window, WM_SYSCOMMAND, IDC_ABOUT, 0); - return S_OK; - } - - return S_OK; -} - -HRESULT SettingsHandler::GetSettingsId( - const wchar_t* value, winfoundtn::IPropertyValue** settings_id) { - mswrw::HString property_value_string; - property_value_string.Attach(MakeHString(value)); - return winrt_utils::CreateStringProperty(property_value_string.Get(), - settings_id); -} diff --git a/win8/metro_driver/settings_handler.h b/win8/metro_driver/settings_handler.h deleted file mode 100644 index 5b234ad..0000000 --- a/win8/metro_driver/settings_handler.h +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright (c) 2012 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. - -#ifndef CHROME_BROWSER_UI_METRO_DRIVER_SETTINGS_HANDLER_H_ -#define CHROME_BROWSER_UI_METRO_DRIVER_SETTINGS_HANDLER_H_ - -#include <windows.ui.applicationsettings.h> -#include <windows.ui.popups.h> - -#include "winrt_utils.h" - -// This class handles the settings charm. -class SettingsHandler { - public: - SettingsHandler(); - ~SettingsHandler(); - - HRESULT Initialize(); - - private: - typedef winfoundtn::Collections::IVector< - winui::ApplicationSettings::SettingsCommand*> ISettingsCommandVector; - - HRESULT OnSettingsCommandsRequested( - winui::ApplicationSettings::ISettingsPane* settings_pane, - winui::ApplicationSettings:: - ISettingsPaneCommandsRequestedEventArgs* args); - - HRESULT AppendNewSettingsCommand( - const wchar_t* id, - const wchar_t* name, - winui::ApplicationSettings::ISettingsCommandFactory* - settings_command_factory, - ISettingsCommandVector* settings_command_vector); - - static HRESULT OnSettings(winui::Popups::IUICommand* command); - static HRESULT GetSettingsId(const wchar_t* value, - winfoundtn::IPropertyValue** settings_id); - - EventRegistrationToken settings_token_; -}; - -#endif // CHROME_BROWSER_UI_METRO_DRIVER_SETTINGS_HANDLER_H_ diff --git a/win8/metro_driver/stdafx.h b/win8/metro_driver/stdafx.h deleted file mode 100644 index d8c1a01..0000000 --- a/win8/metro_driver/stdafx.h +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (c) 2012 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. - -#ifndef CHROME_BROWSER_UI_METRO_DRIVER_STDAFX_H_ -#define CHROME_BROWSER_UI_METRO_DRIVER_STDAFX_H_ - -#include <wrl\implements.h> -#include <wrl\module.h> -#include <wrl\event.h> -#include <wrl\wrappers\corewrappers.h> - -#include <activation.h> -#include <d2d1_1.h> -#include <d3d11_1.h> -#include <roapi.h> -#include <stdio.h> -#include <wincodec.h> -#include <windows.h> - -#include <windows.applicationmodel.core.h> -#include <windows.applicationModel.datatransfer.h> -#include <windows.graphics.printing.h> -#include <windows.ui.notifications.h> - -namespace mswr = Microsoft::WRL; -namespace mswrw = Microsoft::WRL::Wrappers; -namespace winapp = ABI::Windows::ApplicationModel; -namespace windata = ABI::Windows::Data; -namespace winfoundtn = ABI::Windows::Foundation; -namespace wingfx = ABI::Windows::Graphics; -namespace winui = ABI::Windows::UI; -namespace winxml = windata::Xml; - -#endif // CHROME_BROWSER_UI_METRO_DRIVER_STDAFX_H_ diff --git a/win8/metro_driver/toast_notification_handler.cc b/win8/metro_driver/toast_notification_handler.cc deleted file mode 100644 index 36bddd5..0000000 --- a/win8/metro_driver/toast_notification_handler.cc +++ /dev/null @@ -1,234 +0,0 @@ -// Copyright (c) 2012 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 <string> - -#include "win8/metro_driver/stdafx.h" -#include "win8/metro_driver/toast_notification_handler.h" - -#include "base/file_path.h" -#include "base/logging.h" -#include "base/path_service.h" -#include "base/utf_string_conversions.h" -// TODO(ananta) -// Refactor the chrome_util and shell_util code from chrome into a common lib -#include "win8/delegate_execute/chrome_util.h" -#include "win8/metro_driver/winrt_utils.h" - -typedef winfoundtn::ITypedEventHandler< - winui::Notifications::ToastNotification*, IInspectable*> - ToastActivationHandler; - -typedef winfoundtn::ITypedEventHandler< - winui::Notifications::ToastNotification*, - winui::Notifications::ToastDismissedEventArgs*> ToastDismissedHandler; - -namespace { - -// Helper function to return the text node root identified by the index passed -// in. -HRESULT GetTextNodeRoot( - unsigned int index, - winxml::Dom::IXmlDocument* xml_doc, - winxml::Dom::IXmlNode** node) { - DCHECK(xml_doc); - DCHECK(node); - - mswr::ComPtr<winxml::Dom::IXmlElement> document_element; - HRESULT hr = xml_doc->get_DocumentElement(&document_element); - CheckHR(hr); - - mswr::ComPtr<winxml::Dom::IXmlNodeList> elements; - mswrw::HString tag_name; - tag_name.Attach(MakeHString(L"text")); - hr = document_element->GetElementsByTagName(tag_name.Get(), - &elements); - CheckHR(hr); - - unsigned int count = 0; - elements->get_Length(&count); - - if (index > count) { - DVLOG(1) << "Invalid text node index passed in : " << index; - return E_FAIL; - } - hr = elements->Item(index, node); - CheckHR(hr); - return hr; -} - -// Helper function to append a text element to the text section in the -// XML document passed in. -// The index parameter identifies which text node we append to. -HRESULT CreateTextNode(winxml::Dom::IXmlDocument* xml_doc, - int index, - const string16& text_string) { - DCHECK(xml_doc); - - mswr::ComPtr<winxml::Dom::IXmlElement> document_element; - HRESULT hr = xml_doc->get_DocumentElement(&document_element); - CheckHR(hr); - - mswr::ComPtr<winxml::Dom::IXmlText> xml_text_node; - mswrw::HString data_hstring; - data_hstring.Attach(MakeHString(text_string.c_str())); - hr = xml_doc->CreateTextNode(data_hstring.Get(), &xml_text_node); - CheckHR(hr); - - mswr::ComPtr<winxml::Dom::IXmlNode> created_node; - hr = xml_text_node.CopyTo( - winxml::Dom::IID_IXmlNode, - reinterpret_cast<void**>(created_node.GetAddressOf())); - CheckHR(hr); - - mswr::ComPtr<winxml::Dom::IXmlNode> text_node_root; - hr = GetTextNodeRoot(index, xml_doc, &text_node_root); - CheckHR(hr); - - mswr::ComPtr<winxml::Dom::IXmlNode> appended_node; - hr = text_node_root->AppendChild(created_node.Get(), &appended_node); - CheckHR(hr); - return hr; -} - -} // namespace - -ToastNotificationHandler::DesktopNotification::DesktopNotification( - const char* notification_origin, - const char* notification_icon, - const wchar_t* notification_title, - const wchar_t* notification_body, - const wchar_t* notification_display_source, - const char* notification_id) - : origin_url(notification_origin), - icon_url(notification_icon), - title(notification_title), - body(notification_body), - display_source(notification_display_source), - id(notification_id) { -} - - -ToastNotificationHandler::ToastNotificationHandler() { - DVLOG(1) << __FUNCTION__; -} - -ToastNotificationHandler::~ToastNotificationHandler() { - DVLOG(1) << __FUNCTION__; - - if (notifier_ && notification_) - CancelNotification(); -} - -void ToastNotificationHandler::DisplayNotification( - const DesktopNotification& notification) { - DVLOG(1) << __FUNCTION__; - - DCHECK(notifier_.Get() == NULL); - DCHECK(notification_.Get() == NULL); - - mswr::ComPtr<winui::Notifications::IToastNotificationManagerStatics> - toast_manager; - - HRESULT hr = winrt_utils::CreateActivationFactory( - RuntimeClass_Windows_UI_Notifications_ToastNotificationManager, - toast_manager.GetAddressOf()); - CheckHR(hr); - - mswr::ComPtr<winxml::Dom::IXmlDocument> toast_xml; - hr = toast_manager->GetTemplateContent( - winui::Notifications::ToastTemplateType_ToastText02, - &toast_xml); - CheckHR(hr); - - if (!toast_xml) - return; - - mswr::ComPtr<winxml::Dom::IXmlElement> document_element; - hr = toast_xml->get_DocumentElement(&document_element); - CheckHR(hr); - - if (!document_element) - return; - - hr = CreateTextNode(toast_xml.Get(), 0, notification.title); - CheckHR(hr); - - hr = CreateTextNode(toast_xml.Get(), 1, notification.body); - CheckHR(hr); - - mswrw::HString duration_attribute_name; - duration_attribute_name.Attach(MakeHString(L"duration")); - mswrw::HString duration_attribute_value; - duration_attribute_value.Attach(MakeHString(L"long")); - - hr = document_element->SetAttribute(duration_attribute_name.Get(), - duration_attribute_value.Get()); - CheckHR(hr); - - // TODO(ananta) - // We should set the image and launch params attribute in the notification - // XNL as described here: http://msdn.microsoft.com/en-us/library/hh465448 - // To set the image we may have to extract the image and specify it in the - // following url form. ms-appx:///images/foo.png - // The launch params as described don't get passed back to us via the - // winapp::Activation::ILaunchActivatedEventArgs argument. Needs to be - // investigated. - mswr::ComPtr<winui::Notifications::IToastNotificationFactory> - toast_notification_factory; - hr = winrt_utils::CreateActivationFactory( - RuntimeClass_Windows_UI_Notifications_ToastNotification, - toast_notification_factory.GetAddressOf()); - CheckHR(hr); - - hr = toast_notification_factory->CreateToastNotification( - toast_xml.Get(), ¬ification_); - CheckHR(hr); - - FilePath chrome_path; - if (!PathService::Get(base::FILE_EXE, &chrome_path)) { - NOTREACHED() << "Failed to get chrome exe path"; - return; - } - string16 appid = delegate_execute::GetAppId(chrome_path); - DVLOG(1) << "Chrome Appid is " << appid.c_str(); - - // TODO(ananta) - // We should probably use BrowserDistribution here to get the product name. - mswrw::HString app_user_model_id; - app_user_model_id.Attach(MakeHString(appid)); - - hr = toast_manager->CreateToastNotifierWithId(app_user_model_id.Get(), - ¬ifier_); - CheckHR(hr); - - hr = notification_->add_Activated( - mswr::Callback<ToastActivationHandler>( - this, &ToastNotificationHandler::OnActivate).Get(), - &activated_token_); - CheckHR(hr); - - hr = notifier_->Show(notification_.Get()); - CheckHR(hr); -} - -void ToastNotificationHandler::CancelNotification() { - DVLOG(1) << __FUNCTION__; - - DCHECK(notifier_); - DCHECK(notification_); - - notifier_->Hide(notification_.Get()); -} - -HRESULT ToastNotificationHandler::OnActivate( - winui::Notifications::IToastNotification* notification, - IInspectable* inspectable) { - // TODO(ananta) - // We should pass back information from the notification like the source url - // etc to ChromeAppView which would enable it to ensure that the - // correct tab in chrome is activated. - DVLOG(1) << __FUNCTION__; - return S_OK; -} diff --git a/win8/metro_driver/toast_notification_handler.h b/win8/metro_driver/toast_notification_handler.h deleted file mode 100644 index f560e34..0000000 --- a/win8/metro_driver/toast_notification_handler.h +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright (c) 2012 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. - -#ifndef CHROME_BROWSER_UI_METRO_DRIVER_TOAST_NOTIFICATION_HANDLER_H_ -#define CHROME_BROWSER_UI_METRO_DRIVER_TOAST_NOTIFICATION_HANDLER_H_ - -#include <windows.ui.notifications.h> - -#include "base/string16.h" - -// Provides functionality to display a metro style toast notification. -class ToastNotificationHandler { - public: - // Holds information about a desktop notification to be displayed. - struct DesktopNotification { - std::string origin_url; - std::string icon_url; - string16 title; - string16 body; - string16 display_source; - std::string id; - - DesktopNotification(const char* notification_origin, - const char* notification_icon, - const wchar_t* notification_title, - const wchar_t* notification_body, - const wchar_t* notification_display_source, - const char* notification_id); - }; - - ToastNotificationHandler(); - ~ToastNotificationHandler(); - - void DisplayNotification(const DesktopNotification& notification); - void CancelNotification(); - - HRESULT OnActivate(winui::Notifications::IToastNotification* notification, - IInspectable* inspectable); - - private: - mswr::ComPtr<winui::Notifications::IToastNotifier> notifier_; - mswr::ComPtr<winui::Notifications::IToastNotification> notification_; - - EventRegistrationToken activated_token_; -}; - -#endif // CHROME_BROWSER_UI_METRO_DRIVER_TOAST_NOTIFICATION_HANDLER_H_ diff --git a/win8/metro_driver/winrt_utils.cc b/win8/metro_driver/winrt_utils.cc deleted file mode 100644 index cfddc5e..0000000 --- a/win8/metro_driver/winrt_utils.cc +++ /dev/null @@ -1,225 +0,0 @@ -// Copyright (c) 2012 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 "stdafx.h" -#include "winrt_utils.h" - -#include <shlobj.h> - -#include "base/file_path.h" -#include "base/logging.h" -#include "base/win/scoped_com_initializer.h" -#include "base/win/scoped_comptr.h" - -void CheckHR(HRESULT hr, const char* message) { - if (FAILED(hr)) { - if (message) - PLOG(DFATAL) << message << ", hr = " << std::hex << hr; - else - PLOG(DFATAL) << "COM ERROR" << ", hr = " << std::hex << hr; - } -} - -HSTRING MakeHString(const string16& str) { - HSTRING hstr; - if (FAILED(::WindowsCreateString(str.c_str(), str.size(), &hstr))) { - PLOG(DFATAL) << "Hstring creation failed"; - } - return hstr; -} - -string16 MakeStdWString(HSTRING hstring) { - const wchar_t* str; - UINT32 size = 0; - str = ::WindowsGetStringRawBuffer(hstring, &size); - if (!size) - return string16(); - return string16(str, size); -} - -namespace { - -#define IMPLEMENT_CREATE_PROPERTY(Name, Type) \ -HRESULT Create ## Name ## Property(Type value, \ - winfoundtn::IPropertyValue** prop) { \ - mswr::ComPtr<winfoundtn::IPropertyValueStatics> property_value_statics; \ - HRESULT hr = winrt_utils::CreateActivationFactory( \ - RuntimeClass_Windows_Foundation_PropertyValue, \ - property_value_statics.GetAddressOf()); \ - CheckHR(hr, "Can't create IPropertyValueStatics"); \ - hr = property_value_statics->Create ## Name ## ( \ - value, \ - reinterpret_cast<IInspectable**>(prop)); \ - CheckHR(hr, "Failed to create Property"); \ - return hr; \ -} - -#define COMPARE_ATOMIC_PROPERTY_VALUES(Name, Type) \ - Type lhs_value; \ - hr = lhs->Get ## Name ##(&lhs_value); \ - CheckHR(hr, "Can't get value for lhs"); \ - Type rhs_value; \ - hr = rhs->Get ## Name ##(&rhs_value); \ - CheckHR(hr, "Can't get value for rhs"); \ - if (lhs_value < rhs_value) \ - *result = -1; \ - else if (lhs_value > rhs_value) \ - *result = 1; \ - else \ - *result = 0; \ - hr = S_OK - -} // namespace - -namespace winrt_utils { - -IMPLEMENT_CREATE_PROPERTY(String, HSTRING); -IMPLEMENT_CREATE_PROPERTY(Int16, INT16); -IMPLEMENT_CREATE_PROPERTY(Int32, INT32); -IMPLEMENT_CREATE_PROPERTY(Int64, INT64); -IMPLEMENT_CREATE_PROPERTY(UInt8, UINT8); -IMPLEMENT_CREATE_PROPERTY(UInt16, UINT16); -IMPLEMENT_CREATE_PROPERTY(UInt32, UINT32); -IMPLEMENT_CREATE_PROPERTY(UInt64, UINT64); - -HRESULT CompareProperties(winfoundtn::IPropertyValue* lhs, - winfoundtn::IPropertyValue* rhs, - INT32* result) { - if (result == nullptr) { - PLOG(DFATAL) << "Invalid argument to CompareProperties."; - return E_INVALIDARG; - } - - if (lhs == rhs) { - *result = 0; - return S_OK; - } - - winfoundtn::PropertyType lhs_property_type; - HRESULT hr = lhs->get_Type(&lhs_property_type); - if (FAILED(hr)) { - PLOG(DFATAL) << "Can't get property type for lhs, hr=" << std::hex << hr; - } - - winfoundtn::PropertyType rhs_property_type; - hr = rhs->get_Type(&rhs_property_type); - CheckHR(hr, "Can't get property type for rhs"); - - if (lhs_property_type != rhs_property_type) - return E_INVALIDARG; - - switch (lhs_property_type) { - case winfoundtn::PropertyType::PropertyType_String: { - mswrw::HString lhs_string; - hr = lhs->GetString(lhs_string.GetAddressOf()); - CheckHR(hr, "Can't get string for lhs"); - - mswrw::HString rhs_string; - hr = rhs->GetString(rhs_string.GetAddressOf()); - CheckHR(hr, "Can't get string for rhs"); - - hr = WindowsCompareStringOrdinal( - lhs_string.Get(), rhs_string.Get(), result); - break; - } - case winfoundtn::PropertyType::PropertyType_Char16: { - COMPARE_ATOMIC_PROPERTY_VALUES(Char16, wchar_t); - break; - } - case winfoundtn::PropertyType::PropertyType_Double: { - COMPARE_ATOMIC_PROPERTY_VALUES(Double, double); - break; - } - case winfoundtn::PropertyType::PropertyType_Int16: { - COMPARE_ATOMIC_PROPERTY_VALUES(Int16, INT16); - break; - } - case winfoundtn::PropertyType::PropertyType_Int32: { - COMPARE_ATOMIC_PROPERTY_VALUES(Int32, INT32); - break; - } - case winfoundtn::PropertyType::PropertyType_Int64: { - COMPARE_ATOMIC_PROPERTY_VALUES(Int64, INT64); - break; - } - case winfoundtn::PropertyType::PropertyType_UInt8: { - COMPARE_ATOMIC_PROPERTY_VALUES(UInt8, UINT8); - break; - } - case winfoundtn::PropertyType::PropertyType_UInt16: { - COMPARE_ATOMIC_PROPERTY_VALUES(UInt16, UINT16); - break; - } - case winfoundtn::PropertyType::PropertyType_UInt32: { - COMPARE_ATOMIC_PROPERTY_VALUES(UInt32, UINT32); - break; - } - case winfoundtn::PropertyType::PropertyType_UInt64: { - COMPARE_ATOMIC_PROPERTY_VALUES(UInt64, UINT64); - break; - } - default: { - hr = E_NOTIMPL; - } - } - return hr; -} - -bool GetArgumentsFromShortcut(const FilePath& shortcut, - string16* arguments) { - HRESULT result; - base::win::ScopedComPtr<IShellLink> i_shell_link; - bool is_resolved = false; - - - base::win::ScopedCOMInitializer sta_com_initializer; - - // Get pointer to the IShellLink interface - result = i_shell_link.CreateInstance(CLSID_ShellLink, NULL, - CLSCTX_INPROC_SERVER); - if (SUCCEEDED(result)) { - base::win::ScopedComPtr<IPersistFile> persist; - // Query IShellLink for the IPersistFile interface - result = persist.QueryFrom(i_shell_link); - if (SUCCEEDED(result)) { - WCHAR temp_arguments[MAX_PATH]; - // Load the shell link - result = persist->Load(shortcut.value().c_str(), STGM_READ); - if (SUCCEEDED(result)) { - result = i_shell_link->GetArguments(temp_arguments, MAX_PATH); - *arguments = temp_arguments; - is_resolved = true; - } - } - } - - return is_resolved; -} - -string16 ReadArgumentsFromPinnedTaskbarShortcut() { - wchar_t path_buffer[MAX_PATH] = {}; - - if (SUCCEEDED(SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, - SHGFP_TYPE_CURRENT, path_buffer))) { - FilePath shortcut(path_buffer); - shortcut = shortcut.Append( - L"Microsoft\\Internet Explorer\\Quick Launch\\User Pinned\\TaskBar"); - - // TODO(robertshield): Get this stuff from BrowserDistribution. -#if defined(GOOGLE_CHROME_BUILD) - shortcut = shortcut.Append(L"Google Chrome.lnk"); -#else - shortcut = shortcut.Append(L"Chromium.lnk"); -#endif - - string16 arguments; - if (GetArgumentsFromShortcut(shortcut, &arguments)) { - return arguments; - } - } - - return L""; -} - -} // namespace winrt_utils diff --git a/win8/metro_driver/winrt_utils.h b/win8/metro_driver/winrt_utils.h deleted file mode 100644 index 28f1ead..0000000 --- a/win8/metro_driver/winrt_utils.h +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright (c) 2012 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. - -#ifndef CHROME_BROWSER_UI_METRO_DRIVER_WINRT_UTILS_H_ -#define CHROME_BROWSER_UI_METRO_DRIVER_WINRT_UTILS_H_ - -#include <string> - -#include <roapi.h> -#include <windows.applicationmodel.core.h> - -#include "base/string16.h" - -void CheckHR(HRESULT hr, const char* str = nullptr); - -HSTRING MakeHString(const string16& str); - -string16 MakeStdWString(HSTRING hstring); - -namespace winrt_utils { - -template<unsigned int size, typename T> -HRESULT CreateActivationFactory(wchar_t const (&class_name)[size], T** object) { - mswrw::HStringReference ref_class_name(class_name); - return winfoundtn::GetActivationFactory(ref_class_name.Get(), object); -} - -#define DECLARE_CREATE_PROPERTY(Name, Type) \ -HRESULT Create ## Name ## Property( \ - Type value, \ - winfoundtn::IPropertyValue** prop); - -DECLARE_CREATE_PROPERTY(String, HSTRING); -DECLARE_CREATE_PROPERTY(Int16, INT16); -DECLARE_CREATE_PROPERTY(Int32, INT32); -DECLARE_CREATE_PROPERTY(Int64, INT64); -DECLARE_CREATE_PROPERTY(UInt8, UINT8); -DECLARE_CREATE_PROPERTY(UInt16, UINT16); -DECLARE_CREATE_PROPERTY(UInt32, UINT32); -DECLARE_CREATE_PROPERTY(UInt64, UINT64); - -// Compares |lhs| with |rhs| and return the |result| as -// WindowsCompareStringOrdinal would do, i.e., -// -1 if |lhs| is less than |rhs|, 0 if they are equal, and -// +1 if |lhs| is greater than |rhs|. -HRESULT CompareProperties( - winfoundtn::IPropertyValue* lhs, winfoundtn::IPropertyValue* rhs, - INT32* result); - -// Looks for a pinned taskbar shortcut in the current user's profile. If it -// finds one, will return any arguments that have been appended to the -// shortcut's command line. This is intended for scenarios where those shortcut -// parameters are ordinarily ignored (i.e. metro apps on win8). Returns an -// empty string on failure. -string16 ReadArgumentsFromPinnedTaskbarShortcut(); - -} // namespace winrt_utils - -#endif // CHROME_BROWSER_UI_METRO_DRIVER_WINRT_UTILS_H_ diff --git a/win8/metro_driver/winrt_utils_unittest.cc b/win8/metro_driver/winrt_utils_unittest.cc deleted file mode 100644 index 9ae869b..0000000 --- a/win8/metro_driver/winrt_utils_unittest.cc +++ /dev/null @@ -1,115 +0,0 @@ -// Copyright (c) 2012 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 "stdafx.h" - -#include "winrt_utils.h" - -#include "base/logging.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace { - -template <typename Type> -static HRESULT CreateProperty(Type value, winfoundtn::IPropertyValue** prop) { - return E_NOTIMPL; -} - -template <> -static HRESULT CreateProperty<const wchar_t*>( - const wchar_t* value, winfoundtn::IPropertyValue** prop) { - mswrw::HString string_value; - string_value.Attach(MakeHString(value)); - return winrt_utils::CreateStringProperty(string_value.Get(), prop); -} - -template <> -static HRESULT CreateProperty<INT16>(INT16 value, - winfoundtn::IPropertyValue** prop) { - return winrt_utils::CreateInt16Property(value, prop); -} - -template <> -static HRESULT CreateProperty<INT32>(INT32 value, - winfoundtn::IPropertyValue** prop) { - return winrt_utils::CreateInt32Property(value, prop); -} - -template <> -static HRESULT CreateProperty<INT64>(INT64 value, - winfoundtn::IPropertyValue** prop) { - return winrt_utils::CreateInt64Property(value, prop); -} - -template <> -static HRESULT CreateProperty<UINT8>(UINT8 value, - winfoundtn::IPropertyValue** prop) { - return winrt_utils::CreateUInt8Property(value, prop); -} - -template <> -static HRESULT CreateProperty<UINT16>(UINT16 value, - winfoundtn::IPropertyValue** prop) { - return winrt_utils::CreateUInt16Property(value, prop); -} - -template <> -static HRESULT CreateProperty<UINT32>(UINT32 value, - winfoundtn::IPropertyValue** prop) { - return winrt_utils::CreateUInt32Property(value, prop); -} - -template <> -static HRESULT CreateProperty<UINT64>(UINT64 value, - winfoundtn::IPropertyValue** prop) { - return winrt_utils::CreateUInt64Property(value, prop); -} - -template<typename Type> -void TestCompareProperties(Type value1, Type value2) { - mswr::ComPtr<winfoundtn::IPropertyValue> property_1; - HRESULT hr = CreateProperty<Type>(value1, property_1.GetAddressOf()); - ASSERT_TRUE(SUCCEEDED(hr)) << "Can't create Property value 1"; - - mswr::ComPtr<winfoundtn::IPropertyValue> other_property_1; - hr = CreateProperty<Type>(value1, other_property_1.GetAddressOf()); - ASSERT_TRUE(SUCCEEDED(hr)) << "Can't create another Property value 1"; - - mswr::ComPtr<winfoundtn::IPropertyValue> property_2; - hr = CreateProperty<Type>(value2, property_2.GetAddressOf()); - ASSERT_TRUE(SUCCEEDED(hr)) << "Can't create Property value 2"; - - INT32 result = 42; - hr = winrt_utils::CompareProperties( - property_1.Get(), property_1.Get(), &result); - ASSERT_TRUE(SUCCEEDED(hr)) << "Can't compare property_1 to itself"; - EXPECT_EQ(0, result) << "Bad result value while comparing same property"; - - hr = winrt_utils::CompareProperties( - property_1.Get(), other_property_1.Get(), &result); - ASSERT_TRUE(SUCCEEDED(hr)) << "Can't compare property_1 to other_property_1"; - EXPECT_EQ(0, result) << "Bad result while comparing equal values"; - - hr = winrt_utils::CompareProperties( - property_1.Get(), property_2.Get(), &result); - ASSERT_TRUE(SUCCEEDED(hr)) << "Can't compare property_1 to property_2"; - EXPECT_EQ(-1, result) << "Bad result while comparing values for less than"; - - hr = winrt_utils::CompareProperties( - property_2.Get(), property_1.Get(), &result); - ASSERT_TRUE(SUCCEEDED(hr)) << "Can't compare property_1 to property_2"; - EXPECT_EQ(1, result) << "Bad result value while comparing for greater than"; -} - -TEST(PropertyValueCompareTest, CompareProperties) { - TestCompareProperties<INT16>(42, 43); - TestCompareProperties<INT32>(42, 43); - TestCompareProperties<INT64>(42, 43); - TestCompareProperties<UINT8>(42, 43); - TestCompareProperties<UINT16>(42, 43); - TestCompareProperties<UINT32>(42, 43); - TestCompareProperties<UINT64>(42, 43); - TestCompareProperties<const wchar_t*>(L"abc", L"bcd"); -} - -} // namespace diff --git a/win8/win8.gyp b/win8/win8.gyp deleted file mode 100644 index bf64b1f..0000000 --- a/win8/win8.gyp +++ /dev/null @@ -1,33 +0,0 @@ -# Copyright (c) 2012 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. -{ - 'variables': { - 'chromium_code': 1, - }, - 'includes': [ - '../build/win_precompile.gypi', - ], - 'targets': [ - { - 'target_name': 'check_sdk_patch', - 'type': 'none', - 'variables': { - 'check_sdk_script': '<(DEPTH)/chrome/tools/build/win/check_sdk_patch.py', - }, - 'actions': [ - { - 'action_name': 'check_sdk_patch_action', - 'inputs': [ - '<@(windows_sdk_path)/Include/winrt/asyncinfo.h', - ], - 'outputs': [ - # This keeps the ninja build happy. - 'dummy', - ], - 'action': ['python', '<(check_sdk_script)', '<@(windows_sdk_path)'], - }, - ], - }, - ], -}
\ No newline at end of file |