Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(8)

Side by Side Diff: win8/delegate_execute/command_execute_impl.cc

Issue 10928172: Implement the persistent metro mode setting (win8) (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/common/chrome_constants.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 // Implementation of the CommandExecuteImpl class which implements the 4 // Implementation of the CommandExecuteImpl class which implements the
5 // IExecuteCommand and related interfaces for handling ShellExecute based 5 // IExecuteCommand and related interfaces for handling ShellExecute based
6 // launches of the Chrome browser. 6 // launches of the Chrome browser.
7 7
8 #include "win8/delegate_execute/command_execute_impl.h" 8 #include "win8/delegate_execute/command_execute_impl.h"
9 9
10 #include "base/file_util.h" 10 #include "base/file_util.h"
11 #include "base/path_service.h" 11 #include "base/path_service.h"
12 #include "base/utf_string_conversions.h" 12 #include "base/utf_string_conversions.h"
13 #include "base/win/registry.h"
13 #include "base/win/scoped_co_mem.h" 14 #include "base/win/scoped_co_mem.h"
14 #include "base/win/scoped_handle.h" 15 #include "base/win/scoped_handle.h"
16 #include "base/win/win_util.h"
15 #include "chrome/common/chrome_constants.h" 17 #include "chrome/common/chrome_constants.h"
16 #include "chrome/common/chrome_paths.h" 18 #include "chrome/common/chrome_paths.h"
17 #include "chrome/common/chrome_switches.h" 19 #include "chrome/common/chrome_switches.h"
18 #include "win8/delegate_execute/chrome_util.h" 20 #include "win8/delegate_execute/chrome_util.h"
19 21
20 // CommandExecuteImpl is resposible for activating chrome in Windows 8. The 22 // CommandExecuteImpl is resposible for activating chrome in Windows 8. The
21 // flow is complicated and this tries to highlight the important events. 23 // flow is complicated and this tries to highlight the important events.
22 // The current approach is to have a single instance of chrome either 24 // The current approach is to have a single instance of chrome either
23 // running in desktop or metro mode. If there is no current instance then 25 // running in desktop or metro mode. If there is no current instance then
24 // the desktop shortcut launches desktop chrome and the metro tile or search 26 // the desktop shortcut launches desktop chrome and the metro tile or search
(...skipping 13 matching lines...) Expand all
38 // CommandExecuteImpl::SetParameter 40 // CommandExecuteImpl::SetParameter
39 // CommandExecuteImpl::SetNoShowUI 41 // CommandExecuteImpl::SetNoShowUI
40 // CommandExecuteImpl::SetSelection 42 // CommandExecuteImpl::SetSelection
41 // CommandExecuteImpl::Initialize 43 // CommandExecuteImpl::Initialize
42 // Up to this point the code basically just gathers values passed in, like 44 // Up to this point the code basically just gathers values passed in, like
43 // the launch scheme (or url) and the activation verb. 45 // the launch scheme (or url) and the activation verb.
44 // 5- Windows calls CommandExecuteImpl::Getvalue() 46 // 5- Windows calls CommandExecuteImpl::Getvalue()
45 // Here we need to return AHE_IMMERSIVE or AHE_DESKTOP. That depends on: 47 // Here we need to return AHE_IMMERSIVE or AHE_DESKTOP. That depends on:
46 // a) if run in high-integrity return AHE_DESKTOP 48 // a) if run in high-integrity return AHE_DESKTOP
47 // b) if chrome is running return the AHE_ mode of chrome 49 // b) if chrome is running return the AHE_ mode of chrome
48 // c) if the current process is inmmersive return AHE_IMMERSIVE 50 // c) else we return what GetLaunchMode() tells us, which is:
49 // d) if the protocol is file and IExecuteCommandHost::GetUIMode() is not 51 // i) if the command line --force-xxx is present return that
50 // ECHUIM_DESKTOP then return AHE_IMMERSIVE 52 // ii) if the registry 'launch_mode' exists return that
51 // e) if none of the above return AHE_DESKTOP 53 // iii) if IsMachineATablet() is true return AHE_IMMERSIVE
52 // 6- If we returned AHE_DESKTOP in step 5 then CommandExecuteImpl::Execute() 54 // iv) else return AHE_DESKTOP
53 // is called, here we call GetLaunchMode() which: 55 // 6- If we returned AHE_IMMERSIVE in step 5 windows might not call us back
54 // a) if chrome is running return the mode of chrome or 56 // and simply activate chrome in metro by itself, however in some cases
55 // b) return IExecuteCommandHost::GetUIMode() 57 // it might proceed at step 7.
56 // 7- If GetLaunchMode() returns 58 // As far as we know if we return AHE_DESKTOP then step 7 always happens.
57 // a) ECHUIM_DESKTOP we call LaunchDestopChrome() that calls ::CreateProcess 59 // 7- Windows calls CommandExecuteImpl::Execute()
60 // Here we call GetLaunchMode() which returns the cached answer
61 // computed at step 5c. which can be:
62 // a) ECHUIM_DESKTOP then we call LaunchDestopChrome() that calls
63 // ::CreateProcess and we exit at this point even on failure.
58 // b) else we call one of the IApplicationActivationManager activation 64 // b) else we call one of the IApplicationActivationManager activation
59 // functions depending on the parameters passed in step 4. 65 // functions depending on the parameters passed in step 4.
66 // c) If the activation returns E_APPLICATION_NOT_REGISTERED, then we fall
67 // back to launching chrome on the desktop via LaunchDestopChrome().
60 // 68 //
61 // Some examples will help clarify the common cases. 69 // Note that if a command line --force-xxx is present we write that launch mode
70 // in the registry so next time the logic reaches 5c-ii it will use the same
71 // mode again.
62 // 72 //
63 // I - No chrome running, taskbar icon launch: 73 // Also note that if we are not the default browser and IsMachineATablet()
64 // a) Scheme is 'file', Verb is 'open' 74 // returns true, launching chrome can go all the way to 7c, which might be
65 // b) GetValue() returns at e) step : AHE_DESKTOP 75 // a slow way to start chrome.
66 // c) Execute() calls LaunchDestopChrome()
67 // --> desktop chrome runs
68 // II- No chrome running, tile activation launch:
69 // a) Scheme is 'file', Verb is 'open'
70 // b) GetValue() returns at d) step : AHE_IMMERSIVE
71 // c) Windows does not call us back and just activates chrome
72 // --> metro chrome runs
73 // III- No chrome running, url link click on metro app:
74 // a) Scheme is 'http', Verb is 'open'
75 // b) Getvalue() returns at e) step : AHE_DESKTOP
76 // c) Execute() calls IApplicationActivationManager::ActivateForProtocol
77 // --> metro chrome runs
78 // 76 //
79 CommandExecuteImpl::CommandExecuteImpl() 77 CommandExecuteImpl::CommandExecuteImpl()
80 : integrity_level_(base::INTEGRITY_UNKNOWN), 78 : integrity_level_(base::INTEGRITY_UNKNOWN),
81 launch_scheme_(INTERNET_SCHEME_DEFAULT), 79 launch_scheme_(INTERNET_SCHEME_DEFAULT),
82 chrome_mode_(ECHUIM_SYSTEM_LAUNCHER) { 80 chrome_mode_(ECHUIM_SYSTEM_LAUNCHER) {
83 memset(&start_info_, 0, sizeof(start_info_)); 81 memset(&start_info_, 0, sizeof(start_info_));
84 start_info_.cb = sizeof(start_info_); 82 start_info_.cb = sizeof(start_info_);
85 // We need to query the user data dir of chrome so we need chrome's 83 // We need to query the user data dir of chrome so we need chrome's
86 // path provider. 84 // path provider.
87 chrome::RegisterPathProvider(); 85 chrome::RegisterPathProvider();
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
170 chrome_mode_ = ECHUIM_IMMERSIVE; 168 chrome_mode_ = ECHUIM_IMMERSIVE;
171 *pahe = AHE_IMMERSIVE; 169 *pahe = AHE_IMMERSIVE;
172 } else { 170 } else {
173 AtlTrace("Chrome [%d] is Desktop, AHE_DESKTOP\n"); 171 AtlTrace("Chrome [%d] is Desktop, AHE_DESKTOP\n");
174 chrome_mode_ = ECHUIM_DESKTOP; 172 chrome_mode_ = ECHUIM_DESKTOP;
175 *pahe = AHE_DESKTOP; 173 *pahe = AHE_DESKTOP;
176 } 174 }
177 return S_OK; 175 return S_OK;
178 } 176 }
179 177
180 if (IsImmersiveProcess(GetCurrentProcess())) { 178 EC_HOST_UI_MODE mode = GetLaunchMode();
181 AtlTrace("Current process is inmmersive, AHE_IMMERSIVE\n"); 179 *pahe = (mode == ECHUIM_DESKTOP) ? AHE_DESKTOP : AHE_IMMERSIVE;
182 *pahe = AHE_IMMERSIVE;
183 return S_OK;
184 }
185
186 if ((launch_scheme_ == INTERNET_SCHEME_FILE) &&
187 (GetLaunchMode() != ECHUIM_DESKTOP)) {
188 AtlTrace("INTERNET_SCHEME_FILE, mode != ECHUIM_DESKTOP, AHE_IMMERSIVE\n");
189 *pahe = AHE_IMMERSIVE;
190 return S_OK;
191 }
192
193 AtlTrace("Fallback is AHE_DESKTOP\n");
194 *pahe = AHE_DESKTOP;
195 return S_OK; 180 return S_OK;
196 } 181 }
197 182
198 STDMETHODIMP CommandExecuteImpl::Execute() { 183 STDMETHODIMP CommandExecuteImpl::Execute() {
199 AtlTrace("In %hs\n", __FUNCTION__); 184 AtlTrace("In %hs\n", __FUNCTION__);
200 185
201 if (integrity_level_ == base::HIGH_INTEGRITY) 186 if (integrity_level_ == base::HIGH_INTEGRITY)
202 return LaunchDesktopChrome(); 187 return LaunchDesktopChrome();
203 188
204 EC_HOST_UI_MODE mode = GetLaunchMode(); 189 EC_HOST_UI_MODE mode = GetLaunchMode();
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after
392 CloseHandle(proc_info.hProcess); 377 CloseHandle(proc_info.hProcess);
393 CloseHandle(proc_info.hThread); 378 CloseHandle(proc_info.hThread);
394 } else { 379 } else {
395 AtlTrace("Process launch failed, error %d\n", ::GetLastError()); 380 AtlTrace("Process launch failed, error %d\n", ::GetLastError());
396 } 381 }
397 382
398 return S_OK; 383 return S_OK;
399 } 384 }
400 385
401 EC_HOST_UI_MODE CommandExecuteImpl::GetLaunchMode() { 386 EC_HOST_UI_MODE CommandExecuteImpl::GetLaunchMode() {
402 // We are to return chrome's mode if chrome exists else we query our embedder 387 // See the header file for an explanation of the mode selection logic.
403 // IServiceProvider and learn the mode from them.
404 static bool launch_mode_determined = false; 388 static bool launch_mode_determined = false;
405 static EC_HOST_UI_MODE launch_mode = ECHUIM_DESKTOP; 389 static EC_HOST_UI_MODE launch_mode = ECHUIM_DESKTOP;
406 390
407 const char* modes[] = { "Desktop", "Inmmersive", "SysLauncher", "??" }; 391 const char* modes[] = { "Desktop", "Immersive", "SysLauncher", "??" };
408 392
409 if (launch_mode_determined) 393 if (launch_mode_determined)
410 return launch_mode; 394 return launch_mode;
411 395
412 if (chrome_mode_ != ECHUIM_SYSTEM_LAUNCHER) { 396 if (chrome_mode_ != ECHUIM_SYSTEM_LAUNCHER) {
413 launch_mode = chrome_mode_; 397 launch_mode = chrome_mode_;
414 AtlTrace("Launch mode is that of chrome, %s\n", modes[launch_mode]); 398 AtlTrace("Launch mode is that of chrome, %s\n", modes[launch_mode]);
415 launch_mode_determined = true; 399 launch_mode_determined = true;
416 return launch_mode; 400 return launch_mode;
417 } 401 }
418 402
419 if (parameters_ == ASCIIToWide(switches::kForceImmersive)) { 403 if (parameters_ == ASCIIToWide(switches::kForceImmersive)) {
420 launch_mode = ECHUIM_IMMERSIVE; 404 launch_mode = ECHUIM_IMMERSIVE;
421 launch_mode_determined = true; 405 launch_mode_determined = true;
406 parameters_.clear();
422 } else if (parameters_ == ASCIIToWide(switches::kForceDesktop)) { 407 } else if (parameters_ == ASCIIToWide(switches::kForceDesktop)) {
423 launch_mode = ECHUIM_DESKTOP; 408 launch_mode = ECHUIM_DESKTOP;
424 launch_mode_determined = true; 409 launch_mode_determined = true;
410 parameters_.clear();
411 }
412
413 base::win::RegKey reg_key;
414 LONG key_result = reg_key.Create(HKEY_CURRENT_USER,
415 chrome::kMetroRegistryPath,
416 KEY_ALL_ACCESS);
417 if (key_result != ERROR_SUCCESS) {
418 AtlTrace("Failed to open HKCU %ls key, error 0x%x\n",
grt (UTC plus 2) 2012/09/14 01:13:42 in this case, key_result is a last-error code. i
419 chrome::kMetroRegistryPath,
420 key_result);
grt (UTC plus 2) 2012/09/14 01:13:42 nit: move up to previous line
421 if (!launch_mode_determined) {
422 launch_mode = ECHUIM_DESKTOP;
423 launch_mode_determined = true;
424 }
425 return launch_mode;
425 } 426 }
426 427
427 if (launch_mode_determined) { 428 if (launch_mode_determined) {
428 parameters_.clear(); 429 AtlTrace("Launch mode forced by cmdline to %s\n", modes[launch_mode]);
429 AtlTrace("Launch mode forced to %s\n", modes[launch_mode]); 430 reg_key.WriteValue(chrome::kLaunchModeValue,
431 static_cast<DWORD>(launch_mode));
430 return launch_mode; 432 return launch_mode;
431 } 433 }
432 434
433 CComPtr<IExecuteCommandHost> host; 435 DWORD reg_value;
434 CComQIPtr<IServiceProvider> service_provider = m_spUnkSite; 436 if (reg_key.ReadValueDW(chrome::kLaunchModeValue,
435 if (service_provider) { 437 &reg_value) != ERROR_SUCCESS) {
436 service_provider->QueryService(IID_IExecuteCommandHost, &host); 438 launch_mode = base::win::IsMachineATablet() ?
437 if (host) { 439 ECHUIM_IMMERSIVE : ECHUIM_DESKTOP;
438 host->GetUIMode(&launch_mode); 440 AtlTrace("Launch mode forced by heuristics to %s\n", modes[launch_mode]);
439 } else { 441 } else if (reg_value >= ECHUIM_SYSTEM_LAUNCHER) {
440 AtlTrace("Failed to get IID_IExecuteCommandHost. Assuming desktop\n"); 442 AtlTrace("Invalid registry launch mode value %u\n", reg_value);
441 } 443 launch_mode = ECHUIM_DESKTOP;
442 } else { 444 } else {
443 AtlTrace("Failed to get IServiceProvider. Assuming desktop mode\n"); 445 AtlTrace("Launch mode forced by registry to %s\n", modes[launch_mode]);
446 launch_mode = static_cast<EC_HOST_UI_MODE>(reg_value);
444 } 447 }
445 AtlTrace("Launch mode is %s\n", modes[launch_mode]); 448
446 launch_mode_determined = true; 449 launch_mode_determined = true;
447 return launch_mode; 450 return launch_mode;
448 } 451 }
OLDNEW
« no previous file with comments | « chrome/common/chrome_constants.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698