// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Implementation of ChromeActiveDocument
#include "chrome_frame/chrome_active_document.h"

#include <hlink.h>
#include <htiface.h>
#include <initguid.h>
#include <mshtmcid.h>
#include <shdeprecated.h>
#include <shlguid.h>
#include <shlobj.h>
#include <shobjidl.h>
#include <tlogstg.h>
#include <urlmon.h>
#include <wininet.h>

#include "base/command_line.h"
#include "base/debug/trace_event.h"
#include "base/logging.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/win/scoped_variant.h"
#include "chrome/app/chrome_command_ids.h"
#include "chrome/app/chrome_dll_resource.h"
#include "chrome/common/automation_messages.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/test/automation/browser_proxy.h"
#include "chrome/test/automation/tab_proxy.h"
#include "chrome_frame/bho.h"
#include "chrome_frame/bind_context_info.h"
#include "chrome_frame/buggy_bho_handling.h"
#include "chrome_frame/crash_reporting/crash_metrics.h"
#include "chrome_frame/utils.h"
#include "content/public/browser/invalidate_type.h"
#include "content/public/browser/navigation_type.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/page_zoom.h"
#include "grit/generated_resources.h"

DEFINE_GUID(CGID_DocHostCmdPriv, 0x000214D4L, 0, 0, 0xC0, 0, 0, 0, 0, 0, 0,
            0x46);

bool g_first_launch_by_process_ = true;

const DWORD kIEEncodingIdArray[] = {
#define DEFINE_ENCODING_ID_ARRAY(encoding_name, id, chrome_name) encoding_name,
  INTERNAL_IE_ENCODINGMENU_IDS(DEFINE_ENCODING_ID_ARRAY)
#undef DEFINE_ENCODING_ID_ARRAY
  0  // The Last data must be 0 to indicate the end of the encoding id array.
};

ChromeActiveDocument::ChromeActiveDocument()
    : navigation_info_(new NavigationInfo()),
      first_navigation_(true),
      is_automation_client_reused_(false),
      popup_allowed_(false),
      accelerator_table_(NULL) {
  TRACE_EVENT_BEGIN_ETW("chromeframe.createactivedocument", this, "");

  url_fetcher_->set_frame_busting(false);
  memset(navigation_info_.get(), 0, sizeof(NavigationInfo));
}

HRESULT ChromeActiveDocument::FinalConstruct() {
  // The FinalConstruct implementation in the ChromeFrameActivexBase class
  // i.e. Base creates an instance of the ChromeFrameAutomationClient class
  // and initializes it, which would spawn a new Chrome process, etc.
  // We don't want to be doing this if we have a cached document, whose
  // automation client instance can be reused.
  HRESULT hr = BaseActiveX::FinalConstruct();
  if (FAILED(hr))
    return hr;

  InitializeAutomationSettings();

  find_dialog_.Init(automation_client_.get());

  OLECMDF flags = static_cast<OLECMDF>(OLECMDF_ENABLED | OLECMDF_SUPPORTED);

  null_group_commands_map_[OLECMDID_PRINT] = flags;
  null_group_commands_map_[OLECMDID_FIND] = flags;
  null_group_commands_map_[OLECMDID_CUT] = flags;
  null_group_commands_map_[OLECMDID_COPY] = flags;
  null_group_commands_map_[OLECMDID_PASTE] = flags;
  null_group_commands_map_[OLECMDID_SELECTALL] = flags;
  null_group_commands_map_[OLECMDID_SAVEAS] = flags;

  mshtml_group_commands_map_[IDM_BASELINEFONT1] = flags;
  mshtml_group_commands_map_[IDM_BASELINEFONT2] = flags;
  mshtml_group_commands_map_[IDM_BASELINEFONT3] = flags;
  mshtml_group_commands_map_[IDM_BASELINEFONT4] = flags;
  mshtml_group_commands_map_[IDM_BASELINEFONT5] = flags;
  mshtml_group_commands_map_[IDM_VIEWSOURCE] = flags;

  HMODULE this_module = reinterpret_cast<HMODULE>(&__ImageBase);
  accelerator_table_ =
    LoadAccelerators(this_module,
                     MAKEINTRESOURCE(IDR_CHROME_FRAME_IE_FULL_TAB));
  DCHECK(accelerator_table_ != NULL);
  return S_OK;
}

ChromeActiveDocument::~ChromeActiveDocument() {
  DVLOG(1) << __FUNCTION__;
  if (find_dialog_.IsWindow())
    find_dialog_.DestroyWindow();
  // ChromeFramePlugin
  BaseActiveX::Uninitialize();

  TRACE_EVENT_END_ETW("chromeframe.createactivedocument", this, "");
}

// Override DoVerb
STDMETHODIMP ChromeActiveDocument::DoVerb(LONG verb,
                                          LPMSG msg,
                                          IOleClientSite* active_site,
                                          LONG index,
                                          HWND parent_window,
                                          LPCRECT pos) {
  // IE will try and in-place activate us in some cases. This happens when
  // the user opens a new IE window with a URL that has us as the DocObject.
  // Here we refuse to be activated in-place and we will force IE to UIActivate
  // us.
  if (OLEIVERB_INPLACEACTIVATE == verb)
    return OLEOBJ_E_INVALIDVERB;
  // Check if we should activate as a docobject or not
  // (client supports IOleDocumentSite)
  if (doc_site_) {
    switch (verb) {
    case OLEIVERB_SHOW: {
      base::win::ScopedComPtr<IDocHostUIHandler> doc_host_handler;
      doc_host_handler.QueryFrom(doc_site_);
      if (doc_host_handler.get())
        doc_host_handler->ShowUI(DOCHOSTUITYPE_BROWSE, this, this, NULL, NULL);
    }
    case OLEIVERB_OPEN:
    case OLEIVERB_UIACTIVATE:
      if (!m_bUIActive)
        return doc_site_->ActivateMe(NULL);
      break;
    }
  }
  return IOleObjectImpl<ChromeActiveDocument>::DoVerb(verb,
                                                      msg,
                                                      active_site,
                                                      index,
                                                      parent_window,
                                                      pos);
}

// Override IOleInPlaceActiveObjectImpl::OnDocWindowActivate
STDMETHODIMP ChromeActiveDocument::OnDocWindowActivate(BOOL activate) {
  DVLOG(1) << __FUNCTION__;
  return S_OK;
}

STDMETHODIMP ChromeActiveDocument::TranslateAccelerator(MSG* msg) {
  DVLOG(1) << __FUNCTION__;
  if (msg == NULL)
    return E_POINTER;

  if (msg->message == WM_KEYDOWN && msg->wParam == VK_TAB) {
    HWND focus = ::GetFocus();
    if (focus != m_hWnd && !::IsChild(m_hWnd, focus)) {
      // The call to SetFocus triggers a WM_SETFOCUS that makes the base class
      // set focus to the correct element in Chrome.
      ::SetFocus(m_hWnd);
      return S_OK;
    }
  }

  return S_FALSE;
}
// Override IPersistStorageImpl::IsDirty
STDMETHODIMP ChromeActiveDocument::IsDirty() {
  DVLOG(1) << __FUNCTION__;
  return S_FALSE;
}

