// 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 CHROME_FRAME_CHROME_FRAME_ACTIVEX_BASE_H_
#define CHROME_FRAME_CHROME_FRAME_ACTIVEX_BASE_H_

#include <atlbase.h>
#include <atlcom.h>
#include <atlctl.h>
#include <exdisp.h>
#include <wininet.h>
#include <shdeprecated.h>  // for IBrowserService2
#include <shlguid.h>

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

#include "base/metrics/histogram.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/win/scoped_bstr.h"
#include "base/win/scoped_comptr.h"
#include "base/win/scoped_variant.h"
#include "chrome/app/chrome_command_ids.h"
#include "chrome/common/url_constants.h"
#include "chrome_frame/chrome_frame_plugin.h"
#include "chrome_frame/chrome_tab.h"
#include "chrome_frame/com_message_event.h"
#include "chrome_frame/com_type_info_holder.h"
#include "chrome_frame/simple_resource_loader.h"
#include "chrome_frame/urlmon_url_request.h"
#include "chrome_frame/urlmon_url_request_private.h"
#include "chrome_frame/utils.h"
#include "grit/chrome_frame_resources.h"
#include "grit/generated_resources.h"
#include "net/cookies/cookie_monster.h"

// Connection point class to support firing IChromeFrameEvents (dispinterface).
template<class T>
class ATL_NO_VTABLE ProxyDIChromeFrameEvents
    : public IConnectionPointImpl<T, &DIID_DIChromeFrameEvents> {
 public:
  void FireMethodWithParams(ChromeFrameEventDispId dispid,
                            const VARIANT* params, size_t num_params) {
    T* me = static_cast<T*>(this);
    // We need to copy the whole vector and AddRef the sinks in case
    // some would get disconnected as we fire methods. Note that this is not
    // a threading issue, but a re-entrance issue, because the connection
    // can be affected by the implementation of the sinks receiving the event.
    me->Lock();
    std::vector< base::win::ScopedComPtr<IUnknown> > sink_array(
        m_vec.GetSize());
    for (int connection = 0; connection < m_vec.GetSize(); ++connection)
      sink_array[connection] = m_vec.GetAt(connection);
    me->Unlock();

    for (size_t sink = 0; sink < sink_array.size(); ++sink) {
      DIChromeFrameEvents* events =
          static_cast<DIChromeFrameEvents*>(sink_array[sink].get());
      if (events) {
        DISPPARAMS disp_params = {
            const_cast<VARIANT*>(params),
            NULL,
            num_params,
            0};
        HRESULT hr = events->Invoke(static_cast<DISPID>(dispid),
                                    DIID_DIChromeFrameEvents,
                                    LOCALE_USER_DEFAULT, DISPATCH_METHOD,
                                    &disp_params, NULL, NULL, NULL);
        DLOG_IF(ERROR, FAILED(hr)) << "invoke(" << dispid << ") failed" <<
            base::StringPrintf("0x%08X", hr);
      }
    }
  }

  void FireMethodWithParam(ChromeFrameEventDispId dispid,
                           const VARIANT& param) {
    FireMethodWithParams(dispid, &param, 1);
  }

  void Fire_onload(IDispatch* event) {
    VARIANT var = { VT_DISPATCH };
    var.pdispVal = event;
    FireMethodWithParam(CF_EVENT_DISPID_ONLOAD, var);
  }

  void Fire_onloaderror(IDispatch* event) {
    VARIANT var = { VT_DISPATCH };
    var.pdispVal = event;
    FireMethodWithParam(CF_EVENT_DISPID_ONLOADERROR, var);
  }

  void Fire_onmessage(IDispatch* event) {
    VARIANT var = { VT_DISPATCH };
    var.pdispVal = event;
    FireMethodWithParam(CF_EVENT_DISPID_ONMESSAGE, var);
  }

  void Fire_onreadystatechanged(long readystate) {  // NOLINT
    VARIANT var = { VT_I4 };
    var.lVal = readystate;
    FireMethodWithParam(CF_EVENT_DISPID_ONREADYSTATECHANGED, var);
  }

  void Fire_onprivatemessage(IDispatch* event, BSTR target) {
    // Arguments in reverse order to the function declaration, because
    // that's what DISPPARAMS requires.
    VARIANT args[2] = { { VT_BSTR, }, {VT_DISPATCH, } };
    args[0].bstrVal = target;
    args[1].pdispVal = event;

    FireMethodWithParams(CF_EVENT_DISPID_ONPRIVATEMESSAGE,
                         args,
                         arraysize(args));
  }

  void Fire_onchannelerror() {  // NOLINT
    FireMethodWithParams(CF_EVENT_DISPID_ONCHANNELERROR, NULL, 0);
  }

  void Fire_onclose() {  // NOLINT
    FireMethodWithParams(CF_EVENT_DISPID_ONCLOSE, NULL, 0);
  }
};

extern bool g_first_launch_by_process_;

namespace chrome_frame {
// Implemented outside this file so that the header doesn't include
// automation_messages.h.
std::string ActiveXCreateUrl(const GURL& parsed_url,
                             const AttachExternalTabParams& params);
int GetDisposition(const AttachExternalTabParams& params);
void GetMiniContextMenuData(UINT cmd,
                            const MiniContextMenuParams& params,
                            GURL* referrer,
                            GURL* url);
}  // namespace chrome_frame

