Commit message: None
CVE: None
Vulnerability description: None

Project: Chrome

RenderViewImpl* RenderViewImpl::Create(
    int32 opener_id,
    const RendererPreferences& renderer_prefs,
    const WebPreferences& webkit_prefs,
    SharedRenderViewCounter* counter,
    int32 routing_id,
    int32 surface_id,
    int64 session_storage_namespace_id,
    const string16& frame_name,
    bool is_renderer_created,
    bool swapped_out,
    int32 next_page_id,
    const WebKit::WebScreenInfo& screen_info,
    AccessibilityMode accessibility_mode) {
  DCHECK(routing_id != MSG_ROUTING_NONE);
  RenderViewImplParams params(
      opener_id,
      renderer_prefs,
      webkit_prefs,
      counter,
      routing_id,
      surface_id,
      session_storage_namespace_id,
      frame_name,
      is_renderer_created,
      swapped_out,
      next_page_id,
      screen_info,
      accessibility_mode);
  if (g_create_render_view_impl)
    return g_create_render_view_impl(&params);
  return new RenderViewImpl(&params);
}

Project: Chrome

void RenderViewImpl::CreateFrameTree(WebKit::WebFrame* frame,
                                     DictionaryValue* frame_tree) {
  DCHECK(false);
  NavigateToSwappedOutURL(frame);

  string16 name;
  if (frame_tree->GetString(kFrameTreeNodeNameKey, &name) && !name.empty())
    frame->setName(name);

  int remote_id;
  if (frame_tree->GetInteger(kFrameTreeNodeIdKey, &remote_id))
    active_frame_id_map_.insert(std::pair<int, int>(frame->identifier(),
                                                    remote_id));

  ListValue* children;
  if (!frame_tree->GetList(kFrameTreeNodeSubtreeKey, &children))
    return;

  base::DictionaryValue* child;
  for (size_t i = 0; i < children->GetSize(); ++i) {
    if (!children->GetDictionary(i, &child))
      continue;
    WebElement element = frame->document().createElement("iframe");
    element.setAttribute("width", "0");
    element.setAttribute("height", "0");
    element.setAttribute("frameBorder", "0");
    if (frame->document().body().appendChild(element)) {
      WebFrame* subframe = WebFrame::fromFrameOwnerElement(element);
      if (subframe)
        CreateFrameTree(subframe, child);
    } else {
      LOG(ERROR) << "Failed to append created iframe element.";
    }
  }
}

Project: Chrome

webkit::npapi::WebPluginDelegate* RenderViewImpl::CreatePluginDelegate(
    const FilePath& file_path,
    const std::string& mime_type) {
  if (!PluginChannelHost::IsListening()) {
    LOG(ERROR) << "PluginChannelHost isn't listening";
    return NULL;
  }

  bool in_process_plugin = RenderProcess::current()->UseInProcessPlugins();
  if (in_process_plugin) {
#if defined(OS_WIN) && !defined(USE_AURA)
    return webkit::npapi::WebPluginDelegateImpl::Create(file_path, mime_type);
#else
    NOTIMPLEMENTED();
    return NULL;
#endif
  }

  return new WebPluginDelegateProxy(mime_type, AsWeakPtr());
}

Project: Chrome

WebKit::WebPlugin* RenderViewImpl::CreatePluginReplacement(
    const FilePath& file_path) {
  return GetContentClient()->renderer()->CreatePluginReplacement(
      this, file_path);
}

Project: Chrome

static void MaybeHandleDebugURL(const GURL& url) {
  if (!url.SchemeIs(chrome::kChromeUIScheme))
    return;
  if (url == GURL(chrome::kChromeUICrashURL)) {
    CrashIntentionally();
  } else if (url == GURL(chrome::kChromeUIKillURL)) {
    base::KillProcess(base::GetCurrentProcessHandle(), 1, false);
  } else if (url == GURL(chrome::kChromeUIHangURL)) {
    for (;;) {
      base::PlatformThread::Sleep(base::TimeDelta::FromSeconds(1));
    }
  } else if (url == GURL(kChromeUIShorthangURL)) {
    base::PlatformThread::Sleep(base::TimeDelta::FromSeconds(20));
  }
}

Project: Chrome

void RenderViewImpl::OnEnumerateDirectoryResponse(
    int id,
    const std::vector<FilePath>& paths) {
  if (!enumeration_completions_[id])
    return;

  WebVector<WebString> ws_file_names(paths.size());
  for (size_t i = 0; i < paths.size(); ++i)
    ws_file_names[i] = webkit_base::FilePathToWebString(paths[i]);

  enumeration_completions_[id]->didChooseFile(ws_file_names);
  enumeration_completions_.erase(id);
}

Project: Chrome

void RenderViewImpl::OnGetSerializedHtmlDataForCurrentPageWithLocalLinks(
    const std::vector<GURL>& links,
    const std::vector<FilePath>& local_paths,
    const FilePath& local_directory_name) {

  WebVector<WebURL> weburl_links(links);

  WebVector<WebString> webstring_paths(local_paths.size());
  for (size_t i = 0; i < local_paths.size(); i++)
    webstring_paths[i] = webkit_base::FilePathToWebString(local_paths[i]);

  WebPageSerializer::serialize(webview()->mainFrame(), true, this, weburl_links,
                               webstring_paths,
                               webkit_base::FilePathToWebString(
                                   local_directory_name));
}

Project: Chrome