void ChromeActiveDocument::OnAutomationServerReady() {
  BaseActiveX::OnAutomationServerReady();
  BaseActiveX::GiveFocusToChrome(true);
}

STDMETHODIMP ChromeActiveDocument::Load(BOOL fully_avalable,
                                        IMoniker* moniker_name,
                                        LPBC bind_context,
                                        DWORD mode) {
  if (NULL == moniker_name)
    return E_INVALIDARG;

  base::win::ScopedComPtr<IOleClientSite> client_site;
  if (bind_context) {
    base::win::ScopedComPtr<IUnknown> site;
    bind_context->GetObjectParam(SZ_HTML_CLIENTSITE_OBJECTPARAM,
                                 site.Receive());
    if (site)
      client_site.QueryFrom(site);
  }

  if (client_site) {
    SetClientSite(client_site);
    DoQueryService(IID_INewWindowManager, client_site,
                   popup_manager_.Receive());

    // See if mshtml parsed the html header for us.  If so, we need to
    // clear the browser service flag that we use to indicate that this
    // browser instance is navigating to a CF document.
    base::win::ScopedComPtr<IBrowserService> browser_service;
    DoQueryService(SID_SShellBrowser, client_site, browser_service.Receive());
    if (browser_service) {
      bool flagged = CheckForCFNavigation(browser_service, true);
      DVLOG_IF(1, flagged) << "Cleared flagged browser service";
    }
  }

  NavigationManager* mgr = NavigationManager::GetThreadInstance();
  DLOG_IF(ERROR, !mgr) << "Couldn't get instance of NavigationManager";

  std::wstring url;

  base::win::ScopedComPtr<BindContextInfo> info;
  BindContextInfo::FromBindContext(bind_context, info.Receive());
  DCHECK(info);
  if (info && !info->GetUrl().empty()) {
    url = info->GetUrl();
    if (mgr) {
      // If the original URL contains an anchor, then the URL queried
      // from the protocol sink wrapper does not contain the anchor. To
      // workaround this we retrieve the anchor from the navigation manager
      // and append it to the url retrieved from the protocol sink wrapper.
      GURL url_for_anchor(mgr->url());
      if (url_for_anchor.has_ref()) {
        url += L"#";
        url += UTF8ToWide(url_for_anchor.ref());
      }
    }
  } else {
    // If the original URL contains an anchor, then the URL queried
    // from the moniker does not contain the anchor. To workaround
    // this we retrieve the URL from our BHO.
    url = GetActualUrlFromMoniker(moniker_name, bind_context,
                                  mgr ? mgr->url(): std::wstring());
  }

  ChromeFrameUrl cf_url;
  if (!cf_url.Parse(url)) {
    DLOG(WARNING) << __FUNCTION__ << " Failed to parse url:" << url;
    return E_INVALIDARG;
  }

  std::string referrer(mgr ? mgr->referrer() : EmptyString());
  RendererType renderer_type = cf_url.is_chrome_protocol() ?
      RENDERER_TYPE_CHROME_GCF_PROTOCOL : RENDERER_TYPE_UNDETERMINED;

  // With CTransaction patch we have more robust way to grab the referrer for
  // each top-level-switch-to-CF request by peeking at our sniffing data
  // object that lives inside the bind context.  We also remember the reason
  // we're rendering the document in Chrome.
  if (g_patch_helper.state() == PatchHelper::PATCH_PROTOCOL && info) {
    scoped_refptr<ProtData> prot_data = info->get_prot_data();
    if (prot_data) {
      referrer = prot_data->referrer();
      renderer_type = prot_data->renderer_type();
    }
  }

  // For gcf: URLs allow only about and view-source schemes to pass through for
  // further inspection.
  bool is_safe_scheme = cf_url.gurl().SchemeIs(chrome::kAboutScheme) ||
      cf_url.gurl().SchemeIs(content::kViewSourceScheme);
  if (cf_url.is_chrome_protocol() && !is_safe_scheme &&
      !GetConfigBool(false, kAllowUnsafeURLs)) {
    DLOG(ERROR) << __FUNCTION__ << " gcf: not allowed:" << url;
    return E_INVALIDARG;
  }

  if (!LaunchUrl(cf_url, referrer)) {
    DLOG(ERROR) << __FUNCTION__ << " Failed to launch url:" << url;
    return E_INVALIDARG;
  }

  if (!cf_url.is_chrome_protocol() && !cf_url.attach_to_external_tab())
    url_fetcher_->SetInfoForUrl(url.c_str(), moniker_name, bind_context);

  // Log a metric indicating why GCF is rendering in Chrome.
  // (Note: we only track the renderer type when using the CTransaction patch.
  // When the code for the browser service patch and for the moniker patch is
  // removed, this conditional can also go away.)
  if (RENDERER_TYPE_UNDETERMINED != renderer_type) {
    UMA_LAUNCH_TYPE_COUNT(renderer_type);
  }

  return S_OK;
}

STDMETHODIMP ChromeActiveDocument::Save(IMoniker* moniker_name,
                                        LPBC bind_context,
                                        BOOL remember) {
  return E_NOTIMPL;
}

STDMETHODIMP ChromeActiveDocument::SaveCompleted(IMoniker* moniker_name,
                                                 LPBC bind_context) {
  return E_NOTIMPL;
}

STDMETHODIMP ChromeActiveDocument::GetCurMoniker(IMoniker** moniker_name) {
  return E_NOTIMPL;
}

STDMETHODIMP ChromeActiveDocument::GetClassID(CLSID* class_id) {
  if (NULL == class_id)
    return E_POINTER;
  *class_id = GetObjectCLSID();
  return S_OK;
}

STDMETHODIMP ChromeActiveDocument::QueryStatus(const GUID* cmd_group_guid,
                                               ULONG number_of_commands,
                                               OLECMD commands[],
                                               OLECMDTEXT* command_text) {
  DVLOG(1) << __FUNCTION__;

  CommandStatusMap* command_map = NULL;

  if (cmd_group_guid) {
    if (IsEqualGUID(*cmd_group_guid, GUID_NULL)) {
      command_map = &null_group_commands_map_;
    } else if (IsEqualGUID(*cmd_group_guid, CGID_MSHTML)) {
      command_map = &mshtml_group_commands_map_;
    } else if (IsEqualGUID(*cmd_group_guid, CGID_Explorer)) {
      command_map = &explorer_group_commands_map_;
    } else if (IsEqualGUID(*cmd_group_guid, CGID_ShellDocView)) {
      command_map = &shdoc_view_group_commands_map_;
    }
  } else {
    command_map = &null_group_commands_map_;
  }

  if (!command_map) {
    DVLOG(1) << "unsupported command group: " << GuidToString(*cmd_group_guid);
    return OLECMDERR_E_NOTSUPPORTED;
  }

  for (ULONG command_index = 0; command_index < number_of_commands;
       command_index++) {
    DVLOG(1) << "Command id = " << commands[command_index].cmdID;
    CommandStatusMap::iterator index =
        command_map->find(commands[command_index].cmdID);
    if (index != command_map->end())
      commands[command_index].cmdf = index->second;
  }
  return S_OK;
}

