blob: 6768ee819c2e638b93230de128397b5c90731653 [file] [log] [blame]
// Copyright 2016 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_HISTORY_CORE_BROWSER_BROWSING_HISTORY_SERVICE_H_
#define COMPONENTS_HISTORY_CORE_BROWSER_BROWSING_HISTORY_SERVICE_H_
#include <stdint.h>
#include <memory>
#include <set>
#include <string>
#include <vector>
#include "base/functional/callback_forward.h"
#include "base/gtest_prod_util.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/scoped_observation.h"
#include "base/task/cancelable_task_tracker.h"
#include "base/time/clock.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "base/values.h"
#include "components/history/core/browser/history_service.h"
#include "components/history/core/browser/history_service_observer.h"
#include "components/history/core/browser/url_row.h"
#include "components/history/core/browser/web_history_service.h"
#include "components/history/core/browser/web_history_service_observer.h"
#include "components/sync/driver/sync_service.h"
#include "components/sync/driver/sync_service_observer.h"
#include "url/gurl.h"
FORWARD_DECLARE_TEST(BrowsingHistoryHandlerTest, ObservingWebHistoryDeletions);
namespace history {
class BrowsingHistoryDriver;
class QueryResults;
struct QueryOptions;
// Interacts with HistoryService, WebHistoryService, and SyncService to query
// history and provide results to the associated BrowsingHistoryDriver.
class BrowsingHistoryService : public HistoryServiceObserver,
public WebHistoryServiceObserver,
public syncer::SyncServiceObserver {
public:
// Represents a history entry to be shown to the user, representing either
// a local or remote visit. A single entry can represent multiple visits,
// since only the most recent visit on a particular day is shown.
struct HistoryEntry {
// Values indicating whether an entry represents only local visits, only
// remote visits, or a mixture of both.
enum EntryType {
EMPTY_ENTRY = 0,
LOCAL_ENTRY,
REMOTE_ENTRY,
COMBINED_ENTRY
};
HistoryEntry(EntryType type,
const GURL& url,
const std::u16string& title,
base::Time time,
const std::string& client_id,
bool is_search_result,
const std::u16string& snippet,
bool blocked_visit,
const GURL& remote_icon_url_for_uma,
int visit_count,
int typed_count);
HistoryEntry();
HistoryEntry(const HistoryEntry& other);
virtual ~HistoryEntry();
// Comparison function for sorting HistoryEntries from newest to oldest.
static bool SortByTimeDescending(const HistoryEntry& entry1,
const HistoryEntry& entry2);
// The type of visits this entry represents: local, remote, or both.
EntryType entry_type;
GURL url;
std::u16string title; // Title of the entry. May be empty.
// The time of the entry. Usually this will be the time of the most recent
// visit to `url` on a particular day as defined in the local timezone.
base::Time time;
// The sync ID of the client on which the most recent visit occurred.
std::string client_id;
// Timestamps of all local or remote visits the same URL on the same day.
// TODO(skym): These should probably be converted to base::Time.
std::set<int64_t> all_timestamps;
// If true, this entry is a search result.
bool is_search_result;
// The entry's search snippet, if this entry is a search result.
std::u16string snippet;
// Whether this entry was blocked when it was attempted.
bool blocked_visit;
// Optional parameter used to plumb footprints associated icon url.
GURL remote_icon_url_for_uma;
// Total number of times this URL has been visited.
int visit_count = 0;
// Number of times this URL has been manually entered in the URL bar.
int typed_count = 0;
};
// Contains information about a completed history query.
struct QueryResultsInfo {
~QueryResultsInfo();
// The query search text.
std::u16string search_text;
// Whether this query reached the end of all results, or if there are more
// history entries that can be fetched through paging.
bool reached_beginning = false;
// Whether the last call to Web History timed out.
bool sync_timed_out = false;
// Whether the last call to Web History returned successfully with a message
// body. During continuation queries we are not guaranteed to always make a
// call to WebHistory, and this value could reflect the state from previous
// queries.
bool has_synced_results = false;
};
BrowsingHistoryService(BrowsingHistoryDriver* driver,
HistoryService* local_history,
syncer::SyncService* sync_service);
BrowsingHistoryService(const BrowsingHistoryService&) = delete;
BrowsingHistoryService& operator=(const BrowsingHistoryService&) = delete;
~BrowsingHistoryService() override;
// Start a new query with the given parameters.
virtual void QueryHistory(const std::u16string& search_text,
const QueryOptions& options);
// Gets a version of the last time any webpage on the given host was visited,
// by using the min("last navigation time", x minutes ago) as the upper bound
// of the GetLastVisitToHost query. This is done in order to provide the user
// with a more useful sneak peak into their navigation history, by excluding
// the site(s) they were just on.
void GetLastVisitToHostBeforeRecentNavigations(
const std::string& host_name,
base::OnceCallback<void(base::Time)> callback);
// Removes `items` from history.
// TODO(tommycli): Update this API to take only URLs and timestamps, because
// callers only have that information, and only that information is used by
// the actual implementation.
void RemoveVisits(const std::vector<HistoryEntry>& items);
// SyncServiceObserver implementation.
void OnStateChanged(syncer::SyncService* sync) override;
protected:
// Constructor that allows specifying more dependencies for unit tests.
BrowsingHistoryService(BrowsingHistoryDriver* driver,
HistoryService* local_history,
syncer::SyncService* sync_service,
std::unique_ptr<base::OneShotTimer> web_history_timer);
// Should be used only for tests when mocking the service.
BrowsingHistoryService();
private:
FRIEND_TEST_ALL_PREFIXES(::BrowsingHistoryHandlerTest,
ObservingWebHistoryDeletions);
// Used to hold and track query state between asynchronous calls.
struct QueryHistoryState;
// Moves results from `state` into `results`, merging both remote and local
// results together and maintaining reverse chronological order. Any results
// with the same URL will be merged together for each day. Often holds back
// some results in `state` from one of the two sources to ensure that they're
// always returned to the driver in correct order. This function also updates
// the end times in `state` for both sources that the next query should be
// made against.
static void MergeDuplicateResults(QueryHistoryState* state,
std::vector<HistoryEntry>* results);
// Core implementation of history querying.
void QueryHistoryInternal(scoped_refptr<QueryHistoryState> state);
// Callback from the history system when a history query has completed.
void QueryComplete(scoped_refptr<QueryHistoryState> state,
QueryResults results);
// Callback from the history system when the last visit query has completed.
// May need to do a second query based on the results.
void OnLastVisitBeforeRecentNavigationsComplete(
const std::string& host_name,
base::Time query_start_time,
base::OnceCallback<void(base::Time)> callback,
HistoryLastVisitResult result);
// Callback from the history system when the last visit query has completed
// the second time.
void OnLastVisitBeforeRecentNavigationsComplete2(
base::OnceCallback<void(base::Time)> callback,
HistoryLastVisitResult result);
// Combines the query results from the local history database and the history
// server, and sends the combined results to the
// BrowsingHistoryDriver.
void ReturnResultsToDriver(scoped_refptr<QueryHistoryState> state);
// Callback from `web_history_timer_` when a response from web history has
// not been received in time.
void WebHistoryTimeout(scoped_refptr<QueryHistoryState> state);
// Callback from the WebHistoryService when a query has completed.
void WebHistoryQueryComplete(scoped_refptr<QueryHistoryState> state,
base::Time start_time,
WebHistoryService::Request* request,
const base::Value* results_value);
// Callback telling us whether other forms of browsing history were found
// on the history server.
void OtherFormsOfBrowsingHistoryQueryComplete(
bool found_other_forms_of_browsing_history);
// Callback from the history system when visits were deleted.
void RemoveComplete();
// Callback from history server when visits were deleted.
void RemoveWebHistoryComplete(bool success);
// HistoryServiceObserver implementation.
void OnURLsDeleted(HistoryService* history_service,
const DeletionInfo& deletion_info) override;
// WebHistoryServiceObserver implementation.
void OnWebHistoryDeleted() override;
// Tracker for search requests to the history service.
base::CancelableTaskTracker query_task_tracker_;
// The currently-executing request for synced history results.
// Deleting the request will cancel it.
std::unique_ptr<WebHistoryService::Request> web_history_request_;
// True if there is a pending delete requests to the web service.
bool has_pending_delete_request_ = false;
// Tracker for delete requests to the history service.
base::CancelableTaskTracker delete_task_tracker_;
// The list of URLs that are in the process of being deleted.
std::set<GURL> urls_to_be_deleted_;
// Timer used to implement a timeout on a Web History response.
std::unique_ptr<base::OneShotTimer> web_history_timer_;
// HistoryService (local history) observer.
base::ScopedObservation<HistoryService, HistoryServiceObserver>
history_service_observation_{this};
// WebHistoryService (synced history) observer.
base::ScopedObservation<WebHistoryService, WebHistoryServiceObserver>
web_history_service_observation_{this};
// SyncService observer listens to late initialization of history sync.
base::ScopedObservation<syncer::SyncService, syncer::SyncServiceObserver>
sync_service_observation_{this};
// Whether the last call to Web History returned synced results.
bool has_synced_results_ = false;
// Whether there are other forms of browsing history on the history server.
bool has_other_forms_of_browsing_history_ = false;
raw_ptr<BrowsingHistoryDriver> driver_;
raw_ptr<HistoryService> local_history_;
raw_ptr<syncer::SyncService> sync_service_;
// The clock used to vend times.
std::unique_ptr<base::Clock> clock_;
base::WeakPtrFactory<BrowsingHistoryService> weak_factory_{this};
};
} // namespace history
#endif // COMPONENTS_HISTORY_CORE_BROWSER_BROWSING_HISTORY_SERVICE_H_