bool RenderViewImpl::OnMessageReceived(const IPC::Message& message) {
  WebFrame* main_frame = webview() ? webview()->mainFrame() : NULL;
  if (main_frame)
    GetContentClient()->SetActiveURL(main_frame->document().url());

  ObserverListBase<RenderViewObserver>::Iterator it(observers_);
  RenderViewObserver* observer;
  while ((observer = it.GetNext()) != NULL)
    if (observer->OnMessageReceived(message))
      return true;

  bool handled = true;
  bool msg_is_ok = true;
  IPC_BEGIN_MESSAGE_MAP_EX(RenderViewImpl, message, msg_is_ok)
    IPC_MESSAGE_HANDLER(ViewMsg_Navigate, OnNavigate)
    IPC_MESSAGE_HANDLER(ViewMsg_Stop, OnStop)
    IPC_MESSAGE_HANDLER(ViewMsg_ReloadFrame, OnReloadFrame)
    IPC_MESSAGE_HANDLER(ViewMsg_Undo, OnUndo)
    IPC_MESSAGE_HANDLER(ViewMsg_Redo, OnRedo)
    IPC_MESSAGE_HANDLER(ViewMsg_Cut, OnCut)
    IPC_MESSAGE_HANDLER(ViewMsg_Copy, OnCopy)
    IPC_MESSAGE_HANDLER(ViewMsg_Paste, OnPaste)
    IPC_MESSAGE_HANDLER(ViewMsg_PasteAndMatchStyle, OnPasteAndMatchStyle)
    IPC_MESSAGE_HANDLER(ViewMsg_Replace, OnReplace)
    IPC_MESSAGE_HANDLER(ViewMsg_Delete, OnDelete)
    IPC_MESSAGE_HANDLER(ViewMsg_SetName, OnSetName)
    IPC_MESSAGE_HANDLER(ViewMsg_SelectAll, OnSelectAll)
    IPC_MESSAGE_HANDLER(ViewMsg_Unselect, OnUnselect)
    IPC_MESSAGE_HANDLER(ViewMsg_SetEditableSelectionOffsets,
                        OnSetEditableSelectionOffsets)
    IPC_MESSAGE_HANDLER(ViewMsg_SetCompositionFromExistingText,
                        OnSetCompositionFromExistingText)
    IPC_MESSAGE_HANDLER(ViewMsg_ExtendSelectionAndDelete,
                        OnExtendSelectionAndDelete)
    IPC_MESSAGE_HANDLER(ViewMsg_SelectRange, OnSelectRange)
    IPC_MESSAGE_HANDLER(ViewMsg_MoveCaret, OnMoveCaret)
    IPC_MESSAGE_HANDLER(ViewMsg_CopyImageAt, OnCopyImageAt)
    IPC_MESSAGE_HANDLER(ViewMsg_ExecuteEditCommand, OnExecuteEditCommand)
    IPC_MESSAGE_HANDLER(ViewMsg_Find, OnFind)
    IPC_MESSAGE_HANDLER(ViewMsg_StopFinding, OnStopFinding)
    IPC_MESSAGE_HANDLER(ViewMsg_Zoom, OnZoom)
    IPC_MESSAGE_HANDLER(ViewMsg_SetZoomLevel, OnSetZoomLevel)
    IPC_MESSAGE_HANDLER(ViewMsg_ZoomFactor, OnZoomFactor)
    IPC_MESSAGE_HANDLER(ViewMsg_SetZoomLevelForLoadingURL,
                        OnSetZoomLevelForLoadingURL)
    IPC_MESSAGE_HANDLER(ViewMsg_SetPageEncoding, OnSetPageEncoding)
    IPC_MESSAGE_HANDLER(ViewMsg_ResetPageEncodingToDefault,
                        OnResetPageEncodingToDefault)
    IPC_MESSAGE_HANDLER(ViewMsg_ScriptEvalRequest, OnScriptEvalRequest)
    IPC_MESSAGE_HANDLER(ViewMsg_PostMessageEvent, OnPostMessageEvent)
    IPC_MESSAGE_HANDLER(ViewMsg_CSSInsertRequest, OnCSSInsertRequest)
    IPC_MESSAGE_HANDLER(DragMsg_TargetDragEnter, OnDragTargetDragEnter)
    IPC_MESSAGE_HANDLER(DragMsg_TargetDragOver, OnDragTargetDragOver)
    IPC_MESSAGE_HANDLER(DragMsg_TargetDragLeave, OnDragTargetDragLeave)
    IPC_MESSAGE_HANDLER(DragMsg_TargetDrop, OnDragTargetDrop)
    IPC_MESSAGE_HANDLER(DragMsg_SourceEndedOrMoved, OnDragSourceEndedOrMoved)
    IPC_MESSAGE_HANDLER(DragMsg_SourceSystemDragEnded,
                        OnDragSourceSystemDragEnded)
    IPC_MESSAGE_HANDLER(ViewMsg_AllowBindings, OnAllowBindings)
    IPC_MESSAGE_HANDLER(ViewMsg_SetInitialFocus, OnSetInitialFocus)
    IPC_MESSAGE_HANDLER(ViewMsg_ScrollFocusedEditableNodeIntoRect,
                        OnScrollFocusedEditableNodeIntoRect)
    IPC_MESSAGE_HANDLER(ViewMsg_UpdateTargetURL_ACK, OnUpdateTargetURLAck)
    IPC_MESSAGE_HANDLER(ViewMsg_UpdateWebPreferences, OnUpdateWebPreferences)
    IPC_MESSAGE_HANDLER(ViewMsg_TimezoneChange, OnUpdateTimezone)
    IPC_MESSAGE_HANDLER(ViewMsg_SetAltErrorPageURL, OnSetAltErrorPageURL)
    IPC_MESSAGE_HANDLER(ViewMsg_EnumerateDirectoryResponse,
                        OnEnumerateDirectoryResponse)
    IPC_MESSAGE_HANDLER(ViewMsg_RunFileChooserResponse, OnFileChooserResponse)
    IPC_MESSAGE_HANDLER(ViewMsg_ShouldClose, OnShouldClose)
    IPC_MESSAGE_HANDLER(ViewMsg_SwapOut, OnSwapOut)
    IPC_MESSAGE_HANDLER(ViewMsg_ClosePage, OnClosePage)
    IPC_MESSAGE_HANDLER(ViewMsg_ThemeChanged, OnThemeChanged)
    IPC_MESSAGE_HANDLER(ViewMsg_DisassociateFromPopupCount,
                        OnDisassociateFromPopupCount)
    IPC_MESSAGE_HANDLER(ViewMsg_MoveOrResizeStarted, OnMoveOrResizeStarted)
    IPC_MESSAGE_HANDLER(ViewMsg_ClearFocusedNode, OnClearFocusedNode)
    IPC_MESSAGE_HANDLER(ViewMsg_SetBackground, OnSetBackground)
    IPC_MESSAGE_HANDLER(ViewMsg_EnablePreferredSizeChangedMode,
                        OnEnablePreferredSizeChangedMode)
    IPC_MESSAGE_HANDLER(ViewMsg_EnableAutoResize, OnEnableAutoResize)
    IPC_MESSAGE_HANDLER(ViewMsg_DisableAutoResize, OnDisableAutoResize)
    IPC_MESSAGE_HANDLER(ViewMsg_DisableScrollbarsForSmallWindows,
                        OnDisableScrollbarsForSmallWindows)
    IPC_MESSAGE_HANDLER(ViewMsg_SetRendererPrefs, OnSetRendererPrefs)
    IPC_MESSAGE_HANDLER(ViewMsg_MediaPlayerActionAt, OnMediaPlayerActionAt)
    IPC_MESSAGE_HANDLER(ViewMsg_OrientationChangeEvent,
                        OnOrientationChangeEvent)
    IPC_MESSAGE_HANDLER(ViewMsg_PluginActionAt, OnPluginActionAt)
    IPC_MESSAGE_HANDLER(ViewMsg_SetActive, OnSetActive)
    IPC_MESSAGE_HANDLER(ViewMsg_SetNavigationStartTime,
                        OnSetNavigationStartTime)
    IPC_MESSAGE_HANDLER(ViewMsg_SetEditCommandsForNextKeyEvent,
                        OnSetEditCommandsForNextKeyEvent)
    IPC_MESSAGE_HANDLER(ViewMsg_CustomContextMenuAction,
                        OnCustomContextMenuAction)
    IPC_MESSAGE_HANDLER(ViewMsg_AsyncOpenFile_ACK, OnAsyncFileOpened)
    IPC_MESSAGE_HANDLER(ViewMsg_PpapiBrokerChannelCreated,
                        OnPpapiBrokerChannelCreated)
    IPC_MESSAGE_HANDLER(ViewMsg_PpapiBrokerPermissionResult,
                        OnPpapiBrokerPermissionResult)
    IPC_MESSAGE_HANDLER(ViewMsg_GetAllSavableResourceLinksForCurrentPage,
                        OnGetAllSavableResourceLinksForCurrentPage)
    IPC_MESSAGE_HANDLER(
        ViewMsg_GetSerializedHtmlDataForCurrentPageWithLocalLinks,
        OnGetSerializedHtmlDataForCurrentPageWithLocalLinks)
    IPC_MESSAGE_HANDLER(ViewMsg_ContextMenuClosed, OnContextMenuClosed)
    IPC_MESSAGE_HANDLER(ViewMsg_SetHistoryLengthAndPrune,
                        OnSetHistoryLengthAndPrune)
    IPC_MESSAGE_HANDLER(ViewMsg_EnableViewSourceMode, OnEnableViewSourceMode)
    IPC_MESSAGE_HANDLER(JavaBridgeMsg_Init, OnJavaBridgeInit)
    IPC_MESSAGE_HANDLER(ViewMsg_SetAccessibilityMode, OnSetAccessibilityMode)
    IPC_MESSAGE_HANDLER(ViewMsg_DisownOpener, OnDisownOpener)
    IPC_MESSAGE_HANDLER(ViewMsg_UpdateFrameTree, OnUpdatedFrameTree)
#if defined(OS_ANDROID)
    IPC_MESSAGE_HANDLER(ViewMsg_ActivateNearestFindResult,
                        OnActivateNearestFindResult)
    IPC_MESSAGE_HANDLER(ViewMsg_FindMatchRects, OnFindMatchRects)
    IPC_MESSAGE_HANDLER(ViewMsg_SelectPopupMenuItems, OnSelectPopupMenuItems)
    IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewMsg_SynchronousFind, OnSynchronousFind)
    IPC_MESSAGE_HANDLER(ViewMsg_UndoScrollFocusedEditableNodeIntoView,
                        OnUndoScrollFocusedEditableNodeIntoRect)
