15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef CHROME_FRAME_CHROME_FRAME_ACTIVEX_BASE_H_
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CHROME_FRAME_CHROME_FRAME_ACTIVEX_BASE_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <atlbase.h>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <atlcom.h>
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <atlctl.h>
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <exdisp.h>
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <wininet.h>
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <shdeprecated.h>  // for IBrowserService2
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <shlguid.h>
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <set>
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector>
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/metrics/histogram.h"
21868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h"
22868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h"
23868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/win/scoped_bstr.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/win/scoped_comptr.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/win/scoped_variant.h"
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/app/chrome_command_ids.h"
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/url_constants.h"
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome_frame/chrome_frame_plugin.h"
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome_frame/chrome_tab.h"
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome_frame/com_message_event.h"
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome_frame/com_type_info_holder.h"
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome_frame/simple_resource_loader.h"
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome_frame/urlmon_url_request.h"
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome_frame/urlmon_url_request_private.h"
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome_frame/utils.h"
37868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "grit/chrome_frame_resources.h"
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/generated_resources.h"
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/cookies/cookie_monster.h"
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Connection point class to support firing IChromeFrameEvents (dispinterface).
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<class T>
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ATL_NO_VTABLE ProxyDIChromeFrameEvents
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : public IConnectionPointImpl<T, &DIID_DIChromeFrameEvents> {
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void FireMethodWithParams(ChromeFrameEventDispId dispid,
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            const VARIANT* params, size_t num_params) {
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    T* me = static_cast<T*>(this);
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We need to copy the whole vector and AddRef the sinks in case
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // some would get disconnected as we fire methods. Note that this is not
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // a threading issue, but a re-entrance issue, because the connection
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // can be affected by the implementation of the sinks receiving the event.
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    me->Lock();
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::vector< base::win::ScopedComPtr<IUnknown> > sink_array(
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        m_vec.GetSize());
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (int connection = 0; connection < m_vec.GetSize(); ++connection)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sink_array[connection] = m_vec.GetAt(connection);
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    me->Unlock();
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (size_t sink = 0; sink < sink_array.size(); ++sink) {
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DIChromeFrameEvents* events =
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          static_cast<DIChromeFrameEvents*>(sink_array[sink].get());
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (events) {
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        DISPPARAMS disp_params = {
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            const_cast<VARIANT*>(params),
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            NULL,
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            num_params,
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            0};
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        HRESULT hr = events->Invoke(static_cast<DISPID>(dispid),
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    DIID_DIChromeFrameEvents,
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    LOCALE_USER_DEFAULT, DISPATCH_METHOD,
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    &disp_params, NULL, NULL, NULL);
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        DLOG_IF(ERROR, FAILED(hr)) << "invoke(" << dispid << ") failed" <<
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            base::StringPrintf("0x%08X", hr);
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void FireMethodWithParam(ChromeFrameEventDispId dispid,
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           const VARIANT& param) {
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FireMethodWithParams(dispid, &param, 1);
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Fire_onload(IDispatch* event) {
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    VARIANT var = { VT_DISPATCH };
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    var.pdispVal = event;
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FireMethodWithParam(CF_EVENT_DISPID_ONLOAD, var);
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Fire_onloaderror(IDispatch* event) {
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    VARIANT var = { VT_DISPATCH };
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    var.pdispVal = event;
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FireMethodWithParam(CF_EVENT_DISPID_ONLOADERROR, var);
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Fire_onmessage(IDispatch* event) {
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    VARIANT var = { VT_DISPATCH };
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    var.pdispVal = event;
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FireMethodWithParam(CF_EVENT_DISPID_ONMESSAGE, var);
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Fire_onreadystatechanged(long readystate) {  // NOLINT
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    VARIANT var = { VT_I4 };
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    var.lVal = readystate;
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FireMethodWithParam(CF_EVENT_DISPID_ONREADYSTATECHANGED, var);
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Fire_onprivatemessage(IDispatch* event, BSTR target) {
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Arguments in reverse order to the function declaration, because
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // that's what DISPPARAMS requires.
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    VARIANT args[2] = { { VT_BSTR, }, {VT_DISPATCH, } };
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    args[0].bstrVal = target;
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    args[1].pdispVal = event;
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FireMethodWithParams(CF_EVENT_DISPID_ONPRIVATEMESSAGE,
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         args,
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         arraysize(args));
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Fire_onchannelerror() {  // NOLINT
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FireMethodWithParams(CF_EVENT_DISPID_ONCHANNELERROR, NULL, 0);
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Fire_onclose() {  // NOLINT
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FireMethodWithParams(CF_EVENT_DISPID_ONCLOSE, NULL, 0);
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern bool g_first_launch_by_process_;
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace chrome_frame {
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Implemented outside this file so that the header doesn't include
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// automation_messages.h.
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string ActiveXCreateUrl(const GURL& parsed_url,
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             const AttachExternalTabParams& params);
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int GetDisposition(const AttachExternalTabParams& params);
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GetMiniContextMenuData(UINT cmd,
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            const MiniContextMenuParams& params,
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            GURL* referrer,
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            GURL* url);
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace chrome_frame
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Common implementation for ActiveX and Active Document
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <class T, const CLSID& class_id>
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ATL_NO_VTABLE ChromeFrameActivexBase :  // NOLINT
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  public CComObjectRootEx<CComMultiThreadModel>,
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  public IOleControlImpl<T>,
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  public IOleObjectImpl<T>,
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  public IOleInPlaceActiveObjectImpl<T>,
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  public IViewObjectExImpl<T>,
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  public IOleInPlaceObjectWindowlessImpl<T>,
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  public ISupportErrorInfo,
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  public IQuickActivateImpl<T>,
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  public com_util::IProvideClassInfo2Impl<class_id,
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                          DIID_DIChromeFrameEvents>,
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  public com_util::IDispatchImpl<IChromeFrame>,
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  public IConnectionPointContainerImpl<T>,
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  public ProxyDIChromeFrameEvents<T>,
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  public IPropertyNotifySinkCP<T>,
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  public CComCoClass<T, &class_id>,
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  public CComControl<T>,
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  public ChromeFramePlugin<T> {
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef std::set<base::win::ScopedComPtr<IDispatch> > EventHandlers;
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef ChromeFrameActivexBase<T, class_id> BasePlugin;
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ChromeFrameActivexBase()
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : ready_state_(READYSTATE_UNINITIALIZED),
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url_fetcher_(new UrlmonUrlRequestManager()),
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      failed_to_fetch_in_place_frame_(false),
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      draw_sad_tab_(false) {
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    m_bWindowOnly = TRUE;
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    url_fetcher_->set_container(static_cast<IDispatch*>(this));
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~ChromeFrameActivexBase() {
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    url_fetcher_->set_container(NULL);
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DECLARE_OLEMISC_STATUS(OLEMISC_RECOMPOSEONRESIZE | OLEMISC_CANTLINKINSIDE |
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       OLEMISC_INSIDEOUT | OLEMISC_ACTIVATEWHENVISIBLE |
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       OLEMISC_SETCLIENTSITEFIRST)
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DECLARE_NOT_AGGREGATABLE(T)
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BEGIN_COM_MAP(ChromeFrameActivexBase)
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COM_INTERFACE_ENTRY(IChromeFrame)
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COM_INTERFACE_ENTRY(IDispatch)
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COM_INTERFACE_ENTRY(IViewObjectEx)
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COM_INTERFACE_ENTRY(IViewObject2)
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COM_INTERFACE_ENTRY(IViewObject)
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COM_INTERFACE_ENTRY(IOleInPlaceObjectWindowless)
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COM_INTERFACE_ENTRY(IOleInPlaceObject)
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COM_INTERFACE_ENTRY2(IOleWindow, IOleInPlaceObjectWindowless)
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COM_INTERFACE_ENTRY(IOleInPlaceActiveObject)
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COM_INTERFACE_ENTRY(IOleControl)
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COM_INTERFACE_ENTRY(IOleObject)
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COM_INTERFACE_ENTRY(ISupportErrorInfo)
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COM_INTERFACE_ENTRY(IQuickActivate)
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COM_INTERFACE_ENTRY(IProvideClassInfo)
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COM_INTERFACE_ENTRY(IProvideClassInfo2)
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COM_INTERFACE_ENTRY(IConnectionPointContainer)
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COM_INTERFACE_ENTRY_FUNC_BLIND(0, InterfaceNotSupported)
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)END_COM_MAP()
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BEGIN_CONNECTION_POINT_MAP(T)
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CONNECTION_POINT_ENTRY(IID_IPropertyNotifySink)
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CONNECTION_POINT_ENTRY(DIID_DIChromeFrameEvents)
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)END_CONNECTION_POINT_MAP()
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BEGIN_MSG_MAP(ChromeFrameActivexBase)
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MESSAGE_HANDLER(WM_CREATE, OnCreate)
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MESSAGE_HANDLER(WM_DOWNLOAD_IN_HOST, OnDownloadRequestInHost)
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHAIN_MSG_MAP(ChromeFramePlugin<T>)
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHAIN_MSG_MAP(CComControl<T>)
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DEFAULT_REFLECTION_HANDLER()
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)END_MSG_MAP()
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // IViewObjectEx
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DECLARE_VIEW_STATUS(VIEWSTATUS_SOLIDBKGND | VIEWSTATUS_OPAQUE)
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inline HRESULT IViewObject_Draw(DWORD draw_aspect, LONG index,
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      void* aspect_info, DVTARGETDEVICE* ptd, HDC info_dc, HDC dc,
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LPCRECTL bounds, LPCRECTL win_bounds) {
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // ATL ASSERTs if dwDrawAspect is DVASPECT_DOCPRINT, so we cheat.
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DWORD aspect = draw_aspect;
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (aspect == DVASPECT_DOCPRINT)
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      aspect = DVASPECT_CONTENT;
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return CComControl<T>::IViewObject_Draw(aspect, index, aspect_info, ptd,
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        info_dc, dc, bounds, win_bounds);
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DECLARE_PROTECT_FINAL_CONSTRUCT()
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetResourceModule() {
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SimpleResourceLoader* loader_instance = SimpleResourceLoader::GetInstance();
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(loader_instance);
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HMODULE res_dll = loader_instance->GetResourceModuleHandle();
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    _AtlBaseModule.SetResourceInstance(res_dll);
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HRESULT FinalConstruct() {
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SetResourceModule();
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!Initialize())
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return E_OUTOFMEMORY;
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Set to true if this is the first launch by this process.
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Used to perform one time tasks.
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (g_first_launch_by_process_) {
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      g_first_launch_by_process_ = false;
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      UMA_HISTOGRAM_CUSTOM_COUNTS("ChromeFrame.IEVersion",
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  GetIEVersion(),
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  IE_INVALID,
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  IE_10,
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  IE_10 + 1);
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return S_OK;
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void FinalRelease() {
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Uninitialize();
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ResetUrlRequestManager() {
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    url_fetcher_.reset(new UrlmonUrlRequestManager());
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static HRESULT WINAPI InterfaceNotSupported(void* pv, REFIID riid, void** ppv,
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              DWORD dw) {
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef NDEBUG
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    wchar_t buffer[64] = {0};
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ::StringFromGUID2(riid, buffer, arraysize(buffer));
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DVLOG(1) << "E_NOINTERFACE: " << buffer;
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return E_NOINTERFACE;
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ISupportsErrorInfo
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  STDMETHOD(InterfaceSupportsErrorInfo)(REFIID riid) {
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    static const IID* interfaces[] = {
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &IID_IChromeFrame,
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &IID_IDispatch
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (int i = 0; i < arraysize(interfaces); ++i) {
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (InlineIsEqualGUID(*interfaces[i], riid))
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return S_OK;
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return S_FALSE;
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called to draw our control when chrome hasn't been initialized.
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual HRESULT OnDraw(ATL_DRAWINFO& draw_info) {  // NOLINT
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (NULL == draw_info.prcBounds) {
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED();
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return E_FAIL;
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (draw_sad_tab_) {
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // TODO(tommi): Draw a proper sad tab.
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      RECT rc = {0};
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (draw_info.prcBounds) {
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        rc.top = draw_info.prcBounds->top;
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        rc.bottom = draw_info.prcBounds->bottom;
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        rc.left = draw_info.prcBounds->left;
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        rc.right = draw_info.prcBounds->right;
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      } else {
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        GetClientRect(&rc);
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ::DrawTextA(draw_info.hdcDraw, ":-(", -1, &rc,
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          DT_CENTER | DT_VCENTER | DT_SINGLELINE);
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Don't draw anything.
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return S_OK;
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Used to setup the document_url_ member needed for completing navigation.
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create external tab (possibly in incognito mode).
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HRESULT IOleObject_SetClientSite(IOleClientSite* client_site) {
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // If we currently have a document site pointer, release it.
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    doc_site_.Release();
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (client_site) {
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      doc_site_.QueryFrom(client_site);
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (client_site == NULL) {
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      in_place_frame_.Release();
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return CComControlBase::IOleObject_SetClientSite(client_site);
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool HandleContextMenuCommand(UINT cmd, const MiniContextMenuParams& params) {
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (cmd == IDC_ABOUT_CHROME_FRAME) {
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      int tab_handle = automation_client_->tab()->handle();
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HostNavigate(GURL("about:version"), GURL(), NEW_WINDOW);
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      switch (cmd) {
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case IDS_CONTENT_CONTEXT_SAVEAUDIOAS:
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case IDS_CONTENT_CONTEXT_SAVEVIDEOAS:
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case IDS_CONTENT_CONTEXT_SAVEIMAGEAS:
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case IDS_CONTENT_CONTEXT_SAVELINKAS: {
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          GURL referrer, url;
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          chrome_frame::GetMiniContextMenuData(cmd, params, &referrer, &url);
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          DoFileDownloadInIE(UTF8ToWide(url.spec()).c_str());
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          return true;
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case IDC_PRINT: {
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          automation_client_->PrintTab();
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          return true;
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Should connections initiated by this class try to block
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // responses served with the X-Frame-Options header?
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ActiveX controls genereally will want to do this,
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // returning true, while true top-level documents
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // (ActiveDocument servers) will not. Your specialization
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // of this template should implement this method based on how
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // it "feels" from a security perspective. If it's hosted in another
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // scriptable document, return true, else false.
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The base implementation returns true unless we are in privileged
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // mode, in which case we always trust our container so we return false.
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool is_frame_busting_enabled() const {
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return !is_privileged();
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void BringWebBrowserWindowToTop(IWebBrowser2* web_browser2) {
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(web_browser2);
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (web_browser2) {
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      web_browser2->put_Visible(VARIANT_TRUE);
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HWND ie_window = NULL;
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      web_browser2->get_HWND(reinterpret_cast<long*>(&ie_window));
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ::BringWindowToTop(ie_window);
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void GetProfilePath(const std::wstring& profile_name,
3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              base::FilePath* profile_path) {
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool is_IE = (lstrcmpi(profile_name.c_str(), kIexploreProfileName) == 0) ||
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 (lstrcmpi(profile_name.c_str(), kRundllProfileName) == 0);
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Browsers without IDeleteBrowsingHistory in non-priv mode
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // have their profiles moved into "Temporary Internet Files".
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (is_IE && GetIEVersion() < IE_8) {
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *profile_path = GetIETemporaryFilesFolder();
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *profile_path = profile_path->Append(L"Google Chrome Frame");
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ChromeFramePlugin::GetProfilePath(profile_name, profile_path);
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DVLOG(1) << __FUNCTION__ << ": " << profile_path->value();
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnLoad(const GURL& url) {
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ready_state_ < READYSTATE_COMPLETE) {
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ready_state_ = READYSTATE_COMPLETE;
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FireOnChanged(DISPID_READYSTATE);
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HRESULT hr = InvokeScriptFunction(onload_handler_, url.spec());
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnLoadFailed(int error_code, const std::string& url) {
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HRESULT hr = InvokeScriptFunction(onerror_handler_, url);
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnMessageFromChromeFrame(const std::string& message,
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                const std::string& origin,
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                const std::string& target) {
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::win::ScopedComPtr<IDispatch> message_event;
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (SUCCEEDED(CreateDomEvent("message", message, origin,
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 message_event.Receive()))) {
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::win::ScopedVariant event_var;
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      event_var.Set(static_cast<IDispatch*>(message_event));
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      InvokeScriptFunction(onmessage_handler_, event_var.AsInput());
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnTabbedOut(bool reverse) {
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(m_bInPlaceActive);
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HWND parent = ::GetParent(m_hWnd);
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ::SetFocus(parent);
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::win::ScopedComPtr<IOleControlSite> control_site;
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    control_site.QueryFrom(m_spClientSite);
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (control_site)
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      control_site->OnFocus(FALSE);
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnOpenURL(const GURL& url_to_open,
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         const GURL& referrer, int open_disposition) {
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HostNavigate(url_to_open, referrer, open_disposition);
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called when Chrome has decided that a request needs to be treated as a
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // download.  The caller will be the UrlRequest worker thread.
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The worker thread will block while we process the request and take
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ownership of the request object.
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // There's room for improvement here and also see todo below.
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LPARAM OnDownloadRequestInHost(UINT message, WPARAM wparam, LPARAM lparam,
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 BOOL& handled) {
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ChromeFrameUrl cf_url;
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cf_url.Parse(UTF8ToWide(GetDocumentUrl()));
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Always issue the download request in a new window to ensure that the
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // currently loaded ChromeFrame document does not inadvartently see an
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // unload request. This runs javascript unload handlers on the page which
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // renders the page non functional.
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    VARIANT flags = { VT_I4 };
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    V_I4(&flags) = navNoHistory;
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!cf_url.attach_to_external_tab())
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      V_I4(&flags) |= navOpenInNewWindow;
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DownloadInHostParams* download_params =
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        reinterpret_cast<DownloadInHostParams*>(wparam);
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(download_params);
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // TODO(tommi): It looks like we might have to switch the request object
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // into a pass-through request object and serve up any thus far received
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // content and headers to IE in order to prevent what can currently happen
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // which is reissuing requests and turning POST into GET.
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (download_params->moniker) {
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NavigateBrowserToMoniker(
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          doc_site_, download_params->moniker,
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          UTF8ToWide(download_params->request_headers).c_str(),
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          download_params->bind_ctx, NULL, download_params->post_data,
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          &flags);
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delete download_params;
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TRUE;
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnAttachExternalTab(const AttachExternalTabParams& params) {
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GURL current_url(static_cast<BSTR>(url_));
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string url = chrome_frame::ActiveXCreateUrl(current_url, params);
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Pass the current document url as the referrer for the new navigation.
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HostNavigate(GURL(url), current_url, chrome_frame::GetDisposition(params));
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnHandleContextMenu(const ContextMenuModel& menu_model,
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   int align_flags,
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   const MiniContextMenuParams& params) {
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<BasePlugin> ref(this);
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ChromeFramePlugin<T>::OnHandleContextMenu(menu_model, align_flags, params);
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LRESULT OnCreate(UINT message, WPARAM wparam, LPARAM lparam,
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   BOOL& handled) {  // NO_LINT
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ModifyStyle(0, WS_CLIPCHILDREN | WS_CLIPSIBLINGS, 0);
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    url_fetcher_->put_notification_window(m_hWnd);
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (automation_client_.get()) {
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      automation_client_->SetParentWindow(m_hWnd);
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED() << "No automation server";
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return -1;
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Only fire the 'interactive' ready state if we aren't there already.
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ready_state_ < READYSTATE_INTERACTIVE) {
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ready_state_ = READYSTATE_INTERACTIVE;
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FireOnChanged(DISPID_READYSTATE);
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return 0;
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LRESULT OnDestroy(UINT message, WPARAM wparam, LPARAM lparam,
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    BOOL& handled) {  // NO_LINT
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DVLOG(1) << __FUNCTION__;
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return 0;
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ChromeFrameDelegate override
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnAutomationServerReady() {
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    draw_sad_tab_ = false;
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ChromeFramePlugin<T>::OnAutomationServerReady();
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ready_state_ = READYSTATE_COMPLETE;
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FireOnChanged(DISPID_READYSTATE);
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ChromeFrameDelegate override
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnAutomationServerLaunchFailed(
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AutomationLaunchResult reason, const std::string& server_version) {
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DVLOG(1) << __FUNCTION__;
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (reason == AUTOMATION_SERVER_CRASHED)
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      draw_sad_tab_ = true;
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ready_state_ = READYSTATE_UNINITIALIZED;
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FireOnChanged(DISPID_READYSTATE);
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnCloseTab() {
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Fire_onclose();
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Overridden to take advantage of readystate prop changes and send those
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to potential listeners.
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HRESULT FireOnChanged(DISPID dispid) {
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (dispid == DISPID_READYSTATE) {
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Fire_onreadystatechanged(ready_state_);
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return __super::FireOnChanged(dispid);
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // IChromeFrame
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Property getter/setters for the src attribute, which contains a URL.
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The ChromeFrameActivex control initiates navigation to this URL
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // when instantiated.
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  STDMETHOD(get_src)(BSTR* src) {
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (NULL == src) {
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return E_POINTER;
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *src = SysAllocString(url_);
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return S_OK;
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  STDMETHOD(put_src)(BSTR src) {
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (src == NULL)
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return E_INVALIDARG;
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Switch the src to UTF8 and try to expand to full URL
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string src_utf8;
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WideToUTF8(src, SysStringLen(src), &src_utf8);
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string full_url = ResolveURL(GetDocumentUrl(), src_utf8);
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We can initiate navigation here even if ready_state is not complete.
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We do not have to set proxy, and AutomationClient will take care
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // of navigation just after CreateExternalTab is done.
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!automation_client_->InitiateNavigation(full_url,
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                GetDocumentUrl(),
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                this)) {
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // TODO(robertshield): Make InitiateNavigation return more useful
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // error information.
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return E_INVALIDARG;
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Save full URL in BSTR member
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    url_.Reset(::SysAllocString(UTF8ToWide(full_url).c_str()));
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return S_OK;
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  STDMETHOD(get_onload)(VARIANT* onload_handler) {
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (NULL == onload_handler)
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return E_INVALIDARG;
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *onload_handler = onload_handler_.Copy();
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return S_OK;
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Property setter for the onload attribute, which contains a
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // javascript function to be invoked on successful navigation.
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  STDMETHOD(put_onload)(VARIANT onload_handler) {
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (V_VT(&onload_handler) != VT_DISPATCH) {
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DLOG(WARNING) << "Invalid onload handler type: "
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    << onload_handler.vt
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    << " specified";
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return E_INVALIDARG;
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    onload_handler_ = onload_handler;
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return S_OK;
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Property getter/setters for the onloaderror attribute, which contains a
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // javascript function to be invoked on navigation failure.
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  STDMETHOD(get_onloaderror)(VARIANT* onerror_handler) {
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (NULL == onerror_handler)
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return E_INVALIDARG;
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *onerror_handler = onerror_handler_.Copy();
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return S_OK;
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  STDMETHOD(put_onloaderror)(VARIANT onerror_handler) {
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (V_VT(&onerror_handler) != VT_DISPATCH) {
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DLOG(WARNING) << "Invalid onloaderror handler type: "
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    << onerror_handler.vt
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    << " specified";
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return E_INVALIDARG;
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    onerror_handler_ = onerror_handler;
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return S_OK;
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Property getter/setters for the onmessage attribute, which contains a
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // javascript function to be invoked when we receive a message from the
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // chrome frame.
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  STDMETHOD(put_onmessage)(VARIANT onmessage_handler) {
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (V_VT(&onmessage_handler) != VT_DISPATCH) {
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DLOG(WARNING) << "Invalid onmessage handler type: "
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    << onmessage_handler.vt
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    << " specified";
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return E_INVALIDARG;
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    onmessage_handler_ = onmessage_handler;
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return S_OK;
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  STDMETHOD(get_onmessage)(VARIANT* onmessage_handler) {
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (NULL == onmessage_handler)
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return E_INVALIDARG;
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *onmessage_handler = onmessage_handler_.Copy();
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return S_OK;
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  STDMETHOD(get_readyState)(long* ready_state) {  // NOLINT
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DVLOG(1) << __FUNCTION__;
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(ready_state);
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ready_state)
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return E_INVALIDARG;
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *ready_state = ready_state_;
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return S_OK;
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Property getter/setters for use_chrome_network flag. This flag
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // indicates if chrome network stack is to be used for fetching
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // network requests.
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  STDMETHOD(get_useChromeNetwork)(VARIANT_BOOL* use_chrome_network) {
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!use_chrome_network)
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return E_INVALIDARG;
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *use_chrome_network =
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        automation_client_->use_chrome_network() ? VARIANT_TRUE : VARIANT_FALSE;
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return S_OK;
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  STDMETHOD(put_useChromeNetwork)(VARIANT_BOOL use_chrome_network) {
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!is_privileged()) {
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DLOG(ERROR) << "Attempt to set useChromeNetwork in non-privileged mode";
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return E_ACCESSDENIED;
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    automation_client_->set_use_chrome_network(
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        (VARIANT_FALSE != use_chrome_network));
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return S_OK;
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Posts a message to the chrome frame.
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  STDMETHOD(postMessage)(BSTR message, VARIANT target) {
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (NULL == message) {
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return E_INVALIDARG;
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!automation_client_.get())
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return E_FAIL;
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string utf8_target;
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (target.vt == VT_BSTR) {
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      int len = ::SysStringLen(target.bstrVal);
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (len == 1 && target.bstrVal[0] == L'*') {
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        utf8_target = "*";
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      } else {
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        GURL resolved(target.bstrVal);
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (!resolved.is_valid()) {
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          Error(L"Unable to parse the specified target URL.");
7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          return E_INVALIDARG;
7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        utf8_target = resolved.spec();
7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      utf8_target = "*";
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string utf8_message;
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WideToUTF8(message, ::SysStringLen(message), &utf8_message);
7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GURL url(GURL(document_url_).GetOrigin());
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string origin(url.is_empty() ? "null" : url.spec());
7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!automation_client_->ForwardMessageFromExternalHost(utf8_message,
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                            origin,
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                            utf8_target)) {
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Error(L"Failed to post message to chrome frame");
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return E_FAIL;
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return S_OK;
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  STDMETHOD(addEventListener)(BSTR event_type, IDispatch* listener,
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              VARIANT use_capture) {
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EventHandlers* handlers = NULL;
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HRESULT hr = GetHandlersForEvent(event_type, &handlers);
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (FAILED(hr))
7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return hr;
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(handlers != NULL);
7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    handlers->insert(base::win::ScopedComPtr<IDispatch>(listener));
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return hr;
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  STDMETHOD(removeEventListener)(BSTR event_type, IDispatch* listener,
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 VARIANT use_capture) {
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EventHandlers* handlers = NULL;
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HRESULT hr = GetHandlersForEvent(event_type, &handlers);
7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (FAILED(hr))
7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return hr;
7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(handlers != NULL);
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    handlers->erase(base::win::ScopedComPtr<IDispatch>(listener));
7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return hr;
7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  STDMETHOD(get_version)(BSTR* version) {
7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!automation_client_.get()) {
7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED();
7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return E_FAIL;
7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (version == NULL) {
7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return E_INVALIDARG;
7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *version = SysAllocString(automation_client_->GetVersion().c_str());
7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return S_OK;
7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  STDMETHOD(postPrivateMessage)(BSTR message, BSTR origin, BSTR target) {
7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (NULL == message)
7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return E_INVALIDARG;
7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!is_privileged()) {
7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DLOG(ERROR) << "Attempt to postPrivateMessage in non-privileged mode";
7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return E_ACCESSDENIED;
7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(automation_client_.get());
7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string utf8_message, utf8_origin, utf8_target;
7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WideToUTF8(message, ::SysStringLen(message), &utf8_message);
7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WideToUTF8(origin, ::SysStringLen(origin), &utf8_origin);
7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WideToUTF8(target, ::SysStringLen(target), &utf8_target);
8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!automation_client_->ForwardMessageFromExternalHost(utf8_message,
8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                            utf8_origin,
8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                            utf8_target)) {
8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Error(L"Failed to post message to chrome frame");
8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return E_FAIL;
8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return S_OK;
8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  STDMETHOD(installExtension)(BSTR crx_path) {
8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTREACHED();  // Deprecated.
8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return E_NOTIMPL;
8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  STDMETHOD(loadExtension)(BSTR path) {
8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTREACHED();  // Deprecated.
8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return E_NOTIMPL;
8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  STDMETHOD(getEnabledExtensions)() {
8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTREACHED();  // Deprecated.
8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return E_NOTIMPL;
8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  STDMETHOD(registerBhoIfNeeded)() {
8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return E_NOTIMPL;
8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns the vector of event handlers for a given event (e.g. "load").
8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If the event type isn't recognized, the function fills in a descriptive
8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // error (IErrorInfo) and returns E_INVALIDARG.
8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HRESULT GetHandlersForEvent(BSTR event_type, EventHandlers** handlers) {
8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(handlers != NULL);
8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // TODO(tommi): make these if() statements data-driven.
8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HRESULT hr = S_OK;
8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const wchar_t* event_type_end = event_type + ::SysStringLen(event_type);
8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (LowerCaseEqualsASCII(event_type, event_type_end, "message")) {
8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *handlers = &onmessage_;
8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (LowerCaseEqualsASCII(event_type, event_type_end, "load")) {
8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *handlers = &onload_;
8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (LowerCaseEqualsASCII(event_type, event_type_end, "loaderror")) {
8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *handlers = &onloaderror_;
8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (LowerCaseEqualsASCII(event_type, event_type_end,
8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    "readystatechanged")) {
8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *handlers = &onreadystatechanged_;
8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (LowerCaseEqualsASCII(event_type, event_type_end,
8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    "privatemessage")) {
8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // This event handler is only available in privileged mode.
8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (is_privileged()) {
8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        *handlers = &onprivatemessage_;
8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      } else {
8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        Error("Event type 'privatemessage' is privileged");
8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        hr = E_ACCESSDENIED;
8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (LowerCaseEqualsASCII(event_type, event_type_end,
8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    "extensionready")) {
8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // This event handler is only available in privileged mode.
8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (is_privileged()) {
8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        *handlers = &onextensionready_;
8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      } else {
8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        Error("Event type 'extensionready' is privileged");
8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        hr = E_ACCESSDENIED;
8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Error(base::StringPrintf(
8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "Event type '%ls' not found", event_type).c_str());
8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      hr = E_INVALIDARG;
8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return hr;
8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Creates a new event object that supports the |data| property.
8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Note: you should supply an empty string for |origin| unless you're
8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // creating a "message" event.
8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HRESULT CreateDomEvent(const std::string& event_type, const std::string& data,
8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         const std::string& origin, IDispatch** event) {
8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(event_type.length() > 0);  // NOLINT
8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(event != NULL);
8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CComObject<ComMessageEvent>* ev = NULL;
8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HRESULT hr = CComObject<ComMessageEvent>::CreateInstance(&ev);
8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (SUCCEEDED(hr)) {
8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ev->AddRef();
8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::win::ScopedComPtr<IOleContainer> container;
8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      m_spClientSite->GetContainer(container.Receive());
8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (ev->Initialize(container, data, origin, event_type)) {
8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        *event = ev;
8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      } else {
8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        NOTREACHED() << "event->Initialize";
8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ev->Release();
8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        hr = E_UNEXPECTED;
8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return hr;
9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Helper function to execute a function on a script IDispatch interface.
9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HRESULT InvokeScriptFunction(const VARIANT& script_object,
9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               const std::string& param) {
9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::win::ScopedVariant script_arg(UTF8ToWide(param.c_str()).c_str());
9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return InvokeScriptFunction(script_object, script_arg.AsInput());
9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HRESULT InvokeScriptFunction(const VARIANT& script_object, VARIANT* param) {
9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return InvokeScriptFunction(script_object, param, 1);
9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HRESULT InvokeScriptFunction(const VARIANT& script_object, VARIANT* params,
9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               int param_count) {
9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK_GE(param_count, 0);
9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(params);
9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (V_VT(&script_object) != VT_DISPATCH ||
9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        script_object.pdispVal == NULL) {
9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return S_FALSE;
9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CComPtr<IDispatch> script(script_object.pdispVal);
9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HRESULT hr = script.InvokeN(static_cast<DISPID>(DISPID_VALUE),
9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                params,
9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                param_count);
9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // 0x80020101 == SCRIPT_E_REPORTED.
9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // When the script we're invoking has an error, we get this error back.
9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DLOG_IF(ERROR, FAILED(hr) && hr != 0x80020101) << "Failed to invoke script";
9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return hr;
9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Gives the browser a chance to handle an accelerator that was
9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // sent to the out of proc chromium instance.
9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns S_OK iff the accelerator was handled by the browser.
9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HRESULT AllowFrameToTranslateAccelerator(const MSG& msg) {
9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    static const int kMayTranslateAcceleratorOffset = 0x5c;
9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Although IBrowserService2 is officially deprecated, it's still alive
9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // and well in IE7 and earlier.  We have to use it here to correctly give
9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // the browser a chance to handle keyboard shortcuts.
9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // This happens automatically for activex components that have windows that
9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // belong to the current thread.  In that circumstance IE owns the message
9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // loop and can walk the line of components allowing each participant the
9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // chance to handle the keystroke and eventually falls back to
9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // v_MayTranslateAccelerator.  However in our case, the message loop is
9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // owned by the out-of-proc chromium instance so IE doesn't have a chance to
9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // fall back on its default behavior.  Instead we give IE a chance to
9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // handle the shortcut here.
9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MSG accel_message = msg;
9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    accel_message.hwnd = ::GetParent(m_hWnd);
9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HRESULT hr = S_FALSE;
9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::win::ScopedComPtr<IBrowserService2> bs2;
9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // For non-IE containers, we use the standard IOleInPlaceFrame contract
9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // (which IE does not support). For IE, we try to use IBrowserService2,
9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // but need special handling for IE8 (see below).
9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //
9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We try to cache an IOleInPlaceFrame for our site.  If we fail, we don't
9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // retry, and we fall back to the IBrowserService2 and PostMessage
9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // approaches below.
9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!in_place_frame_ && !failed_to_fetch_in_place_frame_) {
9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::win::ScopedComPtr<IOleInPlaceUIWindow> dummy_ui_window;
9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      RECT dummy_pos_rect = {0};
9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      RECT dummy_clip_rect = {0};
9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      OLEINPLACEFRAMEINFO dummy_frame_info = {0};
9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!m_spInPlaceSite ||
9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          FAILED(m_spInPlaceSite->GetWindowContext(in_place_frame_.Receive(),
9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                   dummy_ui_window.Receive(),
9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                   &dummy_pos_rect,
9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                   &dummy_clip_rect,
9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                   &dummy_frame_info))) {
9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        failed_to_fetch_in_place_frame_ = true;
9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The IBrowserService2 code below (second conditional) explicitly checks
9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // for whether the IBrowserService2::v_MayTranslateAccelerator function is
9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // valid. On IE8 there is one vtable ieframe!c_ImpostorBrowserService2Vtbl
9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // where this function entry is NULL which leads to a crash. We don't know
9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // under what circumstances this vtable is actually used though.
9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (in_place_frame_) {
9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      hr = in_place_frame_->TranslateAccelerator(&accel_message, 0);
9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (S_OK == DoQueryService(
9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        SID_STopLevelBrowser, m_spInPlaceSite,
9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        bs2.Receive()) && bs2.get() &&
9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        *(*(reinterpret_cast<void***>(bs2.get())) +
9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        kMayTranslateAcceleratorOffset)) {
9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      hr = bs2->v_MayTranslateAccelerator(&accel_message);
9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // IE8 doesn't support IBrowserService2 unless you enable a special,
9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // undocumented flag with CoInternetSetFeatureEnabled and even then,
9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // the object you get back implements only a couple of methods of
9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // that interface... all the other entries in the vtable are NULL.
9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // In addition, the class that implements it is called
9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // ImpostorBrowserService2 :)
9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // IE8 does have a new interface though, presumably called
9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // ITabBrowserService or something that can be abbreviated to TBS.
9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // That interface has a method, TranslateAcceleratorTBS that does
9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // call the root MayTranslateAccelerator function, but alas the
10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // first argument to MayTranslateAccelerator is hard coded to FALSE
10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // which means that global accelerators are not handled and we're
10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // out of luck.
10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // A third thing that's notable with regards to IE8 is that
10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // none of the *MayTranslate* functions exist in a vtable inside
10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // ieframe.dll.  I checked this by scanning for the address of
10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // those functions inside the dll and found none, which means that
10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // all calls to those functions are relative.
10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // So, for IE8 in certain cases, and for other containers that may
10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // support neither IOleInPlaceFrame or IBrowserService2 our approach
10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // is very simple.  Just post the message to our parent window and IE
10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // will pick it up if it's an accelerator. We won't know for sure if
10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // the browser handled the keystroke or not.
10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ::PostMessage(accel_message.hwnd, accel_message.message,
10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    accel_message.wParam, accel_message.lParam);
10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return hr;
10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnAcceleratorPressed(const MSG& accel_message) {
10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(m_spInPlaceSite != NULL);
10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Allow our host a chance to handle the accelerator.
10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // This catches things like Ctrl+F, Ctrl+O etc, but not browser
10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // accelerators such as F11, Ctrl+T etc.
10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // (see AllowFrameToTranslateAccelerator for those).
10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HRESULT hr = TranslateAccelerator(const_cast<MSG*>(&accel_message));
10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (hr != S_OK)
10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      hr = AllowFrameToTranslateAccelerator(accel_message);
10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DVLOG(1) << __FUNCTION__ << " browser response: "
10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             << base::StringPrintf("0x%08x", hr);
10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (hr != S_OK) {
10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // The WM_SYSKEYDOWN/WM_SYSKEYUP messages are not processed by the
10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // IOleControlSite and IBrowserService2::v_MayTranslateAccelerator
10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // implementations. We need to understand this better. That is for
10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // another day. For now we just post these messages back to the parent
10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // which forwards it off to the frame. This should not cause major
10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // grief for Chrome as it does not need to handle WM_SYSKEY* messages in
10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // in ChromeFrame mode.
10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // TODO(iyengar)
10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Understand and fix WM_SYSCHAR handling
10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // We should probably unify the accelerator handling for the active
10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // document and the activex.
10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (accel_message.message == WM_SYSCHAR ||
10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          accel_message.message == WM_SYSKEYDOWN ||
10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          accel_message.message == WM_SYSKEYUP) {
10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ::PostMessage(GetParent(), accel_message.message, accel_message.wParam,
10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      accel_message.lParam);
10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return;
10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Last chance to handle the keystroke is to pass it to chromium.
10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We do this last partially because there's no way for us to tell if
10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // chromium actually handled the keystroke, but also since the browser
10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // should have first dibs anyway.
10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (hr != S_OK && automation_client_.get()) {
10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TabProxy* tab = automation_client_->tab();
10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (tab) {
10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        tab->ProcessUnhandledAccelerator(accel_message);
10615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
10625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
10665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void HostNavigate(const GURL& url_to_open,
10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    const GURL& referrer, int open_disposition) {
10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::win::ScopedComPtr<IWebBrowser2> web_browser2;
10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DoQueryService(SID_SWebBrowserApp, m_spClientSite, web_browser2.Receive());
10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!web_browser2) {
10715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED() << "Failed to retrieve IWebBrowser2 interface";
10725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
10735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
10745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::win::ScopedVariant url;
10755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Check to see if the URL uses a "view-source:" prefix, if so, open it
10765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // using chrome frame full tab mode by using 'cf:' protocol handler.
10775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Also change the disposition to NEW_WINDOW since IE6 doesn't have tabs.
10785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (url_to_open.has_scheme() &&
1079868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        (url_to_open.SchemeIs(content::kViewSourceScheme) ||
10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        url_to_open.SchemeIs(chrome::kAboutScheme))) {
10815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      std::wstring chrome_url;
10825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      chrome_url.append(kChromeProtocolPrefix);
10835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      chrome_url.append(UTF8ToWide(url_to_open.spec()));
10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url.Set(chrome_url.c_str());
10855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      open_disposition = NEW_WINDOW;
10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
10875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url.Set(UTF8ToWide(url_to_open.spec()).c_str());
10885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
10895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    VARIANT flags = { VT_I4 };
10915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    V_I4(&flags) = 0;
10925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IEVersion ie_version = GetIEVersion();
10945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(ie_version != NON_IE && ie_version != IE_UNSUPPORTED);
10955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Since IE6 doesn't support tabs, so we just use window instead.
10965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ie_version == IE_6) {
10975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (open_disposition == NEW_FOREGROUND_TAB ||
10985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          open_disposition == NEW_BACKGROUND_TAB ||
10995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          open_disposition == NEW_WINDOW ||
11005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          open_disposition == NEW_POPUP) {
11015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        V_I4(&flags) = navOpenInNewWindow;
11025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      } else if (open_disposition != CURRENT_TAB) {
11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        NOTREACHED() << "Unsupported open disposition in IE6";
11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      switch (open_disposition) {
11075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case NEW_FOREGROUND_TAB:
11085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          V_I4(&flags) = navOpenInNewTab;
11095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          break;
11105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case NEW_BACKGROUND_TAB:
11115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          V_I4(&flags) = navOpenInBackgroundTab;
11125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          break;
11135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case NEW_WINDOW:
11145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case NEW_POPUP:
11155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          V_I4(&flags) = navOpenInNewWindow;
11165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          break;
11175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        default:
11185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          break;
11195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
11205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
11215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // TODO(sanjeevr): The navOpenInNewWindow flag causes IE to open this
11235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // in a new window ONLY if the user has specified
11245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // "Always open popups in a new window". Otherwise it opens in a new tab.
11255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We need to investigate more and see if we can force IE to display the
11265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // link in a new window. MSHTML uses the below code to force an open in a
11275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // new window. But this logic also fails for us. Perhaps this flag is not
11285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // honoured if the ActiveDoc is not MSHTML.
11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Even the HLNF_DISABLEWINDOWRESTRICTIONS flag did not work.
11305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Start of MSHTML-like logic.
11315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // CComQIPtr<ITargetFramePriv2> target_frame = web_browser2;
11325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // if (target_frame) {
11335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //   CComPtr<IUri> uri;
11345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //   CreateUri(UTF8ToWide(open_url_command->url_.spec()).c_str(),
11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //             Uri_CREATE_IE_SETTINGS, 0, &uri);
11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //   CComPtr<IBindCtx> bind_ctx;
11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //   CreateBindCtx(0, &bind_ctx);
11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //   target_frame->AggregatedNavigation2(
11395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //       HLNF_TRUSTFIRSTDOWNLOAD|HLNF_OPENINNEWWINDOW, bind_ctx, NULL,
11405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //       L"No_Name", uri, L"");
11415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // }
11425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // End of MSHTML-like logic
11435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    VARIANT empty = base::win::ScopedVariant::kEmptyVariant;
11445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::win::ScopedVariant http_headers;
11455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (referrer.is_valid()) {
11475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      std::wstring referrer_header = L"Referer: ";
11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      referrer_header += UTF8ToWide(referrer.spec());
11495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      referrer_header += L"\r\n\r\n";
11505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      http_headers.Set(referrer_header.c_str());
11515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
11525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // IE6 does not support tabs. If Chrome sent us a window open request
11545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // indicating that the navigation needs to occur in a foreground tab or
11555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // a popup window, then we need to ensure that the new window in IE6 is
11565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // brought to the foreground.
11575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ie_version == IE_6) {
11585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ChromeFrameUrl cf_url;
11595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      cf_url.Parse(static_cast<BSTR>(url_));
11605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (cf_url.attach_to_external_tab() &&
11625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          (cf_url.disposition() == NEW_FOREGROUND_TAB ||
11635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           cf_url.disposition() == NEW_POPUP)) {
11645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        BringWebBrowserWindowToTop(web_browser2);
11655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
11665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
11675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HRESULT hr = web_browser2->Navigate2(url.AsInput(), &flags, &empty, &empty,
11695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         http_headers.AsInput());
11705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // If the current window is a popup window then attempting to open a new
11715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // tab for the navigation will fail. We attempt to issue the navigation in
11725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // a new window in this case.
11735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // http://msdn.microsoft.com/en-us/library/aa752133(v=vs.85).aspx
11745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (FAILED(hr) && V_I4(&flags) != navOpenInNewWindow) {
11755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      V_I4(&flags) = navOpenInNewWindow;
11765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      hr = web_browser2->Navigate2(url.AsInput(), &flags, &empty, &empty,
11775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   http_headers.AsInput());
11785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DLOG_IF(ERROR, FAILED(hr))
11795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          << "Navigate2 failed with error: "
11805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          << base::StringPrintf("0x%08X", hr);
11815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
11825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
11835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void InitializeAutomationSettings() {
11855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    static const wchar_t kHandleTopLevelRequests[] = L"HandleTopLevelRequests";
11865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    static const wchar_t kUseChromeNetworking[] = L"UseChromeNetworking";
11875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Query and assign the top-level-request routing, and host networking
11895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // settings from the registry.
11905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool top_level_requests = GetConfigBool(true, kHandleTopLevelRequests);
11915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool chrome_network = GetConfigBool(false, kUseChromeNetworking);
11925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    automation_client_->set_handle_top_level_requests(top_level_requests);
11935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    automation_client_->set_use_chrome_network(chrome_network);
11945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
11955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::win::ScopedBstr url_;
11975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::win::ScopedComPtr<IOleDocumentSite> doc_site_;
11985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If false, we tried but failed to fetch an IOleInPlaceFrame from our host.
12005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Cached here so we don't try to fetch it every time if we keep failing.
12015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool failed_to_fetch_in_place_frame_;
12025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool draw_sad_tab_;
12035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::win::ScopedComPtr<IOleInPlaceFrame> in_place_frame_;
12055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // For more information on the ready_state_ property see:
12075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // http://msdn.microsoft.com/en-us/library/aa768179(VS.85).aspx#
12085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  READYSTATE ready_state_;
12095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The following members contain IDispatch interfaces representing the
12115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // onload/onerror/onmessage handlers on the page.
12125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::win::ScopedVariant onload_handler_;
12135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::win::ScopedVariant onerror_handler_;
12145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::win::ScopedVariant onmessage_handler_;
12155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EventHandlers onmessage_;
12175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EventHandlers onloaderror_;
12185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EventHandlers onload_;
12195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EventHandlers onreadystatechanged_;
12205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EventHandlers onprivatemessage_;
12215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EventHandlers onextensionready_;
12225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Handle network requests when host network stack is used. Passed to the
12245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // automation client on initialization.
12255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<UrlmonUrlRequestManager> url_fetcher_;
12265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
12275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // CHROME_FRAME_CHROME_FRAME_ACTIVEX_BASE_H_
1229