Desktop Chrome on Windows 8 should attempt to relaunch into immersive mode if the previous run was immersive
or if the machine is a tablet.

This is in line with the expectations of the Windows 8 Chrome Singleton approach where we have one of Chrome 
desktop/Chrome Windows 8 immersive mode running at any given time.

Fixes bug http://code.google.com/p/chromium/issues/detail?id=153318

BUG=153318
R=sky
 
Relaunch Chrome on Windows 8 into immersive mode if the previous run was 
Review URL: https://codereview.chromium.org/11026053

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@160436 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/chrome/browser/process_singleton_win.cc b/chrome/browser/process_singleton_win.cc
index a8c3b264..d3964617 100644
--- a/chrome/browser/process_singleton_win.cc
+++ b/chrome/browser/process_singleton_win.cc
@@ -15,13 +15,17 @@
 #include "base/stringprintf.h"
 #include "base/utf_string_conversions.h"
 #include "base/win/metro.h"
+#include "base/win/registry.h"
 #include "base/win/scoped_com_initializer.h"
 #include "base/win/scoped_comptr.h"
 #include "base/win/scoped_handle.h"
+#include "base/win/win_util.h"
 #include "base/win/windows_version.h"
 #include "base/win/wrapped_window_proc.h"
 #include "chrome/browser/ui/simple_message_box.h"
 #include "chrome/common/chrome_constants.h"
+#include "chrome/common/chrome_paths.h"
+#include "chrome/common/chrome_paths_internal.h"
 #include "chrome/installer/util/browser_distribution.h"
 #include "chrome/installer/util/install_util.h"
 #include "chrome/installer/util/shell_util.h"
@@ -40,6 +44,8 @@
 const char kSearchUrl[] =
   "http://www.google.com/search?q=%s&sourceid=chrome&ie=UTF-8";
 
+const int kImmersiveChromeInitTimeout = 500;
+
 // Checks the visibility of the enumerated window and signals once a visible
 // window has been found.
 BOOL CALLBACK BrowserWindowEnumeration(HWND window, LPARAM param) {
@@ -161,6 +167,54 @@
   return true;
 }
 
+// Returns true if Chrome needs to be relaunched into Windows 8 immersive mode.
+// Following conditions apply:-
+// 1. Windows 8 or greater.
+// 2. Not in Windows 8 immersive mode.
+// 3. Process integrity level is not high.
+// 4. The profile data directory is the default directory .
+// 5. Last used mode was immersive/machine is a tablet.
+// TODO(ananta)
+// Move this function to a common place as the Windows 8 delegate_execute
+// handler can possibly use this.
+bool ShouldLaunchInWindows8ImmersiveMode(const FilePath& user_data_dir) {
+#if defined(USE_AURA)
+  return false;
+#endif
+
+  if (base::win::GetVersion() < base::win::VERSION_WIN8)
+    return false;
+
+  if (base::win::IsProcessImmersive(base::GetCurrentProcessHandle()))
+    return false;
+
+  base::IntegrityLevel integrity_level = base::INTEGRITY_UNKNOWN;
+  base::GetProcessIntegrityLevel(base::GetCurrentProcessHandle(),
+                                 &integrity_level);
+  if (integrity_level == base::HIGH_INTEGRITY)
+    return false;
+
+  FilePath default_user_data_dir;
+  if (!chrome::GetDefaultUserDataDirectory(&default_user_data_dir))
+    return false;
+
+  if (default_user_data_dir != user_data_dir)
+    return false;
+
+  base::win::RegKey reg_key;
+  LONG key_result = reg_key.Create(HKEY_CURRENT_USER,
+                                   chrome::kMetroRegistryPath,
+                                   KEY_READ);
+  if (key_result == ERROR_SUCCESS) {
+    DWORD reg_value = 0;
+    reg_key.ReadValueDW(chrome::kLaunchModeValue,
+                        &reg_value);
+    if (reg_value == 1)
+      return true;
+  }
+  return base::win::IsMachineATablet();
+}
+
 }  // namespace
 
 // Microsoft's Softricity virtualization breaks the sandbox processes.
@@ -200,6 +254,19 @@
 ProcessSingleton::ProcessSingleton(const FilePath& user_data_dir)
     : window_(NULL), locked_(false), foreground_window_(NULL),
     is_virtualized_(false), lock_file_(INVALID_HANDLE_VALUE) {
+  FilePath default_user_data_dir;
+  // For Windows 8 and above check if we need to relaunch into Windows 8
+  // immersive mode.
+  if (ShouldLaunchInWindows8ImmersiveMode(user_data_dir)) {
+    bool immersive_chrome_launched = ActivateMetroChrome();
+    if (!immersive_chrome_launched) {
+      LOG(WARNING) << "Failed to launch immersive chrome";
+    } else {
+      // Sleep to allow the immersive chrome process to create its initial
+      // message window.
+      SleepEx(kImmersiveChromeInitTimeout, FALSE);
+    }
+  }
   remote_window_ = FindWindowEx(HWND_MESSAGE, NULL,
                                 chrome::kMessageWindowClass,
                                 user_data_dir.value().c_str());