#elif defined(OS_MACOSX)
    IPC_MESSAGE_HANDLER(ViewMsg_CopyToFindPboard, OnCopyToFindPboard)
    IPC_MESSAGE_HANDLER(ViewMsg_PluginImeCompositionCompleted,
                        OnPluginImeCompositionCompleted)
    IPC_MESSAGE_HANDLER(ViewMsg_SelectPopupMenuItem, OnSelectPopupMenuItem)
    IPC_MESSAGE_HANDLER(ViewMsg_SetInLiveResize, OnSetInLiveResize)
    IPC_MESSAGE_HANDLER(ViewMsg_SetWindowVisibility, OnSetWindowVisibility)
    IPC_MESSAGE_HANDLER(ViewMsg_WindowFrameChanged, OnWindowFrameChanged)
#endif
    IPC_MESSAGE_HANDLER(ViewMsg_ReleaseDisambiguationPopupDIB,
                        OnReleaseDisambiguationPopupDIB)
    IPC_MESSAGE_HANDLER(ViewMsg_WindowSnapshotCompleted,
                        OnWindowSnapshotCompleted)

    IPC_MESSAGE_UNHANDLED(handled = RenderWidget::OnMessageReceived(message))
  IPC_END_MESSAGE_MAP()

  if (!msg_is_ok) {
    CHECK(false) << "Unable to deserialize message in RenderViewImpl.";
  }

  return handled;
}

Project: Chrome