STDMETHODIMP ChromeActiveDocument::Exec(const GUID* cmd_group_guid,
                                        DWORD command_id,
                                        DWORD cmd_exec_opt,
                                        VARIANT* in_args,
                                        VARIANT* out_args) {
  DVLOG(1) << __FUNCTION__ << " Cmd id =" << command_id;
  // Bail out if we have been uninitialized.
  if (automation_client_.get() && automation_client_->tab()) {
    return ProcessExecCommand(cmd_group_guid, command_id, cmd_exec_opt,
                              in_args, out_args);
  } else if (command_id == OLECMDID_REFRESH && cmd_group_guid == NULL) {
    // If the automation server has crashed and the user is refreshing the
    // page, let OnRefreshPage attempt to recover.
    OnRefreshPage(cmd_group_guid, command_id, cmd_exec_opt, in_args, out_args);
  }

  return OLECMDERR_E_NOTSUPPORTED;
}

STDMETHODIMP ChromeActiveDocument::LoadHistory(IStream* stream,
                                               IBindCtx* bind_context) {
  // Read notes in ChromeActiveDocument::SaveHistory
  DCHECK(stream);
  LARGE_INTEGER offset = {0};
  ULARGE_INTEGER cur_pos = {0};
  STATSTG statstg = {0};

  stream->Seek(offset, STREAM_SEEK_CUR, &cur_pos);
  stream->Stat(&statstg, STATFLAG_NONAME);

  DWORD url_size = statstg.cbSize.LowPart - cur_pos.LowPart;
  base::win::ScopedBstr url_bstr;
  DWORD bytes_read = 0;
  stream->Read(url_bstr.AllocateBytes(url_size), url_size, &bytes_read);
  std::wstring url(url_bstr);

  ChromeFrameUrl cf_url;
  if (!cf_url.Parse(url)) {
    DLOG(WARNING) << __FUNCTION__ << " Failed to parse url:" << url;
    return E_INVALIDARG;
  }

  const std::string& referrer = EmptyString();
  if (!LaunchUrl(cf_url, referrer)) {
    NOTREACHED() << __FUNCTION__ << " Failed to launch url:" << url;
    return E_INVALIDARG;
  }
  return S_OK;
}

STDMETHODIMP ChromeActiveDocument::SaveHistory(IStream* stream) {
  // TODO(sanjeevr): We need to fetch the entire list of navigation entries
  // from Chrome and persist it in the stream. And in LoadHistory we need to
  // pass this list back to Chrome which will recreate the list. This will allow
  // Back-Forward navigation to anchors to work correctly when we navigate to a
  // page outside of ChromeFrame and then come back.
  if (!stream) {
    NOTREACHED();
    return E_INVALIDARG;
  }

  LARGE_INTEGER offset = {0};
  ULARGE_INTEGER new_pos = {0};
  DWORD written = 0;
  std::wstring url = UTF8ToWide(navigation_info_->url.spec());
  return stream->Write(url.c_str(), (url.length() + 1) * sizeof(wchar_t),
                       &written);
}

STDMETHODIMP ChromeActiveDocument::SetPositionCookie(DWORD position_cookie) {
  if (automation_client_.get()) {
    int index = static_cast<int>(position_cookie);
    navigation_info_->navigation_index = index;
    automation_client_->NavigateToIndex(index);
  } else {
    DLOG(WARNING) << "Invalid automation client instance";
  }
  return S_OK;
}

STDMETHODIMP ChromeActiveDocument::GetPositionCookie(DWORD* position_cookie) {
  if (!position_cookie)
    return E_INVALIDARG;

  *position_cookie = navigation_info_->navigation_index;
  return S_OK;
}

STDMETHODIMP ChromeActiveDocument::GetUrlForEvents(BSTR* url) {
  if (NULL == url)
    return E_POINTER;
  *url = ::SysAllocString(url_);
  return S_OK;
}

STDMETHODIMP ChromeActiveDocument::GetAddressBarUrl(BSTR* url) {
  return GetUrlForEvents(url);
}

STDMETHODIMP ChromeActiveDocument::Reset() {
  next_privacy_record_ = privacy_info_.privacy_records.begin();
  return S_OK;
}

STDMETHODIMP ChromeActiveDocument::GetSize(DWORD* size) {
  if (!size)
    return E_POINTER;

  *size = privacy_info_.privacy_records.size();
  return S_OK;
}

STDMETHODIMP ChromeActiveDocument::GetPrivacyImpacted(BOOL* privacy_impacted) {
  if (!privacy_impacted)
    return E_POINTER;

  *privacy_impacted = privacy_info_.privacy_impacted;
  return S_OK;
}

STDMETHODIMP ChromeActiveDocument::Next(BSTR* url, BSTR* policy,
                                        LONG* reserved, DWORD* flags) {
  if (!url || !policy || !flags)
    return E_POINTER;

  if (next_privacy_record_ == privacy_info_.privacy_records.end())
    return HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS);

  *url = SysAllocString(next_privacy_record_->first.c_str());
  *policy = SysAllocString(next_privacy_record_->second.policy_ref.c_str());
  *flags = next_privacy_record_->second.flags;

  next_privacy_record_++;
  return S_OK;
}

bool ChromeActiveDocument::IsSchemeAllowed(const GURL& url) {
  bool allowed = BaseActiveX::IsSchemeAllowed(url);
  if (allowed)
    return true;

  if (url.SchemeIs(chrome::kAboutScheme)) {
    if (LowerCaseEqualsASCII(url.spec(), chrome::kAboutPluginsURL))
      return true;
  }
  return false;
}

HRESULT ChromeActiveDocument::GetInPlaceFrame(
    IOleInPlaceFrame** in_place_frame) {
  DCHECK(in_place_frame);
  if (in_place_frame_) {
    *in_place_frame = in_place_frame_.get();
    (*in_place_frame)->AddRef();
    return S_OK;
  } else {
    return S_FALSE;
  }
}

HRESULT ChromeActiveDocument::IOleObject_SetClientSite(
    IOleClientSite* client_site) {
  if (client_site == NULL) {
    base::win::ScopedComPtr<IDocHostUIHandler> doc_host_handler;
    if (doc_site_)
      doc_host_handler.QueryFrom(doc_site_);

    if (doc_host_handler.get())
      doc_host_handler->HideUI();

    doc_site_.Release();
  }

  if (client_site != m_spClientSite)
    return BaseActiveX::IOleObject_SetClientSite(client_site);

  return S_OK;
}

