blob: 8d9bf1e7363dde6cc4c53eed57b7d62b4e2966ed [file] [log] [blame]
[email protected]e41982a72012-11-20 07:16:511// Copyright 2012 The Chromium Authors. All rights reserved.
[email protected]fd2b9ce2010-08-11 04:03:572// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]03bb7102013-03-17 22:44:475#include "chrome/browser/ui/search/instant_controller.h"
[email protected]fd2b9ce2010-08-11 04:03:576
avi655876a2015-12-25 07:18:157#include <stddef.h>
dcheng4a9d9822015-12-26 22:35:308#include <utility>
avi655876a2015-12-25 07:18:159
Marc Treib5cacd242017-09-06 07:48:2510#include "base/bind.h"
11#include "base/callback.h"
Marc Treib5891b282017-08-22 09:44:3012#include "base/memory/ptr_util.h"
[email protected]f92d6582013-06-10 22:02:3613#include "base/strings/stringprintf.h"
[email protected]d58688c62013-07-03 23:09:1214#include "chrome/browser/profiles/profile.h"
[email protected]a7b8e43d2013-03-18 18:52:4315#include "chrome/browser/search/instant_service.h"
16#include "chrome/browser/search/instant_service_factory.h"
[email protected]4418dbb2012-10-25 03:21:5417#include "chrome/browser/ui/browser_instant_controller.h"
Marc Treib7376bd82017-09-26 08:03:2018#include "chrome/browser/ui/search/search_tab_helper.h"
Marc Treib5cacd242017-09-06 07:48:2519#include "content/public/browser/navigation_handle.h"
[email protected]3d6a8952012-12-14 03:18:0720#include "content/public/browser/web_contents.h"
Marc Treib5cacd242017-09-06 07:48:2521#include "content/public/browser/web_contents_observer.h"
22
23class InstantController::TabObserver : public content::WebContentsObserver {
24 public:
25 TabObserver(content::WebContents* web_contents, const base::Closure& callback)
26 : content::WebContentsObserver(web_contents), callback_(callback) {}
27 ~TabObserver() override = default;
28
29 private:
30 // Overridden from content::WebContentsObserver:
31 void DidFinishNavigation(
32 content::NavigationHandle* navigation_handle) override {
33 if (navigation_handle->HasCommitted() &&
34 navigation_handle->IsInMainFrame()) {
35 callback_.Run();
36 }
37 }
38
39 base::Closure callback_;
40
41 DISALLOW_COPY_AND_ASSIGN(TabObserver);
42};
[email protected]fd2b9ce2010-08-11 04:03:5743
Marc Treib7376bd82017-09-26 08:03:2044InstantController::InstantController(
45 BrowserInstantController* browser_instant_controller)
46 : browser_instant_controller_(browser_instant_controller) {
47 browser_instant_controller_->search_model()->AddObserver(this);
48}
[email protected]e41982a72012-11-20 07:16:5149
Marc Treib7376bd82017-09-26 08:03:2050InstantController::~InstantController() {
51 browser_instant_controller_->search_model()->RemoveObserver(this);
52}
[email protected]0c9406632013-02-08 01:13:3353
Marc Treib7376bd82017-09-26 08:03:2054void InstantController::ModelChanged(SearchModel::Origin old_origin,
55 SearchModel::Origin new_origin) {
56 // The search mode in the active tab has changed. Bind |instant_tab_observer_|
57 // if the |new_origin| reflects an Instant NTP.
58 // Note: This can be called either because the SearchMode changed within the
59 // current tab, or because the active tab changed. In the latter case, this
60 // gets called before ActiveTabChanged().
61 LogDebugEvent(
62 base::StringPrintf("ModelChanged: %d to %d", old_origin, new_origin));
[email protected]cd533bf2012-12-04 19:14:5963
[email protected]cd533bf2012-12-04 19:14:5964 ResetInstantTab();
[email protected]0b10c9ff2012-10-09 17:31:5565}
66
[email protected]e41982a72012-11-20 07:16:5167void InstantController::ActiveTabChanged() {
treibcdd79372016-07-25 13:20:1168 LogDebugEvent("ActiveTabChanged");
[email protected]d58688c62013-07-03 23:09:1269 ResetInstantTab();
[email protected]e41982a72012-11-20 07:16:5170}
71
[email protected]0c9406632013-02-08 01:13:3372void InstantController::LogDebugEvent(const std::string& info) const {
73 DVLOG(1) << info;
74
75 debug_events_.push_front(std::make_pair(
76 base::Time::Now().ToInternalValue(), info));
77 static const size_t kMaxDebugEventSize = 2000;
78 if (debug_events_.size() > kMaxDebugEventSize)
79 debug_events_.pop_back();
80}
81
[email protected]66be51812013-03-05 22:28:0982void InstantController::ClearDebugEvents() {
83 debug_events_.clear();
84}
85
Marc Treib5cacd242017-09-06 07:48:2586void InstantController::InstantTabAboutToNavigateMainFrame() {
87 DCHECK(instant_tab_observer_);
treib88978632017-05-16 15:42:1588 // The Instant tab navigated (which means it had instant support both before
89 // and after the navigation). This may cause it to be assigned to a new
90 // renderer process, which doesn't have the most visited/theme data yet, so
91 // send it now.
92 // TODO(treib): This seems unnecessarily convoluted and fragile. Can't we just
93 // send this when the Instant process is created?
[email protected]4ff347e2013-07-22 19:39:0094 UpdateInfoForInstantTab();
[email protected]a6827652012-11-20 23:41:0895}
96
[email protected]cd533bf2012-12-04 19:14:5997void InstantController::ResetInstantTab() {
Marc Treib7376bd82017-09-26 08:03:2098 content::WebContents* active_tab =
99 browser_instant_controller_->GetActiveWebContents();
100 if (active_tab &&
101 SearchTabHelper::FromWebContents(active_tab)->model()->origin() ==
102 SearchModel::Origin::NTP) {
103 // The active tab is an NTP. If we're not already tracking it, do so and
104 // also update the required info.
Marc Treib5cacd242017-09-06 07:48:25105 if (!instant_tab_observer_ ||
106 active_tab != instant_tab_observer_->web_contents()) {
107 instant_tab_observer_ = base::MakeUnique<TabObserver>(
108 active_tab,
109 base::Bind(&InstantController::InstantTabAboutToNavigateMainFrame,
110 base::Unretained(this)));
[email protected]8cc9e532013-05-06 21:01:47111 UpdateInfoForInstantTab();
[email protected]cd533bf2012-12-04 19:14:59112 }
[email protected]cd533bf2012-12-04 19:14:59113 } else {
Marc Treib7376bd82017-09-26 08:03:20114 instant_tab_observer_ = nullptr;
[email protected]cd533bf2012-12-04 19:14:59115 }
[email protected]0a387472010-10-07 00:18:20116}
117
[email protected]8cc9e532013-05-06 21:01:47118void InstantController::UpdateInfoForInstantTab() {
Marc Treib5cacd242017-09-06 07:48:25119 DCHECK(instant_tab_observer_);
Marc Treib7376bd82017-09-26 08:03:20120 InstantService* instant_service = InstantServiceFactory::GetForProfile(
121 browser_instant_controller_->profile());
treib93f4a872017-04-28 13:29:52122 if (instant_service) {
123 instant_service->UpdateThemeInfo();
124 instant_service->UpdateMostVisitedItemsInfo();
[email protected]8cc9e532013-05-06 21:01:47125 }
126}