void RenderViewImpl::OnNavigate(const ViewMsg_Navigate_Params& params) {
  MaybeHandleDebugURL(params.url);
  if (!webview())
    return;

  FOR_EACH_OBSERVER(RenderViewObserver, observers_, Navigate(params.url));

  bool is_reload = IsReload(params);

  if (IsBackForwardToStaleEntry(params, is_reload))
    return;

  if (is_swapped_out_) {
    webview()->setVisibilityState(visibilityState(), false);

    is_reload = false;

    SetSwappedOut(false);
  }

  history_list_offset_ = params.current_history_list_offset;
  history_list_length_ = params.current_history_list_length;
  if (history_list_length_ >= 0)
    history_page_ids_.resize(history_list_length_, -1);
  if (params.pending_history_list_offset >= 0 &&
      params.pending_history_list_offset < history_list_length_)
    history_page_ids_[params.pending_history_list_offset] = params.page_id;

  GetContentClient()->SetActiveURL(params.url);

  WebFrame* main_frame = webview()->mainFrame();
  if (is_reload && main_frame->currentHistoryItem().isNull()) {
    is_reload = false;
  }

  pending_navigation_params_.reset(new ViewMsg_Navigate_Params(params));

  if (is_reload) {
    bool reload_original_url =
        (params.navigation_type ==
            ViewMsg_Navigate_Type::RELOAD_ORIGINAL_REQUEST_URL);
    bool ignore_cache = (params.navigation_type ==
                             ViewMsg_Navigate_Type::RELOAD_IGNORING_CACHE);

    if (reload_original_url)
      main_frame->reloadWithOverrideURL(params.url, true);
    else
      main_frame->reload(ignore_cache);
  } else if (!params.state.empty()) {
    DCHECK_NE(params.page_id, -1);
    WebHistoryItem item = webkit_glue::HistoryItemFromString(params.state);
    if (!item.isNull()) {
      CHECK(item.urlString() != WebString::fromUTF8(kSwappedOutURL));
      main_frame->loadHistoryItem(item);
    }
  } else if (!params.base_url_for_data_url.is_empty()) {
    std::string mime_type, charset, data;
    if (net::DataURL::Parse(params.url, &mime_type, &charset, &data)) {
      main_frame->loadData(
          WebData(data.c_str(), data.length()),
          WebString::fromUTF8(mime_type),
          WebString::fromUTF8(charset),
          params.base_url_for_data_url,
          params.history_url_for_data_url,
          false);
    } else {
      CHECK(false) <<
          "Invalid URL passed: " << params.url.possibly_invalid_spec();
    }
  } else {
    WebURLRequest request(params.url);

    CHECK_EQ(params.page_id, -1);

    if (main_frame->isViewSourceModeEnabled())
      request.setCachePolicy(WebURLRequest::ReturnCacheDataElseLoad);

    if (params.referrer.url.is_valid()) {
      WebString referrer = WebSecurityPolicy::generateReferrerHeader(
          params.referrer.policy,
          params.url,
          WebString::fromUTF8(params.referrer.url.spec()));
      if (!referrer.isEmpty())
        request.setHTTPHeaderField(WebString::fromUTF8("Referer"), referrer);
    }

    if (!params.extra_headers.empty()) {
      for (net::HttpUtil::HeadersIterator i(params.extra_headers.begin(),
                                            params.extra_headers.end(), "\n");
           i.GetNext(); ) {
        request.addHTTPHeaderField(WebString::fromUTF8(i.name()),
                                   WebString::fromUTF8(i.values()));
      }
    }

    if (params.is_post) {
      request.setHTTPMethod(WebString::fromUTF8("POST"));

      WebHTTPBody http_body;
      http_body.initialize();
      http_body.appendData(WebData(
          reinterpret_cast<const char*>(
              &params.browser_initiated_post_data.front()),
          params.browser_initiated_post_data.size()));
      request.setHTTPBody(http_body);
    }

    main_frame->loadRequest(request);
  }

  pending_navigation_params_.reset();
}

Project: Chrome

void RenderViewImpl::PluginCrashed(const FilePath& plugin_path,
                                   base::ProcessId plugin_pid) {
  Send(new ViewHostMsg_CrashedPlugin(routing_id_, plugin_path, plugin_pid));
}

Project: Chrome

void RenderViewImpl::ProcessAcceleratedPinchZoomFlags(
    const CommandLine& command_line) {
  if (!webview()->isAcceleratedCompositingActive())
    return;

  bool enable_viewport = command_line.HasSwitch(switches::kEnableViewport);
  bool enable_pinch = command_line.HasSwitch(switches::kEnablePinch)
      || command_line.HasSwitch(switches::kEnableCssTransformPinch);

  if (enable_viewport)
    return;

  if (enable_pinch)
    webview()->setPageScaleFactorLimits(1, 4);
  else
    webview()->setPageScaleFactorLimits(1, 1);
}

Project: Chrome

void RenderViewImpl::ProcessViewLayoutFlags(const CommandLine& command_line) {
  bool enable_viewport =
      command_line.HasSwitch(switches::kEnableViewport);
  bool enable_fixed_layout =
      command_line.HasSwitch(switches::kEnableFixedLayout);

  webview()->enableFixedLayoutMode(enable_fixed_layout || enable_viewport);
  webview()->settings()->setFixedElementsLayoutRelativeToFrame(true);

  if (!enable_viewport && enable_fixed_layout) {
    std::string str =
        command_line.GetSwitchValueASCII(switches::kEnableFixedLayout);
    std::vector<std::string> tokens;
    base::SplitString(str, ',', &tokens);
    if (tokens.size() == 2) {
      int width, height;
      if (base::StringToInt(tokens[0], &width) &&
          base::StringToInt(tokens[1], &height))
        webview()->setFixedLayoutSize(WebSize(width, height));
    }
  }

  ProcessAcceleratedPinchZoomFlags(command_line);
}

Project: Chrome

RenderViewImpl::RenderViewImpl(RenderViewImplParams* params)
    : RenderWidget(WebKit::WebPopupTypeNone,
                   params->screen_info,
                   params->swapped_out),
      webkit_preferences_(params->webkit_prefs),
      send_content_state_immediately_(false),
      enabled_bindings_(0),
      send_preferred_size_changes_(false),
      is_loading_(false),
      navigation_gesture_(NavigationGestureUnknown),
      opened_by_user_gesture_(true),
      opener_suppressed_(false),
      page_id_(-1),
      last_page_id_sent_to_browser_(-1),
      next_page_id_(params->next_page_id),
      history_list_offset_(-1),
      history_list_length_(0),
      target_url_status_(TARGET_NONE),
      selection_text_offset_(0),
      cached_is_main_frame_pinned_to_left_(false),
      cached_is_main_frame_pinned_to_right_(false),
      cached_has_main_frame_horizontal_scrollbar_(false),
      cached_has_main_frame_vertical_scrollbar_(false),
      ALLOW_THIS_IN_INITIALIZER_LIST(cookie_jar_(this)),
      geolocation_dispatcher_(NULL),
      input_tag_speech_dispatcher_(NULL),
      speech_recognition_dispatcher_(NULL),
      device_orientation_dispatcher_(NULL),
      media_stream_dispatcher_(NULL),
      browser_plugin_manager_(NULL),
      media_stream_impl_(NULL),
      devtools_agent_(NULL),
      accessibility_mode_(AccessibilityModeOff),
      renderer_accessibility_(NULL),
      java_bridge_dispatcher_(NULL),
      mouse_lock_dispatcher_(NULL),
      favicon_helper_(NULL),
#if defined(OS_ANDROID)
      body_background_color_(SK_ColorWHITE),
      update_frame_info_scheduled_(false),
      expected_content_intent_id_(0),
      media_player_proxy_(NULL),
      synchronous_find_active_match_ordinal_(-1),
      ALLOW_THIS_IN_INITIALIZER_LIST(
          load_progress_tracker_(new LoadProgressTracker(this))),
#endif
      session_storage_namespace_id_(params->session_storage_namespace_id),
      handling_select_range_(false),
      next_snapshot_id_(0),
#if defined(OS_WIN)
      focused_plugin_id_(-1),