HRESULT ChromeActiveDocument::ActiveXDocActivate(LONG verb) {
  HRESULT hr = S_OK;
  m_bNegotiatedWnd = TRUE;
  if (!m_bInPlaceActive) {
    hr = m_spInPlaceSite->CanInPlaceActivate();
    if (FAILED(hr))
      return hr;
    m_spInPlaceSite->OnInPlaceActivate();
  }
  m_bInPlaceActive = TRUE;
  // get location in the parent window,
  // as well as some information about the parent
  base::win::ScopedComPtr<IOleInPlaceUIWindow> in_place_ui_window;
  frame_info_.cb = sizeof(OLEINPLACEFRAMEINFO);
  HWND parent_window = NULL;
  if (m_spInPlaceSite->GetWindow(&parent_window) == S_OK) {
    in_place_frame_.Release();
    RECT position_rect = {0};
    RECT clip_rect = {0};
    m_spInPlaceSite->GetWindowContext(in_place_frame_.Receive(),
                                      in_place_ui_window.Receive(),
                                      &position_rect,
                                      &clip_rect,
                                      &frame_info_);
    if (!m_bWndLess) {
      if (IsWindow()) {
        ::ShowWindow(m_hWnd, SW_SHOW);
        SetFocus();
      } else {
        m_hWnd = Create(parent_window, position_rect);
        if (!IsWindow()) {
          // This might happen if the automation server couldn't be
          // instantiated.  If so, a NOTREACHED() will have already been hit.
          DLOG(ERROR) << "Failed to create Ax window";
          return AtlHresultFromLastError();
        }
      }
    }
    SetObjectRects(&position_rect, &clip_rect);
  }

  base::win::ScopedComPtr<IOleInPlaceActiveObject> in_place_active_object(this);

  // Gone active by now, take care of UIACTIVATE
  if (DoesVerbUIActivate(verb)) {
    if (!m_bUIActive) {
      m_bUIActive = TRUE;
      hr = m_spInPlaceSite->OnUIActivate();
      if (FAILED(hr))
        return hr;
      // set ourselves up in the host
      if (in_place_active_object) {
        if (in_place_frame_)
          in_place_frame_->SetActiveObject(in_place_active_object, NULL);
        if (in_place_ui_window)
          in_place_ui_window->SetActiveObject(in_place_active_object, NULL);
      }
    }
  }
  m_spClientSite->ShowObject();
  return S_OK;
}

void ChromeActiveDocument::OnNavigationStateChanged(
    int flags, const NavigationInfo& nav_info) {
  // TODO(joshia): handle INVALIDATE_TYPE_TAB,INVALIDATE_TYPE_LOAD etc.
  DVLOG(1) << __FUNCTION__
           << "\n Flags: " << flags
           << ", Url: " << nav_info.url
           << ", Title: " << nav_info.title
           << ", Type: " << nav_info.navigation_type
           << ", Relative Offset: " << nav_info.relative_offset
           << ", Index: " << nav_info.navigation_index;

  UpdateNavigationState(nav_info, flags);
}

void ChromeActiveDocument::OnUpdateTargetUrl(
    const std::wstring& new_target_url) {
  if (in_place_frame_)
    in_place_frame_->SetStatusText(new_target_url.c_str());
}

bool IsFindAccelerator(const MSG& msg) {
  // TODO(robertshield): This may not stand up to localization. Fix if this
  // is the case.
  return msg.message == WM_KEYDOWN && msg.wParam == 'F' &&
         base::win::IsCtrlPressed() &&
         !(base::win::IsAltPressed() || base::win::IsShiftPressed());
}

void ChromeActiveDocument::OnAcceleratorPressed(const MSG& accel_message) {
  if (::TranslateAccelerator(m_hWnd, accelerator_table_,
                             const_cast<MSG*>(&accel_message)))
    return;

  bool handled_accel = false;
  if (in_place_frame_ != NULL) {
    handled_accel = (S_OK == in_place_frame_->TranslateAcceleratorW(
        const_cast<MSG*>(&accel_message), 0));
  }

  if (!handled_accel) {
    if (IsFindAccelerator(accel_message)) {
      // Handle the showing of the find dialog explicitly.
      OnFindInPage();
    } else {
      BaseActiveX::OnAcceleratorPressed(accel_message);
    }
  } else {
    DVLOG(1) << "IE handled accel key " << accel_message.wParam;
  }
}

void ChromeActiveDocument::OnTabbedOut(bool reverse) {
  DVLOG(1) << __FUNCTION__;
  if (in_place_frame_) {
    MSG msg = { NULL, WM_KEYDOWN, VK_TAB };
    in_place_frame_->TranslateAcceleratorW(&msg, 0);
  }
}

void ChromeActiveDocument::OnDidNavigate(const NavigationInfo& nav_info) {
  DVLOG(1) << __FUNCTION__ << std::endl
           << "Url: " << nav_info.url
           << ", Title: " << nav_info.title
           << ", Type: " << nav_info.navigation_type
           << ", Relative Offset: " << nav_info.relative_offset
           << ", Index: " << nav_info.navigation_index;

  CrashMetricsReporter::GetInstance()->IncrementMetric(
      CrashMetricsReporter::CHROME_FRAME_NAVIGATION_COUNT);

  UpdateNavigationState(nav_info, 0);
}

void ChromeActiveDocument::OnCloseTab() {
  // Base class will fire DIChromeFrameEvents::onclose.
  BaseActiveX::OnCloseTab();

  // Close the container window.
  base::win::ScopedComPtr<IWebBrowser2> web_browser2;
  DoQueryService(SID_SWebBrowserApp, m_spClientSite, web_browser2.Receive());
  if (web_browser2)
    web_browser2->Quit();
}