// Common implementation for ActiveX and Active Document
template <class T, const CLSID& class_id>
class ATL_NO_VTABLE ChromeFrameActivexBase :  // NOLINT
  public CComObjectRootEx<CComMultiThreadModel>,
  public IOleControlImpl<T>,
  public IOleObjectImpl<T>,
  public IOleInPlaceActiveObjectImpl<T>,
  public IViewObjectExImpl<T>,
  public IOleInPlaceObjectWindowlessImpl<T>,
  public ISupportErrorInfo,
  public IQuickActivateImpl<T>,
  public com_util::IProvideClassInfo2Impl<class_id,
                                          DIID_DIChromeFrameEvents>,
  public com_util::IDispatchImpl<IChromeFrame>,
  public IConnectionPointContainerImpl<T>,
  public ProxyDIChromeFrameEvents<T>,
  public IPropertyNotifySinkCP<T>,
  public CComCoClass<T, &class_id>,
  public CComControl<T>,
  public ChromeFramePlugin<T> {
 protected:
  typedef std::set<base::win::ScopedComPtr<IDispatch> > EventHandlers;
  typedef ChromeFrameActivexBase<T, class_id> BasePlugin;

 public:
  ChromeFrameActivexBase()
      : ready_state_(READYSTATE_UNINITIALIZED),
      url_fetcher_(new UrlmonUrlRequestManager()),
      failed_to_fetch_in_place_frame_(false),
      draw_sad_tab_(false) {
    m_bWindowOnly = TRUE;
    url_fetcher_->set_container(static_cast<IDispatch*>(this));
  }

  ~ChromeFrameActivexBase() {
    url_fetcher_->set_container(NULL);
  }

DECLARE_OLEMISC_STATUS(OLEMISC_RECOMPOSEONRESIZE | OLEMISC_CANTLINKINSIDE |
                       OLEMISC_INSIDEOUT | OLEMISC_ACTIVATEWHENVISIBLE |
                       OLEMISC_SETCLIENTSITEFIRST)

DECLARE_NOT_AGGREGATABLE(T)

BEGIN_COM_MAP(ChromeFrameActivexBase)
  COM_INTERFACE_ENTRY(IChromeFrame)
  COM_INTERFACE_ENTRY(IDispatch)
  COM_INTERFACE_ENTRY(IViewObjectEx)
  COM_INTERFACE_ENTRY(IViewObject2)
  COM_INTERFACE_ENTRY(IViewObject)
  COM_INTERFACE_ENTRY(IOleInPlaceObjectWindowless)
  COM_INTERFACE_ENTRY(IOleInPlaceObject)
  COM_INTERFACE_ENTRY2(IOleWindow, IOleInPlaceObjectWindowless)
  COM_INTERFACE_ENTRY(IOleInPlaceActiveObject)
  COM_INTERFACE_ENTRY(IOleControl)
  COM_INTERFACE_ENTRY(IOleObject)
  COM_INTERFACE_ENTRY(ISupportErrorInfo)
  COM_INTERFACE_ENTRY(IQuickActivate)
  COM_INTERFACE_ENTRY(IProvideClassInfo)
  COM_INTERFACE_ENTRY(IProvideClassInfo2)
  COM_INTERFACE_ENTRY(IConnectionPointContainer)
  COM_INTERFACE_ENTRY_FUNC_BLIND(0, InterfaceNotSupported)
END_COM_MAP()

BEGIN_CONNECTION_POINT_MAP(T)
  CONNECTION_POINT_ENTRY(IID_IPropertyNotifySink)
  CONNECTION_POINT_ENTRY(DIID_DIChromeFrameEvents)
END_CONNECTION_POINT_MAP()

BEGIN_MSG_MAP(ChromeFrameActivexBase)
  MESSAGE_HANDLER(WM_CREATE, OnCreate)
  MESSAGE_HANDLER(WM_DOWNLOAD_IN_HOST, OnDownloadRequestInHost)
  MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
  CHAIN_MSG_MAP(ChromeFramePlugin<T>)
  CHAIN_MSG_MAP(CComControl<T>)
  DEFAULT_REFLECTION_HANDLER()
END_MSG_MAP()

  // IViewObjectEx
  DECLARE_VIEW_STATUS(VIEWSTATUS_SOLIDBKGND | VIEWSTATUS_OPAQUE)

  inline HRESULT IViewObject_Draw(DWORD draw_aspect, LONG index,
      void* aspect_info, DVTARGETDEVICE* ptd, HDC info_dc, HDC dc,
      LPCRECTL bounds, LPCRECTL win_bounds) {
    // ATL ASSERTs if dwDrawAspect is DVASPECT_DOCPRINT, so we cheat.
    DWORD aspect = draw_aspect;
    if (aspect == DVASPECT_DOCPRINT)
      aspect = DVASPECT_CONTENT;

    return CComControl<T>::IViewObject_Draw(aspect, index, aspect_info, ptd,
        info_dc, dc, bounds, win_bounds);
  }

  DECLARE_PROTECT_FINAL_CONSTRUCT()

  void SetResourceModule() {
    SimpleResourceLoader* loader_instance = SimpleResourceLoader::GetInstance();
    DCHECK(loader_instance);
    HMODULE res_dll = loader_instance->GetResourceModuleHandle();
    _AtlBaseModule.SetResourceInstance(res_dll);
  }

  HRESULT FinalConstruct() {
    SetResourceModule();

    if (!Initialize())
      return E_OUTOFMEMORY;

    // Set to true if this is the first launch by this process.
    // Used to perform one time tasks.
    if (g_first_launch_by_process_) {
      g_first_launch_by_process_ = false;
      UMA_HISTOGRAM_CUSTOM_COUNTS("ChromeFrame.IEVersion",
                                  GetIEVersion(),
                                  IE_INVALID,
                                  IE_10,
                                  IE_10 + 1);
    }

    return S_OK;
  }

  void FinalRelease() {
    Uninitialize();
  }

  void ResetUrlRequestManager() {
    url_fetcher_.reset(new UrlmonUrlRequestManager());
  }

  static HRESULT WINAPI InterfaceNotSupported(void* pv, REFIID riid, void** ppv,
                                              DWORD dw) {
#ifndef NDEBUG
    wchar_t buffer[64] = {0};
    ::StringFromGUID2(riid, buffer, arraysize(buffer));
    DVLOG(1) << "E_NOINTERFACE: " << buffer;
#endif
    return E_NOINTERFACE;
  }

  // ISupportsErrorInfo
  STDMETHOD(InterfaceSupportsErrorInfo)(REFIID riid) {
    static const IID* interfaces[] = {
      &IID_IChromeFrame,
      &IID_IDispatch
    };

    for (int i = 0; i < arraysize(interfaces); ++i) {
      if (InlineIsEqualGUID(*interfaces[i], riid))
        return S_OK;
    }
    return S_FALSE;
  }

  // Called to draw our control when chrome hasn't been initialized.
  virtual HRESULT OnDraw(ATL_DRAWINFO& draw_info) {  // NOLINT
    if (NULL == draw_info.prcBounds) {
      NOTREACHED();
      return E_FAIL;
    }

    if (draw_sad_tab_) {
      // TODO(tommi): Draw a proper sad tab.
      RECT rc = {0};
      if (draw_info.prcBounds) {
        rc.top = draw_info.prcBounds->top;
        rc.bottom = draw_info.prcBounds->bottom;
        rc.left = draw_info.prcBounds->left;
        rc.right = draw_info.prcBounds->right;
      } else {
        GetClientRect(&rc);
      }
      ::DrawTextA(draw_info.hdcDraw, ":-(", -1, &rc,
          DT_CENTER | DT_VCENTER | DT_SINGLELINE);
    } else {
      // Don't draw anything.
    }
    return S_OK;
  }

  // Used to setup the document_url_ member needed for completing navigation.
  // Create external tab (possibly in incognito mode).
  HRESULT IOleObject_SetClientSite(IOleClientSite* client_site) {
    // If we currently have a document site pointer, release it.
    doc_site_.Release();
    if (client_site) {
      doc_site_.QueryFrom(client_site);
    }

    if (client_site == NULL) {
      in_place_frame_.Release();
    }

    return CComControlBase::IOleObject_SetClientSite(client_site);
  }

  bool HandleContextMenuCommand(UINT cmd, const MiniContextMenuParams& params) {
    if (cmd == IDC_ABOUT_CHROME_FRAME) {
      int tab_handle = automation_client_->tab()->handle();
      HostNavigate(GURL("about:version"), GURL(), NEW_WINDOW);
      return true;
    } else {
      switch (cmd) {
        case IDS_CONTENT_CONTEXT_SAVEAUDIOAS:
        case IDS_CONTENT_CONTEXT_SAVEVIDEOAS:
        case IDS_CONTENT_CONTEXT_SAVEIMAGEAS:
        case IDS_CONTENT_CONTEXT_SAVELINKAS: {
          GURL referrer, url;
          chrome_frame::GetMiniContextMenuData(cmd, params, &referrer, &url);
          DoFileDownloadInIE(UTF8ToWide(url.spec()).c_str());
          return true;
        }

        case IDC_PRINT: {
          automation_client_->PrintTab();
          return true;
        }
      }
    }

    return false;
  }

  // Should connections initiated by this class try to block
  // responses served with the X-Frame-Options header?
  // ActiveX controls genereally will want to do this,
  // returning true, while true top-level documents
  // (ActiveDocument servers) will not. Your specialization
  // of this template should implement this method based on how
  // it "feels" from a security perspective. If it's hosted in another
  // scriptable document, return true, else false.
  //
  // The base implementation returns true unless we are in privileged
  // mode, in which case we always trust our container so we return false.
  bool is_frame_busting_enabled() const {
    return !is_privileged();
  }

  static void BringWebBrowserWindowToTop(IWebBrowser2* web_browser2) {
    DCHECK(web_browser2);
    if (web_browser2) {
      web_browser2->put_Visible(VARIANT_TRUE);
      HWND ie_window = NULL;
      web_browser2->get_HWND(reinterpret_cast<long*>(&ie_window));
      ::BringWindowToTop(ie_window);
    }
  }

 protected:
  virtual void GetProfilePath(const std::wstring& profile_name,
                              base::FilePath* profile_path) {
    bool is_IE = (lstrcmpi(profile_name.c_str(), kIexploreProfileName) == 0) ||
                 (lstrcmpi(profile_name.c_str(), kRundllProfileName) == 0);
    // Browsers without IDeleteBrowsingHistory in non-priv mode
    // have their profiles moved into "Temporary Internet Files".
    if (is_IE && GetIEVersion() < IE_8) {
      *profile_path = GetIETemporaryFilesFolder();
      *profile_path = profile_path->Append(L"Google Chrome Frame");
    } else {
      ChromeFramePlugin::GetProfilePath(profile_name, profile_path);
    }
    DVLOG(1) << __FUNCTION__ << ": " << profile_path->value();
  }

  void OnLoad(const GURL& url) {
    if (ready_state_ < READYSTATE_COMPLETE) {
      ready_state_ = READYSTATE_COMPLETE;
      FireOnChanged(DISPID_READYSTATE);
    }

    HRESULT hr = InvokeScriptFunction(onload_handler_, url.spec());
  }

  void OnLoadFailed(int error_code, const std::string& url) {
    HRESULT hr = InvokeScriptFunction(onerror_handler_, url);
  }

  void OnMessageFromChromeFrame(const std::string& message,
                                const std::string& origin,
                                const std::string& target) {
    base::win::ScopedComPtr<IDispatch> message_event;
    if (SUCCEEDED(CreateDomEvent("message", message, origin,
                                 message_event.Receive()))) {
      base::win::ScopedVariant event_var;
      event_var.Set(static_cast<IDispatch*>(message_event));
      InvokeScriptFunction(onmessage_handler_, event_var.AsInput());
    }
  }

  virtual void OnTabbedOut(bool reverse) {
    DCHECK(m_bInPlaceActive);

    HWND parent = ::GetParent(m_hWnd);
    ::SetFocus(parent);
    base::win::ScopedComPtr<IOleControlSite> control_site;
    control_site.QueryFrom(m_spClientSite);
    if (control_site)
      control_site->OnFocus(FALSE);
  }

  virtual void OnOpenURL(const GURL& url_to_open,
                         const GURL& referrer, int open_disposition) {
    HostNavigate(url_to_open, referrer, open_disposition);
  }

  // Called when Chrome has decided that a request needs to be treated as a
  // download.  The caller will be the UrlRequest worker thread.
  // The worker thread will block while we process the request and take
  // ownership of the request object.
  // There's room for improvement here and also see todo below.
  LPARAM OnDownloadRequestInHost(UINT message, WPARAM wparam, LPARAM lparam,
                                 BOOL& handled) {
    ChromeFrameUrl cf_url;
    cf_url.Parse(UTF8ToWide(GetDocumentUrl()));

    // Always issue the download request in a new window to ensure that the
    // currently loaded ChromeFrame document does not inadvartently see an
    // unload request. This runs javascript unload handlers on the page which
    // renders the page non functional.
    VARIANT flags = { VT_I4 };
    V_I4(&flags) = navNoHistory;
    if (!cf_url.attach_to_external_tab())
      V_I4(&flags) |= navOpenInNewWindow;

    DownloadInHostParams* download_params =
        reinterpret_cast<DownloadInHostParams*>(wparam);
    DCHECK(download_params);
    // TODO(tommi): It looks like we might have to switch the request object
    // into a pass-through request object and serve up any thus far received
    // content and headers to IE in order to prevent what can currently happen
    // which is reissuing requests and turning POST into GET.
    if (download_params->moniker) {
      NavigateBrowserToMoniker(
          doc_site_, download_params->moniker,
          UTF8ToWide(download_params->request_headers).c_str(),
          download_params->bind_ctx, NULL, download_params->post_data,
          &flags);
    }
    delete download_params;
    return TRUE;
  }

  virtual void OnAttachExternalTab(const AttachExternalTabParams& params) {
    GURL current_url(static_cast<BSTR>(url_));
    std::string url = chrome_frame::ActiveXCreateUrl(current_url, params);
    // Pass the current document url as the referrer for the new navigation.
    HostNavigate(GURL(url), current_url, chrome_frame::GetDisposition(params));
  }

  virtual void OnHandleContextMenu(const ContextMenuModel& menu_model,
                                   int align_flags,
                                   const MiniContextMenuParams& params) {
    scoped_refptr<BasePlugin> ref(this);
    ChromeFramePlugin<T>::OnHandleContextMenu(menu_model, align_flags, params);
  }

  LRESULT OnCreate(UINT message, WPARAM wparam, LPARAM lparam,
                   BOOL& handled) {  // NO_LINT
    ModifyStyle(0, WS_CLIPCHILDREN | WS_CLIPSIBLINGS, 0);
    url_fetcher_->put_notification_window(m_hWnd);
    if (automation_client_.get()) {
      automation_client_->SetParentWindow(m_hWnd);
    } else {
      NOTREACHED() << "No automation server";
      return -1;
    }
    // Only fire the 'interactive' ready state if we aren't there already.
    if (ready_state_ < READYSTATE_INTERACTIVE) {
      ready_state_ = READYSTATE_INTERACTIVE;
      FireOnChanged(DISPID_READYSTATE);
    }
    return 0;
  }

  LRESULT OnDestroy(UINT message, WPARAM wparam, LPARAM lparam,
                    BOOL& handled) {  // NO_LINT
    DVLOG(1) << __FUNCTION__;
    return 0;
  }

  // ChromeFrameDelegate override
  virtual void OnAutomationServerReady() {
    draw_sad_tab_ = false;
    ChromeFramePlugin<T>::OnAutomationServerReady();

    ready_state_ = READYSTATE_COMPLETE;
    FireOnChanged(DISPID_READYSTATE);
  }

  // ChromeFrameDelegate override
  virtual void OnAutomationServerLaunchFailed(
      AutomationLaunchResult reason, const std::string& server_version) {
    DVLOG(1) << __FUNCTION__;
    if (reason == AUTOMATION_SERVER_CRASHED)
      draw_sad_tab_ = true;

    ready_state_ = READYSTATE_UNINITIALIZED;
    FireOnChanged(DISPID_READYSTATE);
  }

  virtual void OnCloseTab() {
    Fire_onclose();
  }

  // Overridden to take advantage of readystate prop changes and send those
  // to potential listeners.
  HRESULT FireOnChanged(DISPID dispid) {
    if (dispid == DISPID_READYSTATE) {
      Fire_onreadystatechanged(ready_state_);
    }
    return __super::FireOnChanged(dispid);
  }

  // IChromeFrame
  // Property getter/setters for the src attribute, which contains a URL.
  // The ChromeFrameActivex control initiates navigation to this URL
  // when instantiated.
  STDMETHOD(get_src)(BSTR* src) {
    if (NULL == src) {
      return E_POINTER;
    }

    *src = SysAllocString(url_);
    return S_OK;
  }

  STDMETHOD(put_src)(BSTR src) {
    if (src == NULL)
      return E_INVALIDARG;

    // Switch the src to UTF8 and try to expand to full URL
    std::string src_utf8;
    WideToUTF8(src, SysStringLen(src), &src_utf8);
    std::string full_url = ResolveURL(GetDocumentUrl(), src_utf8);

    // We can initiate navigation here even if ready_state is not complete.
    // We do not have to set proxy, and AutomationClient will take care
    // of navigation just after CreateExternalTab is done.
    if (!automation_client_->InitiateNavigation(full_url,
                                                GetDocumentUrl(),
                                                this)) {
      // TODO(robertshield): Make InitiateNavigation return more useful
      // error information.
      return E_INVALIDARG;
    }

    // Save full URL in BSTR member
    url_.Reset(::SysAllocString(UTF8ToWide(full_url).c_str()));

    return S_OK;
  }

  STDMETHOD(get_onload)(VARIANT* onload_handler) {
    if (NULL == onload_handler)
      return E_INVALIDARG;

    *onload_handler = onload_handler_.Copy();

    return S_OK;
  }

  // Property setter for the onload attribute, which contains a
  // javascript function to be invoked on successful navigation.
  STDMETHOD(put_onload)(VARIANT onload_handler) {
    if (V_VT(&onload_handler) != VT_DISPATCH) {
      DLOG(WARNING) << "Invalid onload handler type: "
                    << onload_handler.vt
                    << " specified";
      return E_INVALIDARG;
    }

    onload_handler_ = onload_handler;

    return S_OK;
  }

  // Property getter/setters for the onloaderror attribute, which contains a
  // javascript function to be invoked on navigation failure.
  STDMETHOD(get_onloaderror)(VARIANT* onerror_handler) {
    if (NULL == onerror_handler)
      return E_INVALIDARG;

    *onerror_handler = onerror_handler_.Copy();

    return S_OK;
  }

  STDMETHOD(put_onloaderror)(VARIANT onerror_handler) {
    if (V_VT(&onerror_handler) != VT_DISPATCH) {
      DLOG(WARNING) << "Invalid onloaderror handler type: "
                    << onerror_handler.vt
                    << " specified";
      return E_INVALIDARG;
    }

    onerror_handler_ = onerror_handler;

    return S_OK;
  }

  // Property getter/setters for the onmessage attribute, which contains a
  // javascript function to be invoked when we receive a message from the
  // chrome frame.
  STDMETHOD(put_onmessage)(VARIANT onmessage_handler) {
    if (V_VT(&onmessage_handler) != VT_DISPATCH) {
      DLOG(WARNING) << "Invalid onmessage handler type: "
                    << onmessage_handler.vt
                    << " specified";
      return E_INVALIDARG;
    }

    onmessage_handler_ = onmessage_handler;

    return S_OK;
  }

  STDMETHOD(get_onmessage)(VARIANT* onmessage_handler) {
    if (NULL == onmessage_handler)
      return E_INVALIDARG;

    *onmessage_handler = onmessage_handler_.Copy();

    return S_OK;
  }

  STDMETHOD(get_readyState)(long* ready_state) {  // NOLINT
    DVLOG(1) << __FUNCTION__;
    DCHECK(ready_state);

    if (!ready_state)
      return E_INVALIDARG;

    *ready_state = ready_state_;

    return S_OK;
  }

  // Property getter/setters for use_chrome_network flag. This flag
  // indicates if chrome network stack is to be used for fetching
  // network requests.
  STDMETHOD(get_useChromeNetwork)(VARIANT_BOOL* use_chrome_network) {
    if (!use_chrome_network)
      return E_INVALIDARG;

    *use_chrome_network =
        automation_client_->use_chrome_network() ? VARIANT_TRUE : VARIANT_FALSE;
    return S_OK;
  }

  STDMETHOD(put_useChromeNetwork)(VARIANT_BOOL use_chrome_network) {
    if (!is_privileged()) {
      DLOG(ERROR) << "Attempt to set useChromeNetwork in non-privileged mode";
      return E_ACCESSDENIED;
    }

    automation_client_->set_use_chrome_network(
        (VARIANT_FALSE != use_chrome_network));
    return S_OK;
  }

  // Posts a message to the chrome frame.
  STDMETHOD(postMessage)(BSTR message, VARIANT target) {
    if (NULL == message) {
      return E_INVALIDARG;
    }

    if (!automation_client_.get())
      return E_FAIL;

    std::string utf8_target;
    if (target.vt == VT_BSTR) {
      int len = ::SysStringLen(target.bstrVal);
      if (len == 1 && target.bstrVal[0] == L'*') {
        utf8_target = "*";
      } else {
        GURL resolved(target.bstrVal);
        if (!resolved.is_valid()) {
          Error(L"Unable to parse the specified target URL.");
          return E_INVALIDARG;
        }

        utf8_target = resolved.spec();
      }
    } else {
      utf8_target = "*";
    }

    std::string utf8_message;
    WideToUTF8(message, ::SysStringLen(message), &utf8_message);

    GURL url(GURL(document_url_).GetOrigin());
    std::string origin(url.is_empty() ? "null" : url.spec());
    if (!automation_client_->ForwardMessageFromExternalHost(utf8_message,
                                                            origin,
                                                            utf8_target)) {
      Error(L"Failed to post message to chrome frame");
      return E_FAIL;
    }

    return S_OK;
  }

  STDMETHOD(addEventListener)(BSTR event_type, IDispatch* listener,
                              VARIANT use_capture) {
    EventHandlers* handlers = NULL;
    HRESULT hr = GetHandlersForEvent(event_type, &handlers);
    if (FAILED(hr))
      return hr;

    DCHECK(handlers != NULL);

    handlers->insert(base::win::ScopedComPtr<IDispatch>(listener));

    return hr;
  }

  STDMETHOD(removeEventListener)(BSTR event_type, IDispatch* listener,
                                 VARIANT use_capture) {
    EventHandlers* handlers = NULL;
    HRESULT hr = GetHandlersForEvent(event_type, &handlers);
    if (FAILED(hr))
      return hr;

    DCHECK(handlers != NULL);
    handlers->erase(base::win::ScopedComPtr<IDispatch>(listener));

    return hr;
  }

  STDMETHOD(get_version)(BSTR* version) {
    if (!automation_client_.get()) {
      NOTREACHED();
      return E_FAIL;
    }

    if (version == NULL) {
      return E_INVALIDARG;
    }

    *version = SysAllocString(automation_client_->GetVersion().c_str());
    return S_OK;
  }

  STDMETHOD(postPrivateMessage)(BSTR message, BSTR origin, BSTR target) {
    if (NULL == message)
      return E_INVALIDARG;

    if (!is_privileged()) {
      DLOG(ERROR) << "Attempt to postPrivateMessage in non-privileged mode";
      return E_ACCESSDENIED;
    }

    DCHECK(automation_client_.get());
    std::string utf8_message, utf8_origin, utf8_target;
    WideToUTF8(message, ::SysStringLen(message), &utf8_message);
    WideToUTF8(origin, ::SysStringLen(origin), &utf8_origin);
    WideToUTF8(target, ::SysStringLen(target), &utf8_target);

    if (!automation_client_->ForwardMessageFromExternalHost(utf8_message,
                                                            utf8_origin,
                                                            utf8_target)) {
      Error(L"Failed to post message to chrome frame");
      return E_FAIL;
    }

    return S_OK;
  }

  STDMETHOD(installExtension)(BSTR crx_path) {
    NOTREACHED();  // Deprecated.
    return E_NOTIMPL;
  }

  STDMETHOD(loadExtension)(BSTR path) {
    NOTREACHED();  // Deprecated.
    return E_NOTIMPL;
  }

  STDMETHOD(getEnabledExtensions)() {
    NOTREACHED();  // Deprecated.
    return E_NOTIMPL;
  }

  STDMETHOD(registerBhoIfNeeded)() {
    return E_NOTIMPL;
  }

  // Returns the vector of event handlers for a given event (e.g. "load").
  // If the event type isn't recognized, the function fills in a descriptive
  // error (IErrorInfo) and returns E_INVALIDARG.
  HRESULT GetHandlersForEvent(BSTR event_type, EventHandlers** handlers) {
    DCHECK(handlers != NULL);

    // TODO(tommi): make these if() statements data-driven.
    HRESULT hr = S_OK;
    const wchar_t* event_type_end = event_type + ::SysStringLen(event_type);
    if (LowerCaseEqualsASCII(event_type, event_type_end, "message")) {
      *handlers = &onmessage_;
    } else if (LowerCaseEqualsASCII(event_type, event_type_end, "load")) {
      *handlers = &onload_;
    } else if (LowerCaseEqualsASCII(event_type, event_type_end, "loaderror")) {
      *handlers = &onloaderror_;
    } else if (LowerCaseEqualsASCII(event_type, event_type_end,
                                    "readystatechanged")) {
      *handlers = &onreadystatechanged_;
    } else if (LowerCaseEqualsASCII(event_type, event_type_end,
                                    "privatemessage")) {
      // This event handler is only available in privileged mode.
      if (is_privileged()) {
        *handlers = &onprivatemessage_;
      } else {
        Error("Event type 'privatemessage' is privileged");
        hr = E_ACCESSDENIED;
      }
    } else if (LowerCaseEqualsASCII(event_type, event_type_end,
                                    "extensionready")) {
      // This event handler is only available in privileged mode.
      if (is_privileged()) {
        *handlers = &onextensionready_;
      } else {
        Error("Event type 'extensionready' is privileged");
        hr = E_ACCESSDENIED;
      }
    } else {
      Error(base::StringPrintf(
          "Event type '%ls' not found", event_type).c_str());
      hr = E_INVALIDARG;
    }

    return hr;
  }

  // Creates a new event object that supports the |data| property.
  // Note: you should supply an empty string for |origin| unless you're
  // creating a "message" event.
  HRESULT CreateDomEvent(const std::string& event_type, const std::string& data,
                         const std::string& origin, IDispatch** event) {
    DCHECK(event_type.length() > 0);  // NOLINT
    DCHECK(event != NULL);

    CComObject<ComMessageEvent>* ev = NULL;
    HRESULT hr = CComObject<ComMessageEvent>::CreateInstance(&ev);
    if (SUCCEEDED(hr)) {
      ev->AddRef();

      base::win::ScopedComPtr<IOleContainer> container;
      m_spClientSite->GetContainer(container.Receive());
      if (ev->Initialize(container, data, origin, event_type)) {
        *event = ev;
      } else {
        NOTREACHED() << "event->Initialize";
        ev->Release();
        hr = E_UNEXPECTED;
      }
    }

    return hr;
  }

  // Helper function to execute a function on a script IDispatch interface.
  HRESULT InvokeScriptFunction(const VARIANT& script_object,
                               const std::string& param) {
    base::win::ScopedVariant script_arg(UTF8ToWide(param.c_str()).c_str());
    return InvokeScriptFunction(script_object, script_arg.AsInput());
  }

  HRESULT InvokeScriptFunction(const VARIANT& script_object, VARIANT* param) {
    return InvokeScriptFunction(script_object, param, 1);
  }

  HRESULT InvokeScriptFunction(const VARIANT& script_object, VARIANT* params,
                               int param_count) {
    DCHECK_GE(param_count, 0);
    DCHECK(params);

    if (V_VT(&script_object) != VT_DISPATCH ||
        script_object.pdispVal == NULL) {
      return S_FALSE;
    }

    CComPtr<IDispatch> script(script_object.pdispVal);
    HRESULT hr = script.InvokeN(static_cast<DISPID>(DISPID_VALUE),
                                params,
                                param_count);
    // 0x80020101 == SCRIPT_E_REPORTED.
    // When the script we're invoking has an error, we get this error back.
    DLOG_IF(ERROR, FAILED(hr) && hr != 0x80020101) << "Failed to invoke script";
    return hr;
  }

  // Gives the browser a chance to handle an accelerator that was
  // sent to the out of proc chromium instance.
  // Returns S_OK iff the accelerator was handled by the browser.
  HRESULT AllowFrameToTranslateAccelerator(const MSG& msg) {
    static const int kMayTranslateAcceleratorOffset = 0x5c;
    // Although IBrowserService2 is officially deprecated, it's still alive
    // and well in IE7 and earlier.  We have to use it here to correctly give
    // the browser a chance to handle keyboard shortcuts.
    // This happens automatically for activex components that have windows that
    // belong to the current thread.  In that circumstance IE owns the message
    // loop and can walk the line of components allowing each participant the
    // chance to handle the keystroke and eventually falls back to
    // v_MayTranslateAccelerator.  However in our case, the message loop is
    // owned by the out-of-proc chromium instance so IE doesn't have a chance to
    // fall back on its default behavior.  Instead we give IE a chance to
    // handle the shortcut here.
    MSG accel_message = msg;
    accel_message.hwnd = ::GetParent(m_hWnd);
    HRESULT hr = S_FALSE;
    base::win::ScopedComPtr<IBrowserService2> bs2;

    // For non-IE containers, we use the standard IOleInPlaceFrame contract
    // (which IE does not support). For IE, we try to use IBrowserService2,
    // but need special handling for IE8 (see below).
    //
    // We try to cache an IOleInPlaceFrame for our site.  If we fail, we don't
    // retry, and we fall back to the IBrowserService2 and PostMessage
    // approaches below.
    if (!in_place_frame_ && !failed_to_fetch_in_place_frame_) {
      base::win::ScopedComPtr<IOleInPlaceUIWindow> dummy_ui_window;
      RECT dummy_pos_rect = {0};
      RECT dummy_clip_rect = {0};
      OLEINPLACEFRAMEINFO dummy_frame_info = {0};
      if (!m_spInPlaceSite ||
          FAILED(m_spInPlaceSite->GetWindowContext(in_place_frame_.Receive(),
                                                   dummy_ui_window.Receive(),
                                                   &dummy_pos_rect,
                                                   &dummy_clip_rect,
                                                   &dummy_frame_info))) {
        failed_to_fetch_in_place_frame_ = true;
      }
    }

    // The IBrowserService2 code below (second conditional) explicitly checks
    // for whether the IBrowserService2::v_MayTranslateAccelerator function is
    // valid. On IE8 there is one vtable ieframe!c_ImpostorBrowserService2Vtbl
    // where this function entry is NULL which leads to a crash. We don't know
    // under what circumstances this vtable is actually used though.
    if (in_place_frame_) {
      hr = in_place_frame_->TranslateAccelerator(&accel_message, 0);
    } else if (S_OK == DoQueryService(
        SID_STopLevelBrowser, m_spInPlaceSite,
        bs2.Receive()) && bs2.get() &&
        *(*(reinterpret_cast<void***>(bs2.get())) +
        kMayTranslateAcceleratorOffset)) {
      hr = bs2->v_MayTranslateAccelerator(&accel_message);
    } else {
      // IE8 doesn't support IBrowserService2 unless you enable a special,
      // undocumented flag with CoInternetSetFeatureEnabled and even then,
      // the object you get back implements only a couple of methods of
      // that interface... all the other entries in the vtable are NULL.
      // In addition, the class that implements it is called
      // ImpostorBrowserService2 :)
      // IE8 does have a new interface though, presumably called
      // ITabBrowserService or something that can be abbreviated to TBS.
      // That interface has a method, TranslateAcceleratorTBS that does
      // call the root MayTranslateAccelerator function, but alas the
      // first argument to MayTranslateAccelerator is hard coded to FALSE
      // which means that global accelerators are not handled and we're
      // out of luck.
      // A third thing that's notable with regards to IE8 is that
      // none of the *MayTranslate* functions exist in a vtable inside
      // ieframe.dll.  I checked this by scanning for the address of
      // those functions inside the dll and found none, which means that
      // all calls to those functions are relative.
      // So, for IE8 in certain cases, and for other containers that may
      // support neither IOleInPlaceFrame or IBrowserService2 our approach
      // is very simple.  Just post the message to our parent window and IE
      // will pick it up if it's an accelerator. We won't know for sure if
      // the browser handled the keystroke or not.
      ::PostMessage(accel_message.hwnd, accel_message.message,
                    accel_message.wParam, accel_message.lParam);
    }

    return hr;
  }

  virtual void OnAcceleratorPressed(const MSG& accel_message) {
    DCHECK(m_spInPlaceSite != NULL);
    // Allow our host a chance to handle the accelerator.
    // This catches things like Ctrl+F, Ctrl+O etc, but not browser
    // accelerators such as F11, Ctrl+T etc.
    // (see AllowFrameToTranslateAccelerator for those).
    HRESULT hr = TranslateAccelerator(const_cast<MSG*>(&accel_message));
    if (hr != S_OK)
      hr = AllowFrameToTranslateAccelerator(accel_message);

    DVLOG(1) << __FUNCTION__ << " browser response: "
             << base::StringPrintf("0x%08x", hr);

    if (hr != S_OK) {
      // The WM_SYSKEYDOWN/WM_SYSKEYUP messages are not processed by the
      // IOleControlSite and IBrowserService2::v_MayTranslateAccelerator
      // implementations. We need to understand this better. That is for
      // another day. For now we just post these messages back to the parent
      // which forwards it off to the frame. This should not cause major
      // grief for Chrome as it does not need to handle WM_SYSKEY* messages in
      // in ChromeFrame mode.
      // TODO(iyengar)
      // Understand and fix WM_SYSCHAR handling
      // We should probably unify the accelerator handling for the active
      // document and the activex.
      if (accel_message.message == WM_SYSCHAR ||
          accel_message.message == WM_SYSKEYDOWN ||
          accel_message.message == WM_SYSKEYUP) {
        ::PostMessage(GetParent(), accel_message.message, accel_message.wParam,
                      accel_message.lParam);
        return;
      }
    }
    // Last chance to handle the keystroke is to pass it to chromium.
    // We do this last partially because there's no way for us to tell if
    // chromium actually handled the keystroke, but also since the browser
    // should have first dibs anyway.
    if (hr != S_OK && automation_client_.get()) {
      TabProxy* tab = automation_client_->tab();
      if (tab) {
        tab->ProcessUnhandledAccelerator(accel_message);
      }
    }
  }

 protected:
  void HostNavigate(const GURL& url_to_open,
                    const GURL& referrer, int open_disposition) {
    base::win::ScopedComPtr<IWebBrowser2> web_browser2;
    DoQueryService(SID_SWebBrowserApp, m_spClientSite, web_browser2.Receive());
    if (!web_browser2) {
      NOTREACHED() << "Failed to retrieve IWebBrowser2 interface";
      return;
    }
    base::win::ScopedVariant url;
    // Check to see if the URL uses a "view-source:" prefix, if so, open it
    // using chrome frame full tab mode by using 'cf:' protocol handler.
    // Also change the disposition to NEW_WINDOW since IE6 doesn't have tabs.
    if (url_to_open.has_scheme() &&
        (url_to_open.SchemeIs(content::kViewSourceScheme) ||
        url_to_open.SchemeIs(chrome::kAboutScheme))) {
      std::wstring chrome_url;
      chrome_url.append(kChromeProtocolPrefix);
      chrome_url.append(UTF8ToWide(url_to_open.spec()));
      url.Set(chrome_url.c_str());
      open_disposition = NEW_WINDOW;
    } else {
      url.Set(UTF8ToWide(url_to_open.spec()).c_str());
    }

    VARIANT flags = { VT_I4 };
    V_I4(&flags) = 0;

    IEVersion ie_version = GetIEVersion();
    DCHECK(ie_version != NON_IE && ie_version != IE_UNSUPPORTED);
    // Since IE6 doesn't support tabs, so we just use window instead.
    if (ie_version == IE_6) {
      if (open_disposition == NEW_FOREGROUND_TAB ||
          open_disposition == NEW_BACKGROUND_TAB ||
          open_disposition == NEW_WINDOW ||
          open_disposition == NEW_POPUP) {
        V_I4(&flags) = navOpenInNewWindow;
      } else if (open_disposition != CURRENT_TAB) {
        NOTREACHED() << "Unsupported open disposition in IE6";
      }
    } else {
      switch (open_disposition) {
        case NEW_FOREGROUND_TAB:
          V_I4(&flags) = navOpenInNewTab;
          break;
        case NEW_BACKGROUND_TAB:
          V_I4(&flags) = navOpenInBackgroundTab;
          break;
        case NEW_WINDOW:
        case NEW_POPUP:
          V_I4(&flags) = navOpenInNewWindow;
          break;
        default:
          break;
      }
    }

    // TODO(sanjeevr): The navOpenInNewWindow flag causes IE to open this
    // in a new window ONLY if the user has specified
    // "Always open popups in a new window". Otherwise it opens in a new tab.
    // We need to investigate more and see if we can force IE to display the
    // link in a new window. MSHTML uses the below code to force an open in a
    // new window. But this logic also fails for us. Perhaps this flag is not
    // honoured if the ActiveDoc is not MSHTML.
    // Even the HLNF_DISABLEWINDOWRESTRICTIONS flag did not work.
    // Start of MSHTML-like logic.
    // CComQIPtr<ITargetFramePriv2> target_frame = web_browser2;
    // if (target_frame) {
    //   CComPtr<IUri> uri;
    //   CreateUri(UTF8ToWide(open_url_command->url_.spec()).c_str(),
    //             Uri_CREATE_IE_SETTINGS, 0, &uri);
    //   CComPtr<IBindCtx> bind_ctx;
    //   CreateBindCtx(0, &bind_ctx);
    //   target_frame->AggregatedNavigation2(
    //       HLNF_TRUSTFIRSTDOWNLOAD|HLNF_OPENINNEWWINDOW, bind_ctx, NULL,
    //       L"No_Name", uri, L"");
    // }
    // End of MSHTML-like logic
    VARIANT empty = base::win::ScopedVariant::kEmptyVariant;
    base::win::ScopedVariant http_headers;

    if (referrer.is_valid()) {
      std::wstring referrer_header = L"Referer: ";
      referrer_header += UTF8ToWide(referrer.spec());
      referrer_header += L"\r\n\r\n";
      http_headers.Set(referrer_header.c_str());
    }

    // IE6 does not support tabs. If Chrome sent us a window open request
    // indicating that the navigation needs to occur in a foreground tab or
    // a popup window, then we need to ensure that the new window in IE6 is
    // brought to the foreground.
    if (ie_version == IE_6) {
      ChromeFrameUrl cf_url;
      cf_url.Parse(static_cast<BSTR>(url_));

      if (cf_url.attach_to_external_tab() &&
          (cf_url.disposition() == NEW_FOREGROUND_TAB ||
           cf_url.disposition() == NEW_POPUP)) {
        BringWebBrowserWindowToTop(web_browser2);
      }
    }

    HRESULT hr = web_browser2->Navigate2(url.AsInput(), &flags, &empty, &empty,
                                         http_headers.AsInput());
    // If the current window is a popup window then attempting to open a new
    // tab for the navigation will fail. We attempt to issue the navigation in
    // a new window in this case.
    // http://msdn.microsoft.com/en-us/library/aa752133(v=vs.85).aspx
    if (FAILED(hr) && V_I4(&flags) != navOpenInNewWindow) {
      V_I4(&flags) = navOpenInNewWindow;
      hr = web_browser2->Navigate2(url.AsInput(), &flags, &empty, &empty,
                                   http_headers.AsInput());
      DLOG_IF(ERROR, FAILED(hr))
          << "Navigate2 failed with error: "
          << base::StringPrintf("0x%08X", hr);
    }
  }

  void InitializeAutomationSettings() {
    static const wchar_t kHandleTopLevelRequests[] = L"HandleTopLevelRequests";
    static const wchar_t kUseChromeNetworking[] = L"UseChromeNetworking";

    // Query and assign the top-level-request routing, and host networking
    // settings from the registry.
    bool top_level_requests = GetConfigBool(true, kHandleTopLevelRequests);
    bool chrome_network = GetConfigBool(false, kUseChromeNetworking);
    automation_client_->set_handle_top_level_requests(top_level_requests);
    automation_client_->set_use_chrome_network(chrome_network);
  }

  base::win::ScopedBstr url_;
  base::win::ScopedComPtr<IOleDocumentSite> doc_site_;

  // If false, we tried but failed to fetch an IOleInPlaceFrame from our host.
  // Cached here so we don't try to fetch it every time if we keep failing.
  bool failed_to_fetch_in_place_frame_;
  bool draw_sad_tab_;

  base::win::ScopedComPtr<IOleInPlaceFrame> in_place_frame_;

  // For more information on the ready_state_ property see:
  // http://msdn.microsoft.com/en-us/library/aa768179(VS.85).aspx#
  READYSTATE ready_state_;

  // The following members contain IDispatch interfaces representing the
  // onload/onerror/onmessage handlers on the page.
  base::win::ScopedVariant onload_handler_;
  base::win::ScopedVariant onerror_handler_;
  base::win::ScopedVariant onmessage_handler_;

  EventHandlers onmessage_;
  EventHandlers onloaderror_;
  EventHandlers onload_;
  EventHandlers onreadystatechanged_;
  EventHandlers onprivatemessage_;
  EventHandlers onextensionready_;

  // Handle network requests when host network stack is used. Passed to the
  // automation client on initialization.
  scoped_ptr<UrlmonUrlRequestManager> url_fetcher_;
};

#endif  // CHROME_FRAME_CHROME_FRAME_ACTIVEX_BASE_H_