#endif
      updating_frame_tree_(false),
      pending_frame_tree_update_(false),
      target_process_id_(0),
      target_routing_id_(0) {
#if defined(ENABLE_PLUGINS)
  pepper_helper_.reset(new PepperPluginDelegateImpl(this));
#else
  pepper_helper_.reset(new RenderViewPepperHelper());
#endif
  set_throttle_input_events(params->renderer_prefs.throttle_input_events);
  routing_id_ = params->routing_id;
  surface_id_ = params->surface_id;
  if (params->opener_id != MSG_ROUTING_NONE && params->is_renderer_created)
    opener_id_ = params->opener_id;

  DCHECK_GE(next_page_id_, 0);

#if defined(ENABLE_NOTIFICATIONS)
  notification_provider_ = new NotificationProvider(this);
#else
  notification_provider_ = NULL;
#endif

  webwidget_ = WebView::create(this);
  webwidget_mouse_lock_target_.reset(new WebWidgetLockTarget(webwidget_));

  const CommandLine& command_line = *CommandLine::ForCurrentProcess();

#if defined(OS_ANDROID)
  scoped_ptr<DeviceInfo> device_info(new DeviceInfo());

  const std::string region_code =
      command_line.HasSwitch(switches::kNetworkCountryIso)
          ? command_line.GetSwitchValueASCII(switches::kNetworkCountryIso)
          : device_info->GetNetworkCountryIso();
  content_detectors_.push_back(linked_ptr<ContentDetector>(
      new AddressDetector()));
  content_detectors_.push_back(linked_ptr<ContentDetector>(
      new PhoneNumberDetector(region_code)));
  content_detectors_.push_back(linked_ptr<ContentDetector>(
      new EmailDetector()));
#endif

  if (params->counter) {
    shared_popup_counter_ = params->counter;
    if (!params->swapped_out)
      shared_popup_counter_->data++;
    decrement_shared_popup_at_destruction_ = true;
  } else {
    shared_popup_counter_ = new SharedRenderViewCounter(0);
    decrement_shared_popup_at_destruction_ = false;
  }

  RenderThread::Get()->AddRoute(routing_id_, this);
  AddRef();

  if (opener_id_ == MSG_ROUTING_NONE) {
    did_show_ = true;
    CompleteInit();
  }

  g_view_map.Get().insert(std::make_pair(webview(), this));
  g_routing_id_view_map.Get().insert(std::make_pair(routing_id_, this));
  webview()->setDeviceScaleFactor(device_scale_factor_);
  webkit_preferences_.Apply(webview());
  webview()->initializeMainFrame(this);

  if (command_line.HasSwitch(switches::kEnableTouchDragDrop))
    webview()->settings()->setTouchDragDropEnabled(true);

  if (!params->frame_name.empty())
    webview()->mainFrame()->setName(params->frame_name);
  webview()->settings()->setMinimumTimerInterval(
      is_hidden() ? webkit_glue::kBackgroundTabTimerInterval :
          webkit_glue::kForegroundTabTimerInterval);

  OnSetRendererPrefs(params->renderer_prefs);

#if defined(ENABLE_WEBRTC)
  if (!media_stream_dispatcher_)
    media_stream_dispatcher_ = new MediaStreamDispatcher(this);
#endif

  new MHTMLGenerator(this);
#if defined(OS_MACOSX)
  new TextInputClientObserver(this);
#endif  // defined(OS_MACOSX)

#if defined(OS_ANDROID)
  media_player_manager_.reset(
      new webkit_media::WebMediaPlayerManagerAndroid());
#endif

  devtools_agent_ = new DevToolsAgent(this);
  mouse_lock_dispatcher_ = new RenderViewMouseLockDispatcher(this);
  intents_host_ = new WebIntentsHost(this);
  favicon_helper_ = new FaviconHelper(this);

  OnSetAccessibilityMode(params->accessibility_mode);

  new IdleUserDetector(this);

  if (command_line.HasSwitch(switches::kDomAutomationController))
    enabled_bindings_ |= BINDINGS_POLICY_DOM_AUTOMATION;

  ProcessViewLayoutFlags(command_line);

  GetContentClient()->renderer()->RenderViewCreated(this);

  if (params->opener_id != MSG_ROUTING_NONE && !params->is_renderer_created) {
    RenderViewImpl* opener_view = FromRoutingID(params->opener_id);
    if (opener_view)
      webview()->mainFrame()->setOpener(opener_view->webview()->mainFrame());
  }

  if (is_swapped_out_)
    NavigateToSwappedOutURL(webview()->mainFrame());
}

Project: Chrome

void RenderViewImpl::SetDeviceScaleFactor(float device_scale_factor) {
  RenderWidget::SetDeviceScaleFactor(device_scale_factor);
  if (webview())
    webview()->setDeviceScaleFactor(device_scale_factor);
}

Project: Chrome

void RenderViewImpl::SyncSelectionIfRequired() {
  WebFrame* frame = webview()->focusedFrame();
  if (!frame)
    return;

  string16 text;
  size_t offset;
  ui::Range range;
  if (pepper_helper_->IsPluginFocused()) {
    pepper_helper_->GetSurroundingText(&text, &range);
    offset = 0;  // Pepper API does not support offset reporting.
  } else {
    size_t location, length;
    if (!webview()->caretOrSelectionRange(&location, &length))
      return;

    range = ui::Range(location, location + length);

    if (webview()->textInputType() != WebKit::WebTextInputTypeNone) {
      if (location > kExtraCharsBeforeAndAfterSelection)
        offset = location - kExtraCharsBeforeAndAfterSelection;
      else
        offset = 0;
      length = location + length - offset + kExtraCharsBeforeAndAfterSelection;
      WebRange webrange = WebRange::fromDocumentRange(frame, offset, length);
      if (!webrange.isNull())
        text = WebRange::fromDocumentRange(frame, offset, length).toPlainText();
    } else {
      offset = location;
      text = frame->selectionAsText();
      range.set_end(range.start() + text.length());
    }
  }

  if (selection_text_offset_ != offset ||
      selection_range_ != range ||
      selection_text_ != text) {
    selection_text_ = text;
    selection_text_offset_ = offset;
    selection_range_ = range;
    Send(new ViewHostMsg_SelectionChanged(routing_id_, text, offset, range));
    UpdateTextInputState(SHOW_IME_IF_NEEDED);
  }
}

Project: Chrome