void ChromeActiveDocument::UpdateNavigationState(
    const NavigationInfo& new_navigation_info, int flags) {
  // This could be NULL if the active document instance is being destroyed.
  if (!m_spInPlaceSite) {
    DVLOG(1) << __FUNCTION__ << "m_spInPlaceSite is NULL. Returning";
    return;
  }

  HRESULT hr = S_OK;
  bool is_title_changed =
      (navigation_info_->title != new_navigation_info.title);
  bool is_ssl_state_changed =
      (navigation_info_->security_style !=
          new_navigation_info.security_style) ||
      (navigation_info_->displayed_insecure_content !=
          new_navigation_info.displayed_insecure_content) ||
      (navigation_info_->ran_insecure_content !=
          new_navigation_info.ran_insecure_content);

  if (is_ssl_state_changed) {
    int lock_status = SECURELOCK_SET_UNSECURE;
    switch (new_navigation_info.security_style) {
      case content::SECURITY_STYLE_AUTHENTICATED:
        lock_status = new_navigation_info.displayed_insecure_content ?
            SECURELOCK_SET_MIXED : SECURELOCK_SET_SECUREUNKNOWNBIT;
        break;
      default:
        break;
    }

    base::win::ScopedVariant secure_lock_status(lock_status);
    IEExec(&CGID_ShellDocView, INTERNAL_CMDID_SET_SSL_LOCK,
           OLECMDEXECOPT_DODEFAULT, secure_lock_status.AsInput(), NULL);
  }

  // A number of poorly written bho's crash in their event sink callbacks if
  // chrome frame is the currently loaded document. This is because they expect
  // chrome frame to implement interfaces like IHTMLDocument, etc. We patch the
  // event sink's of these bho's and don't invoke the event sink if chrome
  // frame is the currently loaded document.
  if (GetConfigBool(true, kEnableBuggyBhoIntercept)) {
    base::win::ScopedComPtr<IWebBrowser2> wb2;
    DoQueryService(SID_SWebBrowserApp, m_spClientSite, wb2.Receive());
    if (wb2 && buggy_bho::BuggyBhoTls::GetInstance()) {
      buggy_bho::BuggyBhoTls::GetInstance()->PatchBuggyBHOs(wb2);
    }
  }

  // Ideally all navigations should come to Chrome Frame so that we can call
  // BeforeNavigate2 on installed BHOs and give them a chance to cancel the
  // navigation. However, in practice what happens is as below:
  // The very first navigation that happens in CF happens via a Load or a
  // LoadHistory call. In this case, IE already has the correct information for
  // its travel log as well address bar. For other internal navigations (navs
  // that only happen within Chrome such as anchor navigations) we need to
  // update IE's internal state after the fact. In the case of internal
  // navigations, we notify the BHOs but ignore the should_cancel flag.

  // Another case where we need to issue BeforeNavigate2 calls is as below:-
  // We get notified after the fact, when navigations are initiated within
  // Chrome via window.open calls. These navigations are handled by creating
  // an external tab container within chrome and then connecting to it from IE.
  // We still want to update the address bar/history, etc, to ensure that
  // the special URL used by Chrome to indicate this is updated correctly.
  ChromeFrameUrl cf_url;
  bool is_attach_external_tab_url = cf_url.Parse(std::wstring(url_)) &&
      cf_url.attach_to_external_tab();

  bool is_internal_navigation =
      IsNewNavigation(new_navigation_info, flags) || is_attach_external_tab_url;

  if (new_navigation_info.url.is_valid())
    url_.Allocate(UTF8ToWide(new_navigation_info.url.spec()).c_str());

  if (is_internal_navigation) {
    // IE6 does not support tabs. If Chrome sent us a window open request
    // indicating that the navigation needs to occur in a foreground tab or
    // a popup window, then we need to ensure that the new window in IE6 is
    // brought to the foreground.
    if (GetIEVersion() == IE_6 &&
        is_attach_external_tab_url &&
        (cf_url.disposition() == NEW_FOREGROUND_TAB ||
         cf_url.disposition() == NEW_POPUP)) {
      base::win::ScopedComPtr<IWebBrowser2> wb2;
      DoQueryService(SID_SWebBrowserApp, m_spClientSite, wb2.Receive());
      if (wb2)
        BaseActiveX::BringWebBrowserWindowToTop(wb2);
    }
    base::win::ScopedComPtr<IDocObjectService> doc_object_svc;
    base::win::ScopedComPtr<IWebBrowserEventsService> web_browser_events_svc;

    DoQueryService(__uuidof(web_browser_events_svc), m_spClientSite,
                   web_browser_events_svc.Receive());

    if (!web_browser_events_svc.get()) {
      DoQueryService(SID_SShellBrowser, m_spClientSite,
                     doc_object_svc.Receive());
    }

    // web_browser_events_svc can be NULL on IE6.
    if (web_browser_events_svc) {
      VARIANT_BOOL should_cancel = VARIANT_FALSE;
      web_browser_events_svc->FireBeforeNavigate2Event(&should_cancel);
    } else if (doc_object_svc) {
      BOOL should_cancel = FALSE;
      doc_object_svc->FireBeforeNavigate2(NULL, url_, 0, NULL, NULL, 0,
                                          NULL, FALSE, &should_cancel);
    }

    // We need to tell IE that we support navigation so that IE will query us
    // for IPersistHistory and call GetPositionCookie to save our navigation
    // index.
    base::win::ScopedVariant html_window(static_cast<IUnknown*>(
        static_cast<IHTMLWindow2*>(this)));
    IEExec(&CGID_DocHostCmdPriv, DOCHOST_DOCCANNAVIGATE, 0,
           html_window.AsInput(), NULL);

    // We pass the HLNF_INTERNALJUMP flag to INTERNAL_CMDID_FINALIZE_TRAVEL_LOG
    // since we want to make IE treat all internal navigations within this page
    // (including anchor navigations and subframe navigations) as anchor
    // navigations. This will ensure that IE calls GetPositionCookie
    // to save the current position cookie in the travel log and then call
    // SetPositionCookie when the user hits Back/Forward to come back here.
    base::win::ScopedVariant internal_navigation(HLNF_INTERNALJUMP);
    IEExec(&CGID_Explorer, INTERNAL_CMDID_FINALIZE_TRAVEL_LOG, 0,
           internal_navigation.AsInput(), NULL);

    // We no longer need to lie to IE. If we lie persistently to IE, then
    // IE reuses us for new navigations.
    IEExec(&CGID_DocHostCmdPriv, DOCHOST_DOCCANNAVIGATE, 0, NULL, NULL);

    if (doc_object_svc) {
      // Now call the FireNavigateCompleteEvent which makes IE update the text
      // in the address-bar.
      doc_object_svc->FireNavigateComplete2(this, 0);
      doc_object_svc->FireDocumentComplete(this, 0);
    } else if (web_browser_events_svc) {
      web_browser_events_svc->FireNavigateComplete2Event();
      web_browser_events_svc->FireDocumentCompleteEvent();
    }
  }

  if (is_title_changed) {
    base::win::ScopedVariant title(new_navigation_info.title.c_str());
    IEExec(NULL, OLECMDID_SETTITLE, OLECMDEXECOPT_DONTPROMPTUSER,
           title.AsInput(), NULL);
  }

  // There are cases in which we receive NavigationStateChanged events for
  // provisional loads. These events will contain a new URL but will not be
  // considered new navigations since their navigation_index is 0. For these
  // events, do not update the navigation_info_ state, as this will muck up the
  // travel log when the subsequent committed navigation event takes place.
  //
  // Given this filtering, also special-case first navigations since those
  // are needed to initially populate navigation_info_ to keep it in sync with
  // what was placed in the IE travel log when CF was first opened.
  //
  // Lastly, allow through navigation events that would neither affect the
  // travel log nor cause the page location to change, as these will
  // contain informational state (referrer, title, etc.) that we should
  // preserve.
  if (is_internal_navigation || IsFirstNavigation(new_navigation_info) ||
      new_navigation_info.url == navigation_info_->url) {
    // It is important that we only update the navigation_info_ after we have
    // finalized the travel log. This is because IE will ask for information
    // such as navigation index when the travel log is finalized and we need
    // supply the old index and not the new one.
    *navigation_info_ = new_navigation_info;
  }

  // Update the IE zone here. Ideally we would like to do it when the active
  // document is activated. However that does not work at times as the frame we
  // get there is not the actual frame which handles the command.
  IEExec(&CGID_Explorer, SBCMDID_MIXEDZONE, 0, NULL, NULL);
}

void ChromeActiveDocument::OnFindInPage() {
  TabProxy* tab = GetTabProxy();
  if (tab) {
    if (!find_dialog_.IsWindow())
      find_dialog_.Create(m_hWnd);

    find_dialog_.ShowWindow(SW_SHOW);
  }
}

void ChromeActiveDocument::OnViewSource() {
  DCHECK(navigation_info_->url.is_valid());
  HostNavigate(GURL(content::kViewSourceScheme + std::string(":") +
      navigation_info_->url.spec()), GURL(), NEW_WINDOW);
}

void ChromeActiveDocument::OnDetermineSecurityZone(const GUID* cmd_group_guid,
                                                   DWORD command_id,
                                                   DWORD cmd_exec_opt,
                                                   VARIANT* in_args,
                                                   VARIANT* out_args) {
  // Always return URLZONE_INTERNET since that is the Chrome's behaviour.
  // Correct step is to use MapUrlToZone().
  if (out_args != NULL) {
    out_args->vt = VT_UI4;
    out_args->ulVal = URLZONE_INTERNET;
  }
}

