// Copyright (c) 2012 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 CONTENT_BROWSER_PLUGIN_PROCESS_HOST_H_
#define CONTENT_BROWSER_PLUGIN_PROCESS_HOST_H_

#include "build/build_config.h"

#include <list>
#include <set>
#include <string>
#include <vector>

#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "base/memory/ref_counted.h"
#include "content/common/content_export.h"
#include "content/public/browser/browser_child_process_host_delegate.h"
#include "content/public/browser/browser_child_process_host_iterator.h"
#include "content/public/common/process_type.h"
#include "content/public/common/webplugininfo.h"
#include "ipc/ipc_channel_proxy.h"
#include "ui/gfx/native_widget_types.h"

namespace gfx {
class Rect;
}

namespace IPC {
struct ChannelHandle;
}

namespace content {
class BrowserChildProcessHostImpl;
class ResourceContext;

// Represents the browser side of the browser <--> plugin communication
// channel.  Different plugins run in their own process, but multiple instances
// of the same plugin run in the same process.  There will be one
// PluginProcessHost per plugin process, matched with a corresponding
// PluginProcess running in the plugin process.  The browser is responsible for
// starting the plugin process when a plugin is created that doesn't already
// have a process.  After that, most of the communication is directly between
// the renderer and plugin processes.
class CONTENT_EXPORT PluginProcessHost : public BrowserChildProcessHostDelegate,
                                         public IPC::Sender {
 public:
  class Client {
   public:
    // Returns an opaque unique identifier for the process requesting
    // the channel.
    virtual int ID() = 0;
    // Returns the resource context for the renderer requesting the channel.
    virtual ResourceContext* GetResourceContext() = 0;
    virtual bool OffTheRecord() = 0;
    virtual void SetPluginInfo(const WebPluginInfo& info) = 0;
    virtual void OnFoundPluginProcessHost(PluginProcessHost* host) = 0;
    virtual void OnSentPluginChannelRequest() = 0;
    // The client should delete itself when one of these methods is called.
    virtual void OnChannelOpened(const IPC::ChannelHandle& handle) = 0;
    virtual void OnError() = 0;

   protected:
    virtual ~Client() {}
  };

  PluginProcessHost();
  virtual ~PluginProcessHost();

  // IPC::Sender implementation:
  virtual bool Send(IPC::Message* message) OVERRIDE;

  // Initialize the new plugin process, returning true on success. This must
  // be called before the object can be used.
  bool Init(const WebPluginInfo& info);

  // Force the plugin process to shutdown (cleanly).
  void ForceShutdown();

  virtual bool OnMessageReceived(const IPC::Message& msg) OVERRIDE;
  virtual void OnChannelConnected(int32 peer_pid) OVERRIDE;
  virtual void OnChannelError() OVERRIDE;

  // Tells the plugin process to create a new channel for communication with a
  // renderer.  When the plugin process responds with the channel name,
  // OnChannelOpened in the client is called.
  void OpenChannelToPlugin(Client* client);

  // Cancels all pending channel requests for the given resource context.
  static void CancelPendingRequestsForResourceContext(ResourceContext* context);

  // This function is called to cancel pending requests to open new channels.
  void CancelPendingRequest(Client* client);

  // This function is called to cancel sent requests to open new channels.
  void CancelSentRequest(Client* client);

  // This function is called on the IO thread once we receive a reply from the
  // modal HTML dialog (in the form of a JSON string). This function forwards
  // that reply back to the plugin that requested the dialog.
  void OnModalDialogResponse(const std::string& json_retval,
                             IPC::Message* sync_result);

#if defined(OS_MACOSX)
  // This function is called on the IO thread when the browser becomes the
  // active application.
  void OnAppActivation();
#endif

  const WebPluginInfo& info() const { return info_; }

#if defined(OS_WIN)
  // Tracks plugin parent windows created on the browser UI thread.
  void AddWindow(HWND window);
#endif

  // Adds an IPC message filter.  A reference will be kept to the filter.
  void AddFilter(IPC::ChannelProxy::MessageFilter* filter);

 private:
  // Sends a message to the plugin process to request creation of a new channel
  // for the given mime type.
  void RequestPluginChannel(Client* client);

  // Message handlers.
  void OnChannelCreated(const IPC::ChannelHandle& channel_handle);

#if defined(OS_WIN)
  void OnPluginWindowDestroyed(HWND window, HWND parent);
#endif

#if defined(USE_X11)
  void OnMapNativeViewId(gfx::NativeViewId id, gfx::PluginWindowHandle* output);
#endif

#if defined(OS_MACOSX)
  void OnPluginSelectWindow(uint32 window_id, gfx::Rect window_rect,
                            bool modal);
  void OnPluginShowWindow(uint32 window_id, gfx::Rect window_rect,
                          bool modal);
  void OnPluginHideWindow(uint32 window_id, gfx::Rect window_rect);
  void OnPluginSetCursorVisibility(bool visible);
#endif

  virtual bool CanShutdown() OVERRIDE;
  virtual void OnProcessCrashed(int exit_code) OVERRIDE;

  void CancelRequests();

  // These are channel requests that we are waiting to send to the
  // plugin process once the channel is opened.
  std::vector<Client*> pending_requests_;

  // These are the channel requests that we have already sent to
  // the plugin process, but haven't heard back about yet.
  std::list<Client*> sent_requests_;

  // Information about the plugin.
  WebPluginInfo info_;

#if defined(OS_WIN)
  // Tracks plugin parent windows created on the UI thread.
  std::set<HWND> plugin_parent_windows_set_;
#endif
#if defined(OS_MACOSX)
  // Tracks plugin windows currently visible.
  std::set<uint32> plugin_visible_windows_set_;
  // Tracks full screen windows currently visible.
  std::set<uint32> plugin_fullscreen_windows_set_;
  // Tracks modal windows currently visible.
  std::set<uint32> plugin_modal_windows_set_;
  // Tracks the current visibility of the cursor.
  bool plugin_cursor_visible_;
#endif

  scoped_ptr<BrowserChildProcessHostImpl> process_;

  DISALLOW_COPY_AND_ASSIGN(PluginProcessHost);
};

class PluginProcessHostIterator
    : public BrowserChildProcessHostTypeIterator<PluginProcessHost> {
 public:
  PluginProcessHostIterator()
      : BrowserChildProcessHostTypeIterator<PluginProcessHost>(
          PROCESS_TYPE_PLUGIN) {}
};

}  // namespace content

#endif  // CONTENT_BROWSER_PLUGIN_PROCESS_HOST_H_