void RenderViewImpl::UpdateURL(WebFrame* frame) {
  WebDataSource* ds = frame->dataSource();
  DCHECK(ds);

  const WebURLRequest& request = ds->request();
  const WebURLRequest& original_request = ds->originalRequest();
  const WebURLResponse& response = ds->response();

  DocumentState* document_state = DocumentState::FromDataSource(ds);
  NavigationState* navigation_state = document_state->navigation_state();

  ViewHostMsg_FrameNavigate_Params params;
  params.http_status_code = response.httpStatusCode();
  params.is_post = false;
  params.post_id = -1;
  params.page_id = page_id_;
  params.frame_id = frame->identifier();
  params.socket_address.set_host(response.remoteIPAddress().utf8());
  params.socket_address.set_port(response.remotePort());
  params.was_fetched_via_proxy = response.wasFetchedViaProxy();
  params.was_within_same_page = navigation_state->was_within_same_page();
  if (!document_state->security_info().empty()) {
    DCHECK(response.securityInfo().isEmpty());
    params.security_info = document_state->security_info();
  } else {
    params.security_info = response.securityInfo();
  }

  params.url = GetLoadingUrl(frame);

  if (frame->document().baseURL() != params.url)
    params.base_url = frame->document().baseURL();

  GetRedirectChain(ds, &params.redirects);
  params.should_update_history = !ds->hasUnreachableURL() &&
      !response.isMultipartPayload() && (response.httpStatusCode() != 404);

  params.searchable_form_url = document_state->searchable_form_url();
  params.searchable_form_encoding =
      document_state->searchable_form_encoding();

  const PasswordForm* password_form_data =
      document_state->password_form_data();
  if (password_form_data)
    params.password_form = *password_form_data;

  params.gesture = navigation_gesture_;
  navigation_gesture_ = NavigationGestureUnknown;

  const WebHistoryItem& item = frame->currentHistoryItem();
  if (!item.isNull()) {
    params.content_state = webkit_glue::HistoryItemToString(item);
  } else {
    params.content_state =
        webkit_glue::CreateHistoryStateForURL(GURL(request.url()));
  }

  if (!frame->parent()) {

    webview()->zoomLimitsChanged(
        WebView::zoomFactorToZoomLevel(kMinimumZoomFactor),
        WebView::zoomFactorToZoomLevel(kMaximumZoomFactor));

    HostZoomLevels::iterator host_zoom =
        host_zoom_levels_.find(GURL(request.url()));
    if (webview()->mainFrame()->document().isPluginDocument()) {
      webview()->setZoomLevel(false, 0);
    } else {
      if (host_zoom != host_zoom_levels_.end())
        webview()->setZoomLevel(false, host_zoom->second);
    }

    if (host_zoom != host_zoom_levels_.end()) {
      host_zoom_levels_.erase(host_zoom);
    }

    params.contents_mime_type = ds->response().mimeType().utf8();

    params.transition = navigation_state->transition_type();
    if (!PageTransitionIsMainFrame(params.transition)) {
      params.transition = PAGE_TRANSITION_LINK;
    }

    if (completed_client_redirect_src_.url.is_valid()) {
      DCHECK(completed_client_redirect_src_.url == params.redirects[0]);
      params.referrer = completed_client_redirect_src_;
      params.transition = static_cast<PageTransition>(
          params.transition | PAGE_TRANSITION_CLIENT_REDIRECT);
    } else {
      params.referrer = Referrer(GURL(
          original_request.httpHeaderField(WebString::fromUTF8("Referer"))),
          GetReferrerPolicyFromRequest(frame, original_request));
    }

    string16 method = request.httpMethod();
    if (EqualsASCII(method, "POST")) {
      params.is_post = true;
      params.post_id = ExtractPostId(item);
    }

    params.is_overriding_user_agent =
        document_state->is_overriding_user_agent();

    params.original_request_url = original_request.url();

    UMA_HISTOGRAM_COUNTS_10000("Memory.GlyphPagesPerLoad",
                               webkit_glue::GetGlyphPageCount());

    Send(new ViewHostMsg_FrameNavigate(routing_id_, params));
  } else {
    if (page_id_ > last_page_id_sent_to_browser_)
      params.transition = PAGE_TRANSITION_MANUAL_SUBFRAME;
    else
      params.transition = PAGE_TRANSITION_AUTO_SUBFRAME;

    Send(new ViewHostMsg_FrameNavigate(routing_id_, params));
  }

  last_page_id_sent_to_browser_ =
      std::max(last_page_id_sent_to_browser_, page_id_);

  navigation_state->set_transition_type(PAGE_TRANSITION_LINK);
}

Project: Chrome

