diff options
23 files changed, 91 insertions, 32 deletions
diff --git a/base/win/metro.cc b/base/win/metro.cc index 81e3bda..46476c8 100644 --- a/base/win/metro.cc +++ b/base/win/metro.cc @@ -12,7 +12,62 @@ namespace win { const char kActivateApplication[] = "ActivateApplication"; HMODULE GetMetroModule() { - return GetModuleHandleA("metro_driver.dll"); + const HMODULE kUninitialized = reinterpret_cast<HMODULE>(1); + static HMODULE metro_module = kUninitialized; + + if (metro_module == kUninitialized) { + // Initialize the cache, note that the initialization is idempotent + // under the assumption that metro_driver is never unloaded, so the + // race to this assignment is safe. + metro_module = GetModuleHandleA("metro_driver.dll"); + if (metro_module != NULL) { + // This must be a metro process if the metro_driver is loaded. + DCHECK(IsMetroProcess()); + } + } + + DCHECK(metro_module != kUninitialized); + return metro_module; +} + +bool IsMetroProcess() { + enum ImmersiveState { + kImmersiveUnknown, + kImmersiveTrue, + kImmersiveFalse + }; + typedef BOOL (WINAPI* IsImmersiveProcessFunc)(HANDLE process); + + // The immersive state of a process can never change. + // Look it up once and cache it here. + static ImmersiveState state = kImmersiveUnknown; + + if (state == kImmersiveUnknown) { + // The lookup hasn't been done yet. Note that the code below here is + // idempotent, so it doesn't matter if it races to assignment on multiple + // threads. + HMODULE user32 = ::GetModuleHandleA("user32.dll"); + DCHECK(user32 != NULL); + + IsImmersiveProcessFunc is_immersive_process = + reinterpret_cast<IsImmersiveProcessFunc>( + ::GetProcAddress(user32, "IsImmersiveProcess")); + + if (is_immersive_process != NULL) { + if (is_immersive_process(::GetCurrentProcess())) { + state = kImmersiveTrue; + } else { + state = kImmersiveFalse; + } + } else { + // No "IsImmersiveProcess" export on user32.dll, so this is pre-Windows8 + // and therefore not immersive. + state = kImmersiveFalse; + } + } + DCHECK_NE(kImmersiveUnknown, state); + + return state == kImmersiveTrue; } wchar_t* LocalAllocAndCopyString(const string16& src) { diff --git a/base/win/metro.h b/base/win/metro.h index be13a30..e25c6f4 100644 --- a/base/win/metro.h +++ b/base/win/metro.h @@ -51,6 +51,10 @@ BASE_EXPORT extern const char kActivateApplication[]; // indicates that the metro dll was not loaded in the process. BASE_EXPORT HMODULE GetMetroModule(); +// Returns true if this process is running as an immersive program +// in Windows Metro mode. +BASE_EXPORT bool IsMetroProcess(); + // Allocates and returns the destination string via the LocalAlloc API after // copying the src to it. BASE_EXPORT wchar_t* LocalAllocAndCopyString(const string16& src); diff --git a/chrome/browser/bookmarks/bookmark_manager_extension_api.cc b/chrome/browser/bookmarks/bookmark_manager_extension_api.cc index f223c601..159d7f8 100644 --- a/chrome/browser/bookmarks/bookmark_manager_extension_api.cc +++ b/chrome/browser/bookmarks/bookmark_manager_extension_api.cc @@ -509,7 +509,7 @@ bool CanOpenNewWindowsBookmarkFunction::RunImpl() { bool can_open_new_windows = true; #if defined(OS_WIN) - if (base::win::GetMetroModule()) + if (base::win::IsMetroProcess()) can_open_new_windows = false; #endif // OS_WIN diff --git a/chrome/browser/extensions/api/tabs/tabs.cc b/chrome/browser/extensions/api/tabs/tabs.cc index da0a246..38c2652 100644 --- a/chrome/browser/extensions/api/tabs/tabs.cc +++ b/chrome/browser/extensions/api/tabs/tabs.cc @@ -227,7 +227,7 @@ Browser* CreateBrowserWindow(const Browser::CreateParams& params, #if defined(OS_WIN) // In Windows 8 metro mode we only allow new windows to be created if the // extension id is valid in which case it is created as an application window - if (extension_id.empty() && base::win::GetMetroModule()) + if (extension_id.empty() && base::win::IsMetroProcess()) use_existing_browser_window = true; #endif // OS_WIN diff --git a/chrome/browser/first_run/upgrade_util_win.cc b/chrome/browser/first_run/upgrade_util_win.cc index 88c5d7e..a4fc3b0 100644 --- a/chrome/browser/first_run/upgrade_util_win.cc +++ b/chrome/browser/first_run/upgrade_util_win.cc @@ -146,7 +146,7 @@ bool DoUpgradeTasks(const CommandLine& command_line) { // The DelegateExecute verb handler finalizes pending in-use updates for // metro mode launches, as Chrome cannot be gracefully relaunched when // running in this mode. - if (base::win::GetMetroModule()) + if (base::win::IsMetroProcess()) return false; if (!SwapNewChromeExeIfPresent()) return false; diff --git a/chrome/browser/notifications/desktop_notification_service_win.cc b/chrome/browser/notifications/desktop_notification_service_win.cc index 3f9bd29..7f9035b 100644 --- a/chrome/browser/notifications/desktop_notification_service_win.cc +++ b/chrome/browser/notifications/desktop_notification_service_win.cc @@ -23,7 +23,7 @@ bool DesktopNotificationService::CancelDesktopNotification( scoped_refptr<NotificationObjectProxy> proxy( new NotificationObjectProxy(process_id, route_id, notification_id, false)); - if (base::win::GetMetroModule()) { + if (base::win::IsMetroProcess()) { MetroCancelNotification cancel_metro_notification = reinterpret_cast<MetroCancelNotification>(GetProcAddress( base::win::GetMetroModule(), "CancelNotification")); @@ -36,7 +36,7 @@ bool DesktopNotificationService::CancelDesktopNotification( void DesktopNotificationService::ShowNotification( const Notification& notification) { - if (base::win::GetMetroModule()) { + if (base::win::IsMetroProcess()) { MetroDisplayNotification display_metro_notification = reinterpret_cast<MetroDisplayNotification>(GetProcAddress( base::win::GetMetroModule(), "DisplayNotification")); diff --git a/chrome/browser/profiles/profile_manager.cc b/chrome/browser/profiles/profile_manager.cc index a1992a5..7855e32 100644 --- a/chrome/browser/profiles/profile_manager.cc +++ b/chrome/browser/profiles/profile_manager.cc @@ -949,7 +949,7 @@ bool ProfileManager::IsMultipleProfilesEnabled() { return false; #endif #if defined(OS_WIN) - if (base::win::GetMetroModule()) + if (base::win::IsMetroProcess()) return false; #endif return !ManagedMode::IsInManagedMode(); diff --git a/chrome/browser/shell_integration_win.cc b/chrome/browser/shell_integration_win.cc index 680a6e4..68e0cca 100644 --- a/chrome/browser/shell_integration_win.cc +++ b/chrome/browser/shell_integration_win.cc @@ -391,7 +391,7 @@ bool ActivateApplication(const string16& app_id) { // Not supported when running in metro mode. // TODO(grt) This should perhaps check that this Chrome isn't in metro mode // or, if it is, that |app_id| doesn't identify this Chrome. - if (base::win::GetMetroModule()) + if (base::win::IsMetroProcess()) return false; // Delegate to metro_driver, which has the brains to invoke the activation diff --git a/chrome/browser/tab_contents/render_view_context_menu_win.cc b/chrome/browser/tab_contents/render_view_context_menu_win.cc index 8c16a95..bff9a82 100644 --- a/chrome/browser/tab_contents/render_view_context_menu_win.cc +++ b/chrome/browser/tab_contents/render_view_context_menu_win.cc @@ -32,7 +32,7 @@ RenderViewContextMenuViews* RenderViewContextMenuViews::Create( bool RenderViewContextMenuWin::IsCommandIdVisible(int command_id) const { // In windows 8 metro mode no new window option on normal browser windows. - if (base::win::GetMetroModule() && !profile_->IsOffTheRecord() && + if (base::win::IsMetroProcess() && !profile_->IsOffTheRecord() && command_id == IDC_CONTENT_CONTEXT_OPENLINKNEWWINDOW) { return false; } @@ -45,7 +45,7 @@ void RenderViewContextMenuWin::ExecuteCommand(int command_id) { void RenderViewContextMenuWin::ExecuteCommand(int command_id, int event_flags) { - if (base::win::GetMetroModule() && + if (base::win::IsMetroProcess() && command_id == IDC_CONTENT_CONTEXT_OPENLINKNEWWINDOW) { // The open link in new window command should only be enabled for // incognito windows in metro mode. diff --git a/chrome/browser/ui/browser.cc b/chrome/browser/ui/browser.cc index f5f7d91..5aa2819 100644 --- a/chrome/browser/ui/browser.cc +++ b/chrome/browser/ui/browser.cc @@ -4189,7 +4189,7 @@ void Browser::InitCommandState() { command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_7, normal_window); command_updater_.UpdateCommandEnabled(IDC_SELECT_LAST_TAB, normal_window); #if defined(OS_WIN) - const bool metro_mode = (base::win::GetMetroModule() != NULL); + const bool metro_mode = base::win::IsMetroProcess(); command_updater_.UpdateCommandEnabled(IDC_METRO_SNAP_ENABLE, metro_mode); command_updater_.UpdateCommandEnabled(IDC_METRO_SNAP_DISABLE, metro_mode); #endif diff --git a/chrome/browser/ui/browser_win.cc b/chrome/browser/ui/browser_win.cc index 4f307a4..9f67cb5 100644 --- a/chrome/browser/ui/browser_win.cc +++ b/chrome/browser/ui/browser_win.cc @@ -39,7 +39,7 @@ void NewMetroWindow(Browser* source_browser, Profile* profile) { } // namespace void Browser::NewWindow() { - if (base::win::GetMetroModule()) { + if (base::win::IsMetroProcess()) { NewMetroWindow(this, profile_->GetOriginalProfile()); return; } @@ -47,7 +47,7 @@ void Browser::NewWindow() { } void Browser::NewIncognitoWindow() { - if (base::win::GetMetroModule()) { + if (base::win::IsMetroProcess()) { NewMetroWindow(this, profile_->GetOffTheRecordProfile()); return; } diff --git a/chrome/browser/ui/tab_contents/tab_contents.cc b/chrome/browser/ui/tab_contents/tab_contents.cc index 47b894d..ead2ad4 100644 --- a/chrome/browser/ui/tab_contents/tab_contents.cc +++ b/chrome/browser/ui/tab_contents/tab_contents.cc @@ -142,7 +142,7 @@ TabContents::TabContents(WebContents* contents) #if defined(OS_WIN) // Metro mode Chrome on Windows does not support plugins. Avoid registering // the PluginObserver so we don't popup plugin-related infobars. - if (!base::win::GetMetroModule()) + if (!base::win::IsMetroProcess()) plugin_observer_.reset(new PluginObserver(this)); #else plugin_observer_.reset(new PluginObserver(this)); diff --git a/chrome/browser/ui/views/bookmarks/bookmark_context_menu_controller_views_win.cc b/chrome/browser/ui/views/bookmarks/bookmark_context_menu_controller_views_win.cc index e23d7a9..ebb5aa0 100644 --- a/chrome/browser/ui/views/bookmarks/bookmark_context_menu_controller_views_win.cc +++ b/chrome/browser/ui/views/bookmarks/bookmark_context_menu_controller_views_win.cc @@ -43,7 +43,7 @@ BookmarkContextMenuControllerViewsWin } void BookmarkContextMenuControllerViewsWin::ExecuteCommand(int id) { - if (base::win::GetMetroModule()) { + if (base::win::IsMetroProcess()) { switch (id) { // We need to handle the open in new window and open in incognito window // commands to ensure that they first look for an existing browser object @@ -86,7 +86,7 @@ void BookmarkContextMenuControllerViewsWin::ExecuteCommand(int id) { bool BookmarkContextMenuControllerViewsWin::IsCommandEnabled(int id) const { // In Windows 8 metro mode no new window option on a regular chrome window // and no new incognito window option on an incognito chrome window. - if (base::win::GetMetroModule()) { + if (base::win::IsMetroProcess()) { if (id == IDC_BOOKMARK_BAR_OPEN_ALL_NEW_WINDOW && !profile()->IsOffTheRecord()) { return false; diff --git a/chrome/browser/ui/views/frame/browser_frame_win.cc b/chrome/browser/ui/views/frame/browser_frame_win.cc index eb97169..f932a79 100644 --- a/chrome/browser/ui/views/frame/browser_frame_win.cc +++ b/chrome/browser/ui/views/frame/browser_frame_win.cc @@ -96,7 +96,7 @@ BrowserFrameWin::BrowserFrameWin(BrowserFrame* browser_frame, browser_frame_(browser_frame), system_menu_delegate_(new SystemMenuModelDelegate(browser_view, browser_view->browser())) { - if (base::win::GetMetroModule()) { + if (base::win::IsMetroProcess()) { browser_view->SetWindowSwitcherButton( MakeWindowSwitcherButton(this, browser_view->IsOffTheRecord())); } @@ -316,7 +316,7 @@ LRESULT BrowserFrameWin::OnWndProc(UINT message, HandleMetroNavSearchRequest(w_param, l_param); } else if (message == metro_get_current_tab_info_message) { GetMetroCurrentTabInfo(w_param); - } else if (message == WM_PRINT && base::win::GetMetroModule()) { + } else if (message == WM_PRINT && base::win::IsMetroProcess()) { // This message is sent by the AnimateWindow API which is used in metro // mode to flip between active chrome windows. RECT client_rect = {0}; @@ -438,7 +438,7 @@ void BrowserFrameWin::AddFrameToggleItems() { void BrowserFrameWin::HandleMetroNavSearchRequest(WPARAM w_param, LPARAM l_param) { - if (!base::win::GetMetroModule()) { + if (!base::win::IsMetroProcess()) { NOTREACHED() << "Received unexpected metro navigation request"; return; } @@ -477,7 +477,7 @@ void BrowserFrameWin::HandleMetroNavSearchRequest(WPARAM w_param, } void BrowserFrameWin::GetMetroCurrentTabInfo(WPARAM w_param) { - if (!base::win::GetMetroModule()) { + if (!base::win::IsMetroProcess()) { NOTREACHED() << "Received unexpected metro request"; return; } diff --git a/chrome/browser/ui/views/frame/browser_view.cc b/chrome/browser/ui/views/frame/browser_view.cc index 37d43e8..d08ff75 100644 --- a/chrome/browser/ui/views/frame/browser_view.cc +++ b/chrome/browser/ui/views/frame/browser_view.cc @@ -1309,7 +1309,7 @@ WindowOpenDisposition BrowserView::GetDispositionForPopupBounds( return NEW_POPUP; #else // If we are in windows metro-mode, we can't allow popup windows. - return (base::win::GetMetroModule() == NULL) ? NEW_POPUP : NEW_BACKGROUND_TAB; + return base::win::IsMetroProcess() ? NEW_BACKGROUND_TAB : NEW_POPUP; #endif #else return NEW_POPUP; @@ -1485,7 +1485,7 @@ bool BrowserView::ExecuteWindowsCommand(int command_id) { GetWidget()->DebugToggleFrameType(); // In Windows 8 metro mode prevent sizing and moving. - if (base::win::GetMetroModule()) { + if (base::win::IsMetroProcess()) { // Windows uses the 4 lower order bits of |notification_code| for type- // specific information so we must exclude this when comparing. static const int sc_mask = 0xFFF0; @@ -1801,7 +1801,7 @@ int BrowserView::GetOTRIconResourceID() const { if (IsFullscreen()) otr_resource_id = IDR_OTR_ICON_FULLSCREEN; #if defined(OS_WIN) && !defined(USE_AURA) - if (base::win::GetMetroModule() != NULL) + if (base::win::IsMetroProcess()) otr_resource_id = IDR_OTR_ICON_FULLSCREEN; #endif } diff --git a/chrome/browser/ui/views/tabs/tab_strip.cc b/chrome/browser/ui/views/tabs/tab_strip.cc index 624a3ed..66c766d 100644 --- a/chrome/browser/ui/views/tabs/tab_strip.cc +++ b/chrome/browser/ui/views/tabs/tab_strip.cc @@ -1001,7 +1001,7 @@ void TabStrip::MaybeStartDrag( } #if defined(OS_WIN) // It doesn't make sense to drag tabs out on metro. - if (base::win::GetMetroModule()) + if (base::win::IsMetroProcess()) detach_behavior = TabDragController::NOT_DETACHABLE; #endif drag_controller_.reset(new TabDragController); diff --git a/chrome/common/chrome_paths_win.cc b/chrome/common/chrome_paths_win.cc index 21d9a35..c9afb7a 100644 --- a/chrome/common/chrome_paths_win.cc +++ b/chrome/common/chrome_paths_win.cc @@ -29,7 +29,7 @@ bool GetUserDataDirectoryForEnvironment(bool current, FilePath* result) { return false; BrowserDistribution* dist = BrowserDistribution::GetDistribution(); *result = result->Append(dist->GetInstallSubDir()); - if (base::win::GetMetroModule() ? current : !current) + if (base::win::IsMetroProcess() ? current : !current) *result = result->Append(kMetroChromeUserDataSubDir); *result = result->Append(chrome::kUserDataDirname); return true; diff --git a/chrome/common/extensions/extension.cc b/chrome/common/extensions/extension.cc index c36402c..0b9c110 100644 --- a/chrome/common/extensions/extension.cc +++ b/chrome/common/extensions/extension.cc @@ -1524,7 +1524,7 @@ bool Extension::LoadPlugins(string16* error) { #if defined(OS_WIN) // Like Chrome OS, we don't support NPAPI plugins in Windows 8 metro mode // but in this case we want to fail with an error. - if (base::win::GetMetroModule()) { + if (base::win::IsMetroProcess()) { *error = l10n_util::GetStringUTF16( IDS_EXTENSION_INSTALL_PLUGIN_NOT_SUPPORTED); return false; diff --git a/chrome/common/pepper_flash.cc b/chrome/common/pepper_flash.cc index 0f4a6cc..2f3e531 100644 --- a/chrome/common/pepper_flash.cc +++ b/chrome/common/pepper_flash.cc @@ -93,7 +93,7 @@ bool IsPepperFlashEnabledByDefault() { return true; #elif defined(OS_WIN) // Pepper Flash is required for Windows 8 Metro mode. - if (base::win::GetMetroModule()) + if (base::win::IsMetroProcess()) return true; chrome::VersionInfo::Channel channel = chrome::VersionInfo::GetChannel(); diff --git a/content/browser/renderer_host/render_widget_host_view_win.cc b/content/browser/renderer_host/render_widget_host_view_win.cc index 93e74a6..641d46c 100644 --- a/content/browser/renderer_host/render_widget_host_view_win.cc +++ b/content/browser/renderer_host/render_widget_host_view_win.cc @@ -606,7 +606,7 @@ void RenderWidgetHostViewWin::CreateWnd(HWND parent) { // ATL function to create the window. Create(parent); if (base::win::GetVersion() >= base::win::VERSION_WIN8 && - !base::win::GetMetroModule()) { + !base::win::IsMetroProcess()) { virtual_keyboard_.CreateInstance(CLSID_TextInputPanel, NULL, CLSCTX_INPROC); if (virtual_keyboard_) { virtual_keyboard_->put_AttachedEditWindow(m_hWnd); @@ -2724,7 +2724,7 @@ LRESULT RenderWidgetHostViewWin::OnPointerMessage( lparam = MAKELPARAM(point.x, point.y); if (message == WM_POINTERDOWN) { - if (!base::win::GetMetroModule()) { + if (!base::win::IsMetroProcess()) { SetFocus(); pointer_down_context_ = true; received_focus_change_after_pointer_down_ = false; diff --git a/ui/base/layout.cc b/ui/base/layout.cc index 368a395..3b0446e 100644 --- a/ui/base/layout.cc +++ b/ui/base/layout.cc @@ -45,7 +45,7 @@ bool UseTouchOptimizedUI() { #if defined(OS_WIN) // On Windows, we use the touch layout only when we are running in // Metro mode. - return base::win::GetMetroModule() != NULL; + return base::win::IsMetroProcess(); #elif defined(USE_AURA) && defined(USE_X11) // Determine whether touch-screen hardware is currently available. // For now we must ensure this won't change over the life of the process, diff --git a/ui/views/controls/textfield/native_textfield_win.cc b/ui/views/controls/textfield/native_textfield_win.cc index 39fb411..ec98132 100644 --- a/ui/views/controls/textfield/native_textfield_win.cc +++ b/ui/views/controls/textfield/native_textfield_win.cc @@ -124,7 +124,7 @@ NativeTextfieldWin::NativeTextfieldWin(Textfield* textfield) text_object_model_.QueryFrom(ole_interface); if (base::win::GetVersion() >= base::win::VERSION_WIN8 && - !base::win::GetMetroModule()) { + !base::win::IsMetroProcess()) { keyboard_.CreateInstance(__uuidof(TextInputPanel), NULL, CLSCTX_INPROC); if (keyboard_ != NULL) keyboard_->put_AttachedEditWindow(m_hWnd); diff --git a/webkit/plugins/npapi/plugin_list_win.cc b/webkit/plugins/npapi/plugin_list_win.cc index 88e6374..3a723138 100644 --- a/webkit/plugins/npapi/plugin_list_win.cc +++ b/webkit/plugins/npapi/plugin_list_win.cc @@ -395,7 +395,7 @@ bool PluginList::ShouldLoadPlugin(const webkit::WebPluginInfo& info, } } - if (base::win::GetMetroModule()) { + if (base::win::IsMetroProcess()) { // In metro mode we only allow pepper plugins. if (info.type == WebPluginInfo::PLUGIN_TYPE_NPAPI) return false; |
