summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorshrikant@chromium.org <shrikant@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-02-27 22:56:27 +0000
committershrikant@chromium.org <shrikant@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-02-27 22:56:27 +0000
commita37cac5498b26dff7ee93dea47fa6b206e2303a5 (patch)
tree7dbf04ab413028cdf1bdec1d8047b4795b5950fd
parent9934b43df0157182b8cb452ab7a58c40352987ce (diff)
downloadchromium_src-a37cac5498b26dff7ee93dea47fa6b206e2303a5.zip
chromium_src-a37cac5498b26dff7ee93dea47fa6b206e2303a5.tar.gz
chromium_src-a37cac5498b26dff7ee93dea47fa6b206e2303a5.tar.bz2
Closed UI channel for fast metro shutdown/restart.
As it works currently, when we close metro viewer with Alt+F4, the process remains in suspended state for approximately 10 seconds and terminates after that. On the browser process side, ChromeMetroViewerProcessHost class holds ref count to browser process and releases OnChannelError. With this change we trigger channel error immediately after sending Alt+F4 so that browser process can exit/restart. BUG=335070 R=cpu,ananta Review URL: https://codereview.chromium.org/164553007 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@253960 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--win8/metro_driver/chrome_app_view_ash.cc49
-rw-r--r--win8/metro_driver/chrome_app_view_ash.h7
2 files changed, 35 insertions, 21 deletions
diff --git a/win8/metro_driver/chrome_app_view_ash.cc b/win8/metro_driver/chrome_app_view_ash.cc
index 1479a7c..dc5923c 100644
--- a/win8/metro_driver/chrome_app_view_ash.cc
+++ b/win8/metro_driver/chrome_app_view_ash.cc
@@ -85,7 +85,7 @@ enum KeyModifier {
// Helper function to send keystrokes via the SendInput function.
// mnemonic_char: The keystroke to be sent.
// modifiers: Combination with Alt, Ctrl, Shift, etc.
-void SendMnemonic(
+void SendKeySequence(
WORD mnemonic_char, KeyModifier modifiers) {
INPUT keys[4] = {0}; // Keyboard events
int key_count = 0; // Number of generated events
@@ -134,19 +134,6 @@ void SendMnemonic(
}
}
-// Helper function to Exit metro chrome cleanly. If we are in the foreground
-// then we try and exit by sending an Alt+F4 key combination to the core
-// window which ensures that the chrome application tile does not show up in
-// the running metro apps list on the top left corner.
-void MetroExit(HWND core_window) {
- if ((core_window != NULL) && (core_window == ::GetForegroundWindow())) {
- DVLOG(1) << "We are in the foreground. Exiting via Alt F4";
- SendMnemonic(VK_F4, ALT);
- } else {
- globals.app_exit->Exit();
- }
-}
-
class ChromeChannelListener : public IPC::Listener {
public:
ChromeChannelListener(base::MessageLoop* ui_loop, ChromeAppViewAsh* app_view)
@@ -179,11 +166,15 @@ class ChromeChannelListener : public IPC::Listener {
virtual void OnChannelError() OVERRIDE {
DVLOG(1) << "Channel error. Exiting.";
- MetroExit(app_view_->core_window_hwnd());
+ ui_proxy_->PostTask(FROM_HERE,
+ base::Bind(&ChromeAppViewAsh::OnMetroExit, base::Unretained(app_view_),
+ TERMINATE_USING_KEY_SEQUENCE));
+
// In early Windows 8 versions the code above sometimes fails so we call
// it a second time with a NULL window which just calls Exit().
ui_proxy_->PostDelayedTask(FROM_HERE,
- base::Bind(&MetroExit, HWND(NULL)),
+ base::Bind(&ChromeAppViewAsh::OnMetroExit, base::Unretained(app_view_),
+ TERMINATE_USING_PROCESS_EXIT),
base::TimeDelta::FromMilliseconds(100));
}
@@ -196,7 +187,9 @@ class ChromeChannelListener : public IPC::Listener {
}
void OnMetroExit() {
- MetroExit(app_view_->core_window_hwnd());
+ ui_proxy_->PostTask(FROM_HERE,
+ base::Bind(&ChromeAppViewAsh::OnMetroExit,
+ base::Unretained(app_view_), TERMINATE_USING_KEY_SEQUENCE));
}
void OnOpenURLOnDesktop(const base::FilePath& shortcut,
@@ -746,7 +739,7 @@ void ChromeAppViewAsh::OnActivateDesktop(const base::FilePath& file_path,
if (ash_exit) {
// As we are the top level window, the exiting is done async so we manage
// to execute the entire function including the final Send().
- MetroExit(core_window_hwnd());
+ OnMetroExit(TERMINATE_USING_KEY_SEQUENCE);
}
// We are just executing delegate_execute here without parameters. Assumption
@@ -768,9 +761,6 @@ void ChromeAppViewAsh::OnActivateDesktop(const base::FilePath& file_path,
::TerminateProcess(sei.hProcess, 0);
::CloseHandle(sei.hProcess);
}
-
- if (ash_exit)
- ui_channel_->Close();
}
void ChromeAppViewAsh::OnOpenURLOnDesktop(const base::FilePath& shortcut,
@@ -920,6 +910,23 @@ void ChromeAppViewAsh::OnImePopupChanged(ImePopupObserver::EventType event) {
}
}
+// Function to Exit metro chrome cleanly. If we are in the foreground
+// then we try and exit by sending an Alt+F4 key combination to the core
+// window which ensures that the chrome application tile does not show up in
+// the running metro apps list on the top left corner.
+void ChromeAppViewAsh::OnMetroExit(MetroTerminateMethod method) {
+ HWND core_window = core_window_hwnd();
+ if (method == TERMINATE_USING_KEY_SEQUENCE && core_window != NULL &&
+ core_window == ::GetForegroundWindow()) {
+ DVLOG(1) << "We are in the foreground. Exiting via Alt F4";
+ SendKeySequence(VK_F4, ALT);
+ if (ui_channel_)
+ ui_channel_->Close();
+ } else {
+ globals.app_exit->Exit();
+ }
+}
+
void ChromeAppViewAsh::OnInputSourceChanged() {
if (!input_source_)
return;
diff --git a/win8/metro_driver/chrome_app_view_ash.h b/win8/metro_driver/chrome_app_view_ash.h
index d347205..5de9f67 100644
--- a/win8/metro_driver/chrome_app_view_ash.h
+++ b/win8/metro_driver/chrome_app_view_ash.h
@@ -45,6 +45,11 @@ class FilePickerSessionBase;
struct MetroViewerHostMsg_SaveAsDialogParams;
+enum MetroTerminateMethod {
+ TERMINATE_USING_KEY_SEQUENCE = 1,
+ TERMINATE_USING_PROCESS_EXIT = 2,
+};
+
class ChromeAppViewAsh
: public mswr::RuntimeClass<winapp::Core::IFrameworkView>,
public metro_driver::ImePopupObserver,
@@ -104,6 +109,8 @@ class ChromeAppViewAsh
const std::vector<int32>& input_scopes,
const std::vector<metro_viewer::CharacterBounds>& character_bounds);
+ void OnMetroExit(MetroTerminateMethod method);
+
HWND core_window_hwnd() const { return core_window_hwnd_; }