WebMediaPlayer* RenderViewImpl::createMediaPlayer(
    WebFrame* frame, const WebKit::WebURL& url, WebMediaPlayerClient* client) {
  FOR_EACH_OBSERVER(
      RenderViewObserver, observers_, WillCreateMediaPlayer(frame, client));

  const CommandLine* cmd_line = CommandLine::ForCurrentProcess();
#if defined(ENABLE_WEBRTC)
  if (!cmd_line->HasSwitch(switches::kDisableWebMediaPlayerMS) &&
      MediaStreamImpl::CheckMediaStream(url)) {
    EnsureMediaStreamImpl();
    return new webkit_media::WebMediaPlayerMS(
        frame, client, AsWeakPtr(), media_stream_impl_, new RenderMediaLog());
  }
#endif

#if defined(OS_ANDROID)
  WebGraphicsContext3D* resource_context =
      GetWebView()->sharedGraphicsContext3D();

  GpuChannelHost* gpu_channel_host =
      RenderThreadImpl::current()->EstablishGpuChannelSync(
          CAUSE_FOR_GPU_LAUNCH_VIDEODECODEACCELERATOR_INITIALIZE);
  if (!gpu_channel_host) {
    LOG(ERROR) << "Failed to establish GPU channel for media player";
    return NULL;
  }

  if (cmd_line->HasSwitch(switches::kMediaPlayerInRenderProcess)) {
    if (!media_bridge_manager_.get()) {
      media_bridge_manager_.reset(
          new webkit_media::MediaPlayerBridgeManagerImpl(1));
    }
    return new webkit_media::WebMediaPlayerInProcessAndroid(
        frame,
        client,
        cookieJar(frame),
        media_player_manager_.get(),
        media_bridge_manager_.get(),
        new StreamTextureFactoryImpl(
            resource_context, gpu_channel_host, routing_id_),
        cmd_line->HasSwitch(switches::kDisableMediaHistoryLogging));
  }
  if (!media_player_proxy_) {
    media_player_proxy_ = new WebMediaPlayerProxyImplAndroid(
        this, media_player_manager_.get());
  }
  return new webkit_media::WebMediaPlayerImplAndroid(
      frame,
      client,
      media_player_manager_.get(),
      media_player_proxy_,
      new StreamTextureFactoryImpl(
          resource_context, gpu_channel_host, routing_id_));
#endif

  scoped_refptr<media::AudioRendererSink> sink;
  if (!cmd_line->HasSwitch(switches::kDisableAudio)) {
#if defined(OS_WIN) || defined(OS_MACOSX)
    const bool use_mixing =
        !cmd_line->HasSwitch(switches::kDisableRendererSideMixing);
#else
    const bool use_mixing =
        cmd_line->HasSwitch(switches::kEnableRendererSideMixing);
#endif
    if (use_mixing) {
      sink = RenderThreadImpl::current()->GetAudioRendererMixerManager()->
          CreateInput(routing_id_);
      DVLOG(1) << "Using AudioRendererMixerManager-provided sink: " << sink;
    } else {
      scoped_refptr<RendererAudioOutputDevice> device =
          AudioDeviceFactory::NewOutputDevice();
      device->SetSourceRenderView(routing_id_);
      sink = device;
      DVLOG(1) << "Using AudioDeviceFactory-provided sink: " << sink;
    }
  }

  scoped_refptr<media::GpuVideoDecoder::Factories> gpu_factories;
  WebGraphicsContext3DCommandBufferImpl* context3d = NULL;
  if (!cmd_line->HasSwitch(switches::kDisableAcceleratedVideoDecode))
    context3d = RenderThreadImpl::current()->GetGpuVDAContext3D();
  if (context3d) {
    scoped_refptr<base::MessageLoopProxy> factories_loop =
        RenderThreadImpl::current()->compositor_thread() ?
        RenderThreadImpl::current()->compositor_thread()->GetWebThread()
            ->message_loop()->message_loop_proxy() :
        base::MessageLoopProxy::current();
    GpuChannelHost* gpu_channel_host =
        RenderThreadImpl::current()->EstablishGpuChannelSync(
            CAUSE_FOR_GPU_LAUNCH_VIDEODECODEACCELERATOR_INITIALIZE);
    gpu_factories = new RendererGpuVideoDecoderFactories(
        gpu_channel_host, factories_loop, context3d);
  }

  webkit_media::WebMediaPlayerParams params(
      sink, gpu_factories, media_stream_impl_, new RenderMediaLog());
  WebMediaPlayer* media_player =
      GetContentClient()->renderer()->OverrideCreateWebMediaPlayer(
          this, frame, client, AsWeakPtr(), params);
  if (!media_player) {
    media_player = new webkit_media::WebMediaPlayerImpl(
        frame, client, AsWeakPtr(), params);
  }
  return media_player;
}

Project: Chrome

WebNavigationPolicy RenderViewImpl::decidePolicyForNavigation(
    WebFrame* frame, const WebURLRequest& request, WebNavigationType type,
    const WebNode&, WebNavigationPolicy default_policy, bool is_redirect) {
  if (request.url() != GURL(kSwappedOutURL) &&
      GetContentClient()->renderer()->HandleNavigation(frame, request, type,
                                                       default_policy,
                                                       is_redirect)) {
    return WebKit::WebNavigationPolicyIgnore;
  }

  Referrer referrer(
      GURL(request.httpHeaderField(WebString::fromUTF8("Referer"))),
      GetReferrerPolicyFromRequest(frame, request));

  if (is_swapped_out_) {
    if (request.url() != GURL(kSwappedOutURL)) {
      if (frame->parent() == NULL) {
        OpenURL(frame, request.url(), referrer, default_policy);
        return WebKit::WebNavigationPolicyIgnore;  // Suppress the load here.
      }

      return WebKit::WebNavigationPolicyIgnore;
    }

    return default_policy;
  }

  const GURL& url = request.url();

  bool is_content_initiated =
      DocumentState::FromDataSource(frame->provisionalDataSource())->
          navigation_state()->is_content_initiated();

  const CommandLine& command_line = *CommandLine::ForCurrentProcess();
  bool force_swap_due_to_flag =
      command_line.HasSwitch(switches::kEnableStrictSiteIsolation) ||
      command_line.HasSwitch(switches::kSitePerProcess);
  if (force_swap_due_to_flag &&
      !frame->parent() && (is_content_initiated || is_redirect)) {
    WebString origin_str = frame->document().securityOrigin().toString();
    GURL frame_url(origin_str.utf8().data());
    if (!net::RegistryControlledDomainService::SameDomainOrHost(frame_url,
                                                                url) ||
        frame_url.scheme() != url.scheme()) {
      OpenURL(frame, url, referrer, default_policy);
      return WebKit::WebNavigationPolicyIgnore;
    }
  }

  if (is_content_initiated) {
    bool browser_handles_request =
        renderer_preferences_.browser_handles_non_local_top_level_requests &&
        IsNonLocalTopLevelNavigation(url, frame, type);
    if (!browser_handles_request) {
      browser_handles_request =
          renderer_preferences_.browser_handles_all_top_level_requests &&
          IsTopLevelNavigation(frame);
    }

    if (browser_handles_request) {
      page_id_ = -1;
      last_page_id_sent_to_browser_ = -1;
      OpenURL(frame, url, referrer, default_policy);
      return WebKit::WebNavigationPolicyIgnore;  // Suppress the load here.
    }
  }

  GURL old_url(frame->dataSource()->request().url());

  if (!frame->parent() && is_content_initiated &&
      !url.SchemeIs(chrome::kAboutScheme)) {
    bool send_referrer = false;

    int cumulative_bindings = RenderProcess::current()->GetEnabledBindings();
    bool is_initial_navigation = page_id_ == -1;
    bool should_fork =
        GetContentClient()->HasWebUIScheme(url) ||
        (cumulative_bindings & BINDINGS_POLICY_WEB_UI) ||
        url.SchemeIs(chrome::kViewSourceScheme) ||
        (frame->isViewSourceModeEnabled() &&
            type != WebKit::WebNavigationTypeReload);

    if (!should_fork && url.SchemeIs(chrome::kFileScheme)) {
      GURL source_url(old_url);
      if (is_initial_navigation && source_url.is_empty() && frame->opener())
        source_url = frame->opener()->top()->document().url();
      DCHECK(!source_url.is_empty());
      should_fork = !source_url.SchemeIs(chrome::kFileScheme);
    }

    if (!should_fork) {
      if (request.httpMethod() == "GET") {
        should_fork = GetContentClient()->renderer()->ShouldFork(
            frame, url, is_initial_navigation, &send_referrer);
      }
    }

    if (should_fork) {
      OpenURL(
          frame, url, send_referrer ? referrer : Referrer(), default_policy);
      return WebKit::WebNavigationPolicyIgnore;  // Suppress the load here.
    }
  }

  bool is_fork =
      old_url == GURL(chrome::kAboutBlankURL) &&
      historyBackListCount() < 1 &&
      historyForwardListCount() < 1 &&
      frame->opener() == NULL &&
      frame->parent() == NULL &&
      is_content_initiated &&
      default_policy == WebKit::WebNavigationPolicyCurrentTab &&
      type == WebKit::WebNavigationTypeOther;

  if (is_fork) {
    OpenURL(frame, url, Referrer(), default_policy);
    return WebKit::WebNavigationPolicyIgnore;
  }

  return default_policy;
}

