1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef WIN8_VIEWER_METRO_VIEWER_PROCESS_HOST_H_ 6 #define WIN8_VIEWER_METRO_VIEWER_PROCESS_HOST_H_ 7 8 #include "base/basictypes.h" 9 #include "base/callback.h" 10 #include "base/memory/scoped_ptr.h" 11 #include "base/strings/string16.h" 12 #include "base/threading/non_thread_safe.h" 13 #include "ipc/ipc_channel_proxy.h" 14 #include "ipc/ipc_listener.h" 15 #include "ipc/ipc_sender.h" 16 #include "ipc/message_filter.h" 17 #include "ui/gfx/native_widget_types.h" 18 #include "win8/viewer/metro_viewer_exports.h" 19 20 namespace base { 21 class SingleThreadTaskRunner; 22 class WaitableEvent; 23 } 24 25 namespace IPC { 26 class ChannelProxy; 27 class Message; 28 } 29 30 namespace win8 { 31 32 // Abstract base class for various Metro viewer process host implementations. 33 class METRO_VIEWER_EXPORT MetroViewerProcessHost : public IPC::Listener, 34 public IPC::Sender, 35 public base::NonThreadSafe { 36 public: 37 typedef base::Callback<void(const base::FilePath&, int, void*)> 38 OpenFileCompletion; 39 40 typedef base::Callback<void(const std::vector<base::FilePath>&, void*)> 41 OpenMultipleFilesCompletion; 42 43 typedef base::Callback<void(const base::FilePath&, int, void*)> 44 SaveFileCompletion; 45 46 typedef base::Callback<void(const base::FilePath&, int, void*)> 47 SelectFolderCompletion; 48 49 typedef base::Callback<void(void*)> FileSelectionCanceled; 50 51 // Initializes a viewer process host to connect to the Metro viewer process 52 // over IPC. The given task runner correspond to a thread on which 53 // IPC::Channel is created and used (e.g. IO thread). Instantly connects to 54 // the viewer process if one is already connected to |ipc_channel_name|; a 55 // viewer can otherwise be launched synchronously via 56 // LaunchViewerAndWaitForConnection(). 57 explicit MetroViewerProcessHost( 58 base::SingleThreadTaskRunner* ipc_task_runner); 59 virtual ~MetroViewerProcessHost(); 60 61 // Returns the process id of the viewer process if one is connected to this 62 // host, returns base::kNullProcessId otherwise. 63 base::ProcessId GetViewerProcessId(); 64 65 // Launches the viewer process associated with the given |app_user_model_id| 66 // and blocks until that viewer process connects or until a timeout is 67 // reached. Returns true if the viewer process connects before the timeout is 68 // reached. NOTE: this assumes that the app referred to by |app_user_model_id| 69 // is registered as the default browser. 70 bool LaunchViewerAndWaitForConnection( 71 const base::string16& app_user_model_id); 72 73 // Handles the activate desktop command for Metro Chrome Ash. The |ash_exit| 74 // parameter indicates whether the Ash process would be shutdown after 75 // activating the desktop. 76 static void HandleActivateDesktop(const base::FilePath& shortcut, 77 bool ash_exit); 78 79 // Handles the metro exit command. Notifies the metro viewer to shutdown 80 // gracefully. 81 static void HandleMetroExit(); 82 83 // Handles the open file operation for Metro Chrome Ash. The on_success 84 // callback passed in is invoked when we receive the opened file name from 85 // the metro viewer. The on failure callback is invoked on failure. 86 static void HandleOpenFile(const base::string16& title, 87 const base::FilePath& default_path, 88 const base::string16& filter, 89 const OpenFileCompletion& on_success, 90 const FileSelectionCanceled& on_failure); 91 92 // Handles the open multiple file operation for Metro Chrome Ash. The 93 // on_success callback passed in is invoked when we receive the opened file 94 // names from the metro viewer. The on failure callback is invoked on failure. 95 static void HandleOpenMultipleFiles( 96 const base::string16& title, 97 const base::FilePath& default_path, 98 const base::string16& filter, 99 const OpenMultipleFilesCompletion& on_success, 100 const FileSelectionCanceled& on_failure); 101 102 // Handles the save file operation for Metro Chrome Ash. The on_success 103 // callback passed in is invoked when we receive the saved file name from 104 // the metro viewer. The on failure callback is invoked on failure. 105 static void HandleSaveFile(const base::string16& title, 106 const base::FilePath& default_path, 107 const base::string16& filter, 108 int filter_index, 109 const base::string16& default_extension, 110 const SaveFileCompletion& on_success, 111 const FileSelectionCanceled& on_failure); 112 113 // Handles the select folder for Metro Chrome Ash. The on_success 114 // callback passed in is invoked when we receive the folder name from the 115 // metro viewer. The on failure callback is invoked on failure. 116 static void HandleSelectFolder(const base::string16& title, 117 const SelectFolderCompletion& on_success, 118 const FileSelectionCanceled& on_failure); 119 120 protected: 121 // IPC::Sender implementation: 122 virtual bool Send(IPC::Message* msg) OVERRIDE; 123 124 // IPC::Listener implementation: 125 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; 126 virtual void OnChannelError() OVERRIDE = 0; 127 128 private: 129 // The following are the implementation for the corresponding static methods 130 // above, see them for descriptions. 131 void HandleOpenFileImpl(const base::string16& title, 132 const base::FilePath& default_path, 133 const base::string16& filter, 134 const OpenFileCompletion& on_success, 135 const FileSelectionCanceled& on_failure); 136 void HandleOpenMultipleFilesImpl( 137 const base::string16& title, 138 const base::FilePath& default_path, 139 const base::string16& filter, 140 const OpenMultipleFilesCompletion& on_success, 141 const FileSelectionCanceled& on_failure); 142 void HandleSaveFileImpl(const base::string16& title, 143 const base::FilePath& default_path, 144 const base::string16& filter, 145 int filter_index, 146 const base::string16& default_extension, 147 const SaveFileCompletion& on_success, 148 const FileSelectionCanceled& on_failure); 149 void HandleSelectFolderImpl(const base::string16& title, 150 const SelectFolderCompletion& on_success, 151 const FileSelectionCanceled& on_failure); 152 153 // Called over IPC by the viewer process to tell this host that it should be 154 // drawing to |target_surface|. 155 virtual void OnSetTargetSurface(gfx::NativeViewId target_surface, 156 float device_scale) = 0; 157 158 // Called over IPC by the viewer process to request that the url passed in be 159 // opened. 160 virtual void OnOpenURL(const base::string16& url) = 0; 161 162 // Called over IPC by the viewer process to request that the search string 163 // passed in is passed to the default search provider and a URL navigation be 164 // performed. 165 virtual void OnHandleSearchRequest(const base::string16& search_string) = 0; 166 167 // Called over IPC by the viewer process when the window size has changed. 168 virtual void OnWindowSizeChanged(uint32 width, uint32 height) = 0; 169 170 void NotifyChannelConnected(); 171 172 // IPC message handing methods: 173 void OnFileSaveAsDone(bool success, 174 const base::FilePath& filename, 175 int filter_index); 176 void OnFileOpenDone(bool success, const base::FilePath& filename); 177 void OnMultiFileOpenDone(bool success, 178 const std::vector<base::FilePath>& files); 179 void OnSelectFolderDone(bool success, const base::FilePath& folder); 180 181 // Inner message filter used to handle connection event on the IPC channel 182 // proxy's background thread. This prevents consumers of 183 // MetroViewerProcessHost from having to pump messages on their own message 184 // loop. 185 class InternalMessageFilter : public IPC::MessageFilter { 186 public: 187 InternalMessageFilter(MetroViewerProcessHost* owner); 188 189 // IPC::MessageFilter implementation. 190 virtual void OnChannelConnected(int32 peer_pid) OVERRIDE; 191 192 private: 193 MetroViewerProcessHost* owner_; 194 DISALLOW_COPY_AND_ASSIGN(InternalMessageFilter); 195 }; 196 197 scoped_ptr<IPC::ChannelProxy> channel_; 198 scoped_ptr<base::WaitableEvent> channel_connected_event_; 199 scoped_refptr<InternalMessageFilter> message_filter_; 200 201 static MetroViewerProcessHost* instance_; 202 203 // Saved callbacks which inform the caller about the result of the open file/ 204 // save file/select operations. 205 OpenFileCompletion file_open_completion_callback_; 206 OpenMultipleFilesCompletion multi_file_open_completion_callback_; 207 SaveFileCompletion file_saveas_completion_callback_; 208 SelectFolderCompletion select_folder_completion_callback_; 209 FileSelectionCanceled failure_callback_; 210 211 DISALLOW_COPY_AND_ASSIGN(MetroViewerProcessHost); 212 }; 213 214 } // namespace win8 215 216 #endif // WIN8_VIEWER_METRO_VIEWER_PROCESS_HOST_H_ 217