void ChromeActiveDocument::OnDisplayPrivacyInfo() {
  privacy_info_ = url_fetcher_->privacy_info();
  Reset();
  DoPrivacyDlg(m_hWnd, url_, this, TRUE);
}

void ChromeActiveDocument::OnGetZoomRange(const GUID* cmd_group_guid,
                                          DWORD command_id,
                                          DWORD cmd_exec_opt,
                                          VARIANT* in_args,
                                          VARIANT* out_args) {
  if (out_args != NULL) {
    out_args->vt = VT_I4;
    out_args->lVal = 0;
  }
}

void ChromeActiveDocument::OnSetZoomRange(const GUID* cmd_group_guid,
                                          DWORD command_id,
                                          DWORD cmd_exec_opt,
                                          VARIANT* in_args,
                                          VARIANT* out_args) {
  const int kZoomIn = 125;
  const int kZoomOut = 75;

  if (in_args && V_VT(in_args) == VT_I4 && IsValid()) {
    if (in_args->lVal == kZoomIn) {
      automation_client_->SetZoomLevel(content::PAGE_ZOOM_IN);
    } else if (in_args->lVal == kZoomOut) {
      automation_client_->SetZoomLevel(content::PAGE_ZOOM_OUT);
    } else {
      DLOG(WARNING) << "Unsupported zoom level:" << in_args->lVal;
    }
  }
}

void ChromeActiveDocument::OnUnload(const GUID* cmd_group_guid,
                                    DWORD command_id,
                                    DWORD cmd_exec_opt,
                                    VARIANT* in_args,
                                    VARIANT* out_args) {
  if (IsValid() && out_args) {
    // If the navigation is attempted to the url loaded in CF, with the only
    // difference being the addition of an anchor, IE will attempt to unload
    // the currently loaded document which basically would end up running
    // unload handlers on the currently loaded document thus rendering it non
    // functional. We handle this as below:-
    // The BHO receives the new url in the BeforeNavigate event.
    // We compare the non anchor portions of the url in the BHO with the loaded
    // url and if they match, we initiate a Chrome navigation to the url with
    // the anchor which works nicely.
    // We don't want to continue processing the unload in this case.
    // Note:-
    // IE handles these navigations by querying the loaded document for
    // IHTMLDocument which then handles the new navigation. That won't work for
    // us as we don't implement IHTMLDocument.
    NavigationManager* mgr = NavigationManager::GetThreadInstance();
    DLOG_IF(ERROR, !mgr) << "Couldn't get instance of NavigationManager";
    if (mgr) {
      ChromeFrameUrl url;
      url.Parse(mgr->url());
      if (url.gurl().has_ref()) {
        url_canon::Replacements<char> replacements;
        replacements.ClearRef();

        if (url.gurl().ReplaceComponents(replacements) ==
            GURL(static_cast<BSTR>(url_))) {
          // We want to reuse the existing automation client and channel for
          // initiating the new navigation. Setting the
          // is_automation_client_reused_ flag to true before calling the
          // LaunchUrl function achieves that.
          is_automation_client_reused_ = true;
          LaunchUrl(url, mgr->referrer());
          out_args->vt = VT_BOOL;
          out_args->boolVal = VARIANT_FALSE;
          return;
        }
      }
    }
    bool should_unload = true;
    automation_client_->OnUnload(&should_unload);
    out_args->vt = VT_BOOL;
    out_args->boolVal = should_unload ? VARIANT_TRUE : VARIANT_FALSE;
  }
}

void ChromeActiveDocument::OnAttachExternalTab(
    const AttachExternalTabParams& params) {
  if (!automation_client_.get()) {
    DLOG(WARNING) << "Invalid automation client instance";
    return;
  }
  DWORD flags = 0;
  if (params.user_gesture)
    flags = NWMF_USERREQUESTED;
  else if (popup_allowed_)
    flags = NWMF_USERALLOWED;

  HRESULT hr = S_OK;
  if (popup_manager_) {
    const std::wstring& url_wide = UTF8ToWide(params.url.spec());
    hr = popup_manager_->EvaluateNewWindow(url_wide.c_str(), NULL, url_,
        NULL, FALSE, flags, 0);
  }
  // Allow popup
  if (hr == S_OK) {
    BaseActiveX::OnAttachExternalTab(params);
    return;
  }

  automation_client_->BlockExternalTab(params.cookie);
}

bool ChromeActiveDocument::PreProcessContextMenu(HMENU menu) {
  base::win::ScopedComPtr<IBrowserService> browser_service;
  base::win::ScopedComPtr<ITravelLog> travel_log;
  GetBrowserServiceAndTravelLog(browser_service.Receive(),
                                travel_log.Receive());
  if (!browser_service || !travel_log)
    return true;

  EnableMenuItem(menu, IDC_BACK, MF_BYCOMMAND |
      (SUCCEEDED(travel_log->GetTravelEntry(browser_service, TLOG_BACK,
                                            NULL)) ?
      MF_ENABLED : MF_DISABLED));
  EnableMenuItem(menu, IDC_FORWARD, MF_BYCOMMAND |
      (SUCCEEDED(travel_log->GetTravelEntry(browser_service, TLOG_FORE,
                                            NULL)) ?
      MF_ENABLED : MF_DISABLED));
  // Call base class (adds 'About' item)
  return BaseActiveX::PreProcessContextMenu(menu);
}

bool ChromeActiveDocument::HandleContextMenuCommand(
    UINT cmd, const MiniContextMenuParams& params) {
  base::win::ScopedComPtr<IWebBrowser2> web_browser2;
  DoQueryService(SID_SWebBrowserApp, m_spClientSite, web_browser2.Receive());

  if (cmd == IDC_BACK)
    web_browser2->GoBack();
  else if (cmd == IDC_FORWARD)
    web_browser2->GoForward();
  else if (cmd == IDC_RELOAD)
    web_browser2->Refresh();
  else
    return BaseActiveX::HandleContextMenuCommand(cmd, params);

  return true;
}

HRESULT ChromeActiveDocument::IEExec(const GUID* cmd_group_guid,
                                     DWORD command_id, DWORD cmd_exec_opt,
                                     VARIANT* in_args, VARIANT* out_args) {
  HRESULT hr = E_FAIL;

  base::win::ScopedComPtr<IOleCommandTarget> frame_cmd_target;

  base::win::ScopedComPtr<IOleInPlaceSite> in_place_site(m_spInPlaceSite);
  if (!in_place_site.get() && m_spClientSite != NULL)
    in_place_site.QueryFrom(m_spClientSite);

  if (in_place_site)
    hr = frame_cmd_target.QueryFrom(in_place_site);

  if (frame_cmd_target) {
    hr = frame_cmd_target->Exec(cmd_group_guid, command_id, cmd_exec_opt,
                                in_args, out_args);
  }

  return hr;
}