Project: Chrome

void RenderViewImpl::didChangeContentsSize(WebFrame* frame,
                                           const WebSize& size) {
  if (webview()->mainFrame() != frame)
    return;
  WebView* frameView = frame->view();
  if (!frameView)
    return;

  bool has_horizontal_scrollbar = frame->hasHorizontalScrollbar();
  bool has_vertical_scrollbar = frame->hasVerticalScrollbar();

  if (has_horizontal_scrollbar != cached_has_main_frame_horizontal_scrollbar_ ||
      has_vertical_scrollbar != cached_has_main_frame_vertical_scrollbar_) {
    Send(new ViewHostMsg_DidChangeScrollbarsForMainFrame(
          routing_id_, has_horizontal_scrollbar, has_vertical_scrollbar));

    cached_has_main_frame_horizontal_scrollbar_ = has_horizontal_scrollbar;
    cached_has_main_frame_vertical_scrollbar_ = has_vertical_scrollbar;
  }

#if defined(OS_ANDROID)
  ScheduleUpdateFrameInfo();
#endif
}

Project: Chrome

void RenderViewImpl::didChangeScrollOffset(WebFrame* frame) {
  StartNavStateSyncTimerIfNecessary();

  if (webview()->mainFrame() == frame)
    UpdateScrollState(frame);

  FOR_EACH_OBSERVER(
      RenderViewObserver, observers_, DidChangeScrollOffset(frame));

#if defined(OS_ANDROID)
  if (webview()->mainFrame() == frame)
    ScheduleUpdateFrameInfo();
#endif
}

Project: Chrome

void RenderViewImpl::didCreateScriptContext(WebFrame* frame,
                                            v8::Handle<v8::Context> context,
                                            int extension_group,
                                            int world_id) {
  GetContentClient()->renderer()->DidCreateScriptContext(
      frame, context, extension_group, world_id);

  intents_host_->DidCreateScriptContext(
      frame, context, extension_group, world_id);
}

Project: Chrome

void RenderViewImpl::didHandleGestureEvent(const WebGestureEvent& event,
                                           bool event_swallowed) {
#if defined(OS_ANDROID)
  if (event.type == WebInputEvent::GestureTap ||
      event.type == WebInputEvent::GestureLongPress) {
    UpdateTextInputState(SHOW_IME_IF_NEEDED);
  }
#endif
  FOR_EACH_OBSERVER(RenderViewObserver, observers_,
                    DidHandleGestureEvent(event));
}

Project: Chrome

bool RenderViewImpl::didTapMultipleTargets(
    const WebKit::WebGestureEvent& event,
    const WebVector<WebRect>& target_rects) {
  gfx::Rect finger_rect(
      event.x - event.data.tap.width / 2, event.y - event.data.tap.height / 2,
      event.data.tap.width, event.data.tap.height);
  gfx::Rect zoom_rect;
  float scale = DisambiguationPopupHelper::ComputeZoomAreaAndScaleFactor(
      finger_rect, target_rects, GetSize(), &zoom_rect);
  if (!scale)
    return false;

  gfx::Size canvas_size = zoom_rect.size();
  canvas_size = ToCeiledSize(gfx::ScaleSize(canvas_size, scale));
  TransportDIB* transport_dib = NULL;
  {
    scoped_ptr<skia::PlatformCanvas> canvas(
        RenderProcess::current()->GetDrawingCanvas(&transport_dib,
                                                   gfx::Rect(canvas_size)));
    if (!canvas.get())
      return false;

    canvas->scale(scale, scale);

    canvas->translate(-zoom_rect.x(), -zoom_rect.y());
    webwidget_->paint(webkit_glue::ToWebCanvas(canvas.get()), zoom_rect,
        WebWidget::ForceSoftwareRenderingAndIgnoreGPUResidentContent);
  }
  Send(new ViewHostMsg_ShowDisambiguationPopup(routing_id_,
                                               zoom_rect,
                                               canvas_size,
                                               transport_dib->id()));

  return true;
}

Project: Chrome

bool RenderViewImpl::isPointerLocked() {
  return mouse_lock_dispatcher_->IsMouseLockedTo(
      webwidget_mouse_lock_target_.get());
 }

Project: Chrome

void RenderViewImpl::showContextMenu(
    WebFrame* frame, const WebContextMenuData& data) {
  ContextMenuParams params(data);

  string16 selection_text;
  if (!selection_text_.empty() && !selection_range_.is_empty()) {
    const int start = selection_range_.GetMin() - selection_text_offset_;
    const size_t length = selection_range_.length();
    if (start >= 0 && start + length <= selection_text_.length())
      selection_text = selection_text_.substr(start, length);
  }
  if (params.selection_text != selection_text) {
    selection_text_ = params.selection_text;
    selection_text_offset_ = 0;
    selection_range_ = ui::Range(0, selection_text_.length());
    Send(new ViewHostMsg_SelectionChanged(routing_id_,
                                          selection_text_,
                                          selection_text_offset_,
                                          selection_range_));
  }

  if (frame)
    params.frame_id = frame->identifier();

  if (params.src_url.spec().size() > kMaxURLChars)
    params.src_url = GURL();
  context_menu_node_ = data.node;

#if defined(OS_ANDROID)
  gfx::Rect start_rect;
  gfx::Rect end_rect;
  GetSelectionBounds(&start_rect, &end_rect);
  params.selection_start =
      gfx::Point(start_rect.x(), start_rect.bottom()) + GetScrollOffset();
  params.selection_end =
      gfx::Point(end_rect.right(), end_rect.bottom()) + GetScrollOffset();
#endif

  Send(new ViewHostMsg_ContextMenu(routing_id_, params));

  FOR_EACH_OBSERVER(
      RenderViewObserver, observers_, DidRequestShowContextMenu(frame, data));
}