// Copyright (c) 2013 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef WIN8_VIEWER_METRO_VIEWER_PROCESS_HOST_H_ #define WIN8_VIEWER_METRO_VIEWER_PROCESS_HOST_H_ #include "base/basictypes.h" #include "base/callback.h" #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" #include "base/strings/string16.h" #include "base/threading/non_thread_safe.h" #include "ipc/ipc_channel_proxy.h" #include "ipc/ipc_listener.h" #include "ipc/ipc_sender.h" #include "ipc/message_filter.h" #include "ui/gfx/native_widget_types.h" #include "win8/viewer/metro_viewer_exports.h" namespace base { class SingleThreadTaskRunner; class WaitableEvent; } namespace IPC { class ChannelProxy; class Message; } namespace win8 { // Abstract base class for various Metro viewer process host implementations. class METRO_VIEWER_EXPORT MetroViewerProcessHost : public IPC::Listener, public IPC::Sender, public base::NonThreadSafe { public: typedef base::Callback OpenFileCompletion; typedef base::Callback&, void*)> OpenMultipleFilesCompletion; typedef base::Callback SaveFileCompletion; typedef base::Callback SelectFolderCompletion; typedef base::Callback FileSelectionCanceled; // Initializes a viewer process host to connect to the Metro viewer process // over IPC. The given task runner correspond to a thread on which // IPC::Channel is created and used (e.g. IO thread). Instantly connects to // the viewer process if one is already connected to |ipc_channel_name|; a // viewer can otherwise be launched synchronously via // LaunchViewerAndWaitForConnection(). explicit MetroViewerProcessHost( const scoped_refptr& ipc_task_runner); ~MetroViewerProcessHost() override; // Returns the process id of the viewer process if one is connected to this // host, returns base::kNullProcessId otherwise. base::ProcessId GetViewerProcessId(); // Launches the viewer process associated with the given |app_user_model_id| // and blocks until that viewer process connects or until a timeout is // reached. Returns true if the viewer process connects before the timeout is // reached. NOTE: this assumes that the app referred to by |app_user_model_id| // is registered as the default browser. bool LaunchViewerAndWaitForConnection( const base::string16& app_user_model_id); // Handles the activate desktop command for Metro Chrome Ash. The |ash_exit| // parameter indicates whether the Ash process would be shutdown after // activating the desktop. static void HandleActivateDesktop(const base::FilePath& shortcut, bool ash_exit); // Handles the metro exit command. Notifies the metro viewer to shutdown // gracefully. static void HandleMetroExit(); // Handles the open file operation for Metro Chrome Ash. The on_success // callback passed in is invoked when we receive the opened file name from // the metro viewer. The on failure callback is invoked on failure. static void HandleOpenFile(const base::string16& title, const base::FilePath& default_path, const base::string16& filter, const OpenFileCompletion& on_success, const FileSelectionCanceled& on_failure); // Handles the open multiple file operation for Metro Chrome Ash. The // on_success callback passed in is invoked when we receive the opened file // names from the metro viewer. The on failure callback is invoked on failure. static void HandleOpenMultipleFiles( const base::string16& title, const base::FilePath& default_path, const base::string16& filter, const OpenMultipleFilesCompletion& on_success, const FileSelectionCanceled& on_failure); // Handles the save file operation for Metro Chrome Ash. The on_success // callback passed in is invoked when we receive the saved file name from // the metro viewer. The on failure callback is invoked on failure. static void HandleSaveFile(const base::string16& title, const base::FilePath& default_path, const base::string16& filter, int filter_index, const base::string16& default_extension, const SaveFileCompletion& on_success, const FileSelectionCanceled& on_failure); // Handles the select folder for Metro Chrome Ash. The on_success // callback passed in is invoked when we receive the folder name from the // metro viewer. The on failure callback is invoked on failure. static void HandleSelectFolder(const base::string16& title, const SelectFolderCompletion& on_success, const FileSelectionCanceled& on_failure); protected: // IPC::Sender implementation: bool Send(IPC::Message* msg) override; // IPC::Listener implementation: bool OnMessageReceived(const IPC::Message& message) override; void OnChannelError() override = 0; private: // The following are the implementation for the corresponding static methods // above, see them for descriptions. void HandleOpenFileImpl(const base::string16& title, const base::FilePath& default_path, const base::string16& filter, const OpenFileCompletion& on_success, const FileSelectionCanceled& on_failure); void HandleOpenMultipleFilesImpl( const base::string16& title, const base::FilePath& default_path, const base::string16& filter, const OpenMultipleFilesCompletion& on_success, const FileSelectionCanceled& on_failure); void HandleSaveFileImpl(const base::string16& title, const base::FilePath& default_path, const base::string16& filter, int filter_index, const base::string16& default_extension, const SaveFileCompletion& on_success, const FileSelectionCanceled& on_failure); void HandleSelectFolderImpl(const base::string16& title, const SelectFolderCompletion& on_success, const FileSelectionCanceled& on_failure); // Called over IPC by the viewer process to tell this host that it should be // drawing to |target_surface|. virtual void OnSetTargetSurface(gfx::NativeViewId target_surface, float device_scale) = 0; // Called over IPC by the viewer process to request that the url passed in be // opened. virtual void OnOpenURL(const base::string16& url) = 0; // Called over IPC by the viewer process to request that the search string // passed in is passed to the default search provider and a URL navigation be // performed. virtual void OnHandleSearchRequest(const base::string16& search_string) = 0; // Called over IPC by the viewer process when the window size has changed. virtual void OnWindowSizeChanged(uint32 width, uint32 height) = 0; void NotifyChannelConnected(); // IPC message handing methods: void OnFileSaveAsDone(bool success, const base::FilePath& filename, int filter_index); void OnFileOpenDone(bool success, const base::FilePath& filename); void OnMultiFileOpenDone(bool success, const std::vector& files); void OnSelectFolderDone(bool success, const base::FilePath& folder); // Inner message filter used to handle connection event on the IPC channel // proxy's background thread. This prevents consumers of // MetroViewerProcessHost from having to pump messages on their own message // loop. class InternalMessageFilter : public IPC::MessageFilter { public: InternalMessageFilter(MetroViewerProcessHost* owner); // IPC::MessageFilter implementation. void OnChannelConnected(int32 peer_pid) override; private: ~InternalMessageFilter(); MetroViewerProcessHost* owner_; DISALLOW_COPY_AND_ASSIGN(InternalMessageFilter); }; scoped_ptr channel_; scoped_ptr channel_connected_event_; scoped_refptr message_filter_; static MetroViewerProcessHost* instance_; // Saved callbacks which inform the caller about the result of the open file/ // save file/select operations. OpenFileCompletion file_open_completion_callback_; OpenMultipleFilesCompletion multi_file_open_completion_callback_; SaveFileCompletion file_saveas_completion_callback_; SelectFolderCompletion select_folder_completion_callback_; FileSelectionCanceled failure_callback_; DISALLOW_COPY_AND_ASSIGN(MetroViewerProcessHost); }; } // namespace win8 #endif // WIN8_VIEWER_METRO_VIEWER_PROCESS_HOST_H_