bool ChromeActiveDocument::LaunchUrl(const ChromeFrameUrl& cf_url,
                                     const std::string& referrer) {
  DCHECK(!cf_url.gurl().is_empty());

  if (!automation_client_.get()) {
    // http://code.google.com/p/chromium/issues/detail?id=52894
    // Still not sure how this happens.
    DLOG(ERROR) << "No automation client!";
    if (!Initialize()) {
      NOTREACHED() << "...and failed to start a new one >:(";
      return false;
    }
  }

  document_url_ = cf_url.gurl().spec();

  url_.Allocate(UTF8ToWide(cf_url.gurl().spec()).c_str());
  if (cf_url.attach_to_external_tab()) {
    automation_client_->AttachExternalTab(cf_url.cookie());
    OnMoveWindow(cf_url.dimensions());
  } else if (!automation_client_->InitiateNavigation(cf_url.gurl().spec(),
                                                     referrer,
                                                     this)) {
    DLOG(ERROR) << "Invalid URL: " << url_;
    Error(L"Invalid URL");
    url_.Reset();
    return false;
  }

  if (is_automation_client_reused_)
    return true;

  automation_client_->SetUrlFetcher(url_fetcher_.get());
  if (launch_params_) {
    return automation_client_->Initialize(this, launch_params_);
  } else {
    std::wstring profile = UTF8ToWide(cf_url.profile_name());
    // If no profile was given, then make use of the host process's name.
    if (profile.empty())
      profile = GetHostProcessName(false);
    return InitializeAutomation(profile, IsIEInPrivate(),
                                false, cf_url.gurl(), GURL(referrer),
                                false);
  }
}

HRESULT ChromeActiveDocument::OnRefreshPage(const GUID* cmd_group_guid,
    DWORD command_id, DWORD cmd_exec_opt, VARIANT* in_args, VARIANT* out_args) {
  DVLOG(1) << __FUNCTION__;
  popup_allowed_ = false;
  if (in_args->vt == VT_I4 &&
      in_args->lVal & OLECMDIDF_REFRESH_PAGEACTION_POPUPWINDOW) {
    popup_allowed_ = true;

    // Ask the yellow security band to change the text and icon and to remain
    // visible.
    IEExec(&CGID_DocHostCommandHandler, OLECMDID_PAGEACTIONBLOCKED,
        0x80000000 | OLECMDIDF_WINDOWSTATE_USERVISIBLE_VALID, NULL, NULL);
  }

  NavigationManager* mgr = NavigationManager::GetThreadInstance();
  DLOG_IF(ERROR, !mgr) << "Couldn't get instance of NavigationManager";

  // If ChromeFrame was activated on this page as a result of a document
  // received in response to a top level post, then we ask the user for
  // permission to repost and issue a navigation with the saved post data
  // which reinitates the whole sequence, i.e. the server receives the top
  // level post and chrome frame will be reactivated in response.
  if (mgr && mgr->post_data().type() != VT_EMPTY) {
    if (MessageBox(
            SimpleResourceLoader::Get(IDS_HTTP_POST_WARNING).c_str(),
            SimpleResourceLoader::Get(IDS_HTTP_POST_WARNING_TITLE).c_str(),
            MB_YESNO | MB_ICONEXCLAMATION) == IDYES) {
      base::win::ScopedComPtr<IWebBrowser2> web_browser2;
      DoQueryService(SID_SWebBrowserApp, m_spClientSite,
                     web_browser2.Receive());
      DCHECK(web_browser2);
      VARIANT empty = base::win::ScopedVariant::kEmptyVariant;
      VARIANT flags = { VT_I4 };
      V_I4(&flags) = navNoHistory;

      return web_browser2->Navigate2(base::win::ScopedVariant(url_).AsInput(),
                                     &flags,
                                     &empty,
                                     const_cast<VARIANT*>(&mgr->post_data()),
                                     const_cast<VARIANT*>(&mgr->headers()));
    } else {
      return S_OK;
    }
  }

  TabProxy* tab_proxy = GetTabProxy();
  if (tab_proxy) {
    tab_proxy->ReloadAsync();
  } else {
    DLOG(ERROR) << "No automation proxy";
    DCHECK(automation_client_.get() != NULL) << "how did it get freed?";
    // The current url request manager (url_fetcher_) has been switched to
    // a stopping state so we need to reset it and get a new one for the new
    // automation server.
    ResetUrlRequestManager();
    url_fetcher_->set_frame_busting(false);
    // And now launch the current URL again.  This starts a new server process.
    DCHECK(navigation_info_->url.is_valid());
    ChromeFrameUrl cf_url;
    cf_url.Parse(UTF8ToWide(navigation_info_->url.spec()));
    LaunchUrl(cf_url, navigation_info_->referrer.spec());
  }

  return S_OK;
}

HRESULT ChromeActiveDocument::SetPageFontSize(const GUID* cmd_group_guid,
                                              DWORD command_id,
                                              DWORD cmd_exec_opt,
                                              VARIANT* in_args,
                                              VARIANT* out_args) {
  if (!automation_client_.get()) {
    NOTREACHED() << "Invalid automation client";
    return E_FAIL;
  }

  switch (command_id) {
    case IDM_BASELINEFONT1:
      automation_client_->SetPageFontSize(SMALLEST_FONT);
      break;

    case IDM_BASELINEFONT2:
      automation_client_->SetPageFontSize(SMALL_FONT);
      break;

    case IDM_BASELINEFONT3:
      automation_client_->SetPageFontSize(MEDIUM_FONT);
      break;

    case IDM_BASELINEFONT4:
      automation_client_->SetPageFontSize(LARGE_FONT);
      break;

    case IDM_BASELINEFONT5:
      automation_client_->SetPageFontSize(LARGEST_FONT);
      break;

    default:
      NOTREACHED() << "Invalid font size command: "
                  << command_id;
      return E_FAIL;
  }

  // Forward the command back to IEFrame with group set to
  // CGID_ExplorerBarDoc. This is probably needed to update the menu state to
  // indicate that the font size was set. This currently fails with error
  // 0x80040104.
  // TODO(iyengar)
  // Do some investigation into why this Exec call fails.
  IEExec(&CGID_ExplorerBarDoc, command_id, cmd_exec_opt, NULL, NULL);
  return S_OK;
}

HRESULT ChromeActiveDocument::OnEncodingChange(const GUID* cmd_group_guid,
                                               DWORD command_id,
                                               DWORD cmd_exec_opt,
                                               VARIANT* in_args,
                                               VARIANT* out_args) {
  const struct EncodingMapData {
    DWORD ie_encoding_id;
    const char* chrome_encoding_name;
  } kEncodingTestDatas[] = {
#define DEFINE_ENCODING_MAP(encoding_name, id, chrome_name) \
    { encoding_name, chrome_name },
  INTERNAL_IE_ENCODINGMENU_IDS(DEFINE_ENCODING_MAP)
#undef DEFINE_ENCODING_MAP
  };

  if (!automation_client_.get()) {
    NOTREACHED() << "Invalid automtion client";
    return E_FAIL;
  }

  // Using ARRAYSIZE_UNSAFE in here is because we define the struct
  // EncodingMapData inside function.
  const char* chrome_encoding_name = NULL;
  for (int i = 0; i < ARRAYSIZE_UNSAFE(kEncodingTestDatas); ++i) {
    const struct EncodingMapData* encoding_data = &kEncodingTestDatas[i];
    if (command_id == encoding_data->ie_encoding_id) {
      chrome_encoding_name = encoding_data->chrome_encoding_name;
      break;
    }
  }
  // Return E_FAIL when encountering invalid encoding id.
  if (!chrome_encoding_name)
    return E_FAIL;

  TabProxy* tab = GetTabProxy();
  if (!tab) {
    NOTREACHED() << "Can not get TabProxy";
    return E_FAIL;
  }

  if (chrome_encoding_name)
    tab->OverrideEncoding(chrome_encoding_name);

  // Like we did on SetPageFontSize, we may forward the command back to IEFrame
  // to update the menu state to indicate that which encoding was set.
  // TODO(iyengar)
  // Do some investigation into why this Exec call fails.
  IEExec(&CGID_ExplorerBarDoc, command_id, cmd_exec_opt, NULL, NULL);
  return S_OK;
}

void ChromeActiveDocument::OnGoToHistoryEntryOffset(int offset) {
  DVLOG(1) <<  __FUNCTION__ << " - offset:" << offset;

  base::win::ScopedComPtr<IBrowserService> browser_service;
  base::win::ScopedComPtr<ITravelLog> travel_log;
  GetBrowserServiceAndTravelLog(browser_service.Receive(),
                                travel_log.Receive());

  if (browser_service && travel_log)
    travel_log->Travel(browser_service, offset);
}

void ChromeActiveDocument::OnMoveWindow(const gfx::Rect& dimensions) {
  base::win::ScopedComPtr<IWebBrowser2> web_browser2;
  DoQueryService(SID_SWebBrowserApp, m_spClientSite,
                 web_browser2.Receive());
  if (!web_browser2)
    return;
  DVLOG(1) << "this:" << this << "\ndimensions: width:" << dimensions.width()
           << " height:" << dimensions.height();
  if (!dimensions.IsEmpty()) {
    web_browser2->put_MenuBar(VARIANT_FALSE);
    web_browser2->put_ToolBar(VARIANT_FALSE);

    int width = dimensions.width();
    int height = dimensions.height();
    // Compute the size of the browser window given the desired size of the
    // content area. As per MSDN, the WebBrowser object returns an error from
    // this method. As a result the code below is best effort.
    web_browser2->ClientToWindow(&width, &height);

    web_browser2->put_Width(width);
    web_browser2->put_Height(height);
    web_browser2->put_Left(dimensions.x());
    web_browser2->put_Top(dimensions.y());
  }
}

HRESULT ChromeActiveDocument::GetBrowserServiceAndTravelLog(
    IBrowserService** browser_service, ITravelLog** travel_log) {
  DCHECK(browser_service || travel_log);
  base::win::ScopedComPtr<IBrowserService> browser_service_local;
  HRESULT hr = DoQueryService(SID_SShellBrowser, m_spClientSite,
                              browser_service_local.Receive());
  if (!browser_service_local) {
    NOTREACHED() << "DoQueryService for IBrowserService failed: " << hr;
    return hr;
  }

  if (travel_log) {
    hr = browser_service_local->GetTravelLog(travel_log);
    DVLOG_IF(1, !travel_log) << "browser_service->GetTravelLog failed: " << hr;
  }

  if (browser_service)
    *browser_service = browser_service_local.Detach();

  return hr;
}

LRESULT ChromeActiveDocument::OnForward(WORD notify_code, WORD id,
                                        HWND control_window,
                                        BOOL& bHandled) {
  base::win::ScopedComPtr<IWebBrowser2> web_browser2;
  DoQueryService(SID_SWebBrowserApp, m_spClientSite, web_browser2.Receive());
  DCHECK(web_browser2);

  if (web_browser2)
    web_browser2->GoForward();
  return 0;
}

LRESULT ChromeActiveDocument::OnBack(WORD notify_code, WORD id,
                                     HWND control_window,
                                     BOOL& bHandled) {
  base::win::ScopedComPtr<IWebBrowser2> web_browser2;
  DoQueryService(SID_SWebBrowserApp, m_spClientSite, web_browser2.Receive());
  DCHECK(web_browser2);

  if (web_browser2)
    web_browser2->GoBack();
  return 0;
}

LRESULT ChromeActiveDocument::OnFirePrivacyChange(UINT message, WPARAM wparam,
                                                  LPARAM lparam,
                                                  BOOL& handled) {
  if (!m_spClientSite)
    return 0;

  base::win::ScopedComPtr<IWebBrowser2> web_browser2;
  DoQueryService(SID_SWebBrowserApp, m_spClientSite,
                 web_browser2.Receive());
  if (!web_browser2) {
    NOTREACHED() << "Failed to retrieve IWebBrowser2 interface.";
    return 0;
  }

  base::win::ScopedComPtr<IShellBrowser> shell_browser;
  DoQueryService(SID_STopLevelBrowser, web_browser2,
                 shell_browser.Receive());
  DCHECK(shell_browser.get() != NULL);
  base::win::ScopedComPtr<ITridentService2> trident_services;
  trident_services.QueryFrom(shell_browser);
  if (trident_services)
    trident_services->FirePrivacyImpactedStateChange(wparam);
  else
    NOTREACHED() << "Failed to retrieve IWebBrowser2 interface.";
  return 0;
}

LRESULT ChromeActiveDocument::OnShowWindow(UINT message, WPARAM wparam,
                                           LPARAM lparam,
                                           BOOL& handled) {  // NO_LINT
  if (wparam)
    SetFocus();
  return 0;
}

LRESULT ChromeActiveDocument::OnSetFocus(UINT message, WPARAM wparam,
                                         LPARAM lparam,
                                         BOOL& handled) {  // NO_LINT
  if (!ignore_setfocus_)
    GiveFocusToChrome(false);
  return 0;
}

bool ChromeActiveDocument::IsNewNavigation(
    const NavigationInfo& new_navigation_info, int flags) const {
  // A new navigation is typically an internal navigation which is initiated by
  // the renderer(WebKit). Condition 1 below has to be true along with the
  // any of the other conditions below.
  // 1. The navigation notification flags passed in as the flags parameter
  //    is not INVALIDATE_TYPE_LOAD which indicates that the loading state of
  //    the tab changed.
  // 2. The navigation index is greater than 0 which means that a top level
  //    navigation was initiated on the current external tab.
  // 3. The navigation type has changed.
  // 4. The url or the referrer are different.
  if (flags == content::INVALIDATE_TYPE_LOAD)
    return false;

  if (new_navigation_info.navigation_index <= 0)
    return false;

  if (new_navigation_info.navigation_index ==
      navigation_info_->navigation_index)
    return false;

  if (new_navigation_info.navigation_type != navigation_info_->navigation_type)
    return true;

  if (new_navigation_info.url != navigation_info_->url)
    return true;

  if (new_navigation_info.referrer != navigation_info_->referrer)
    return true;

  return false;
}

bool ChromeActiveDocument::IsFirstNavigation(
    const NavigationInfo& new_navigation_info) const {
  return (navigation_info_->url.is_empty() &&
          new_navigation_info.navigation_type ==
              content::NAVIGATION_TYPE_NEW_PAGE);
}
