1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file. 4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/extensions/extension_history_api.h" 6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/callback.h" 8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/json/json_writer.h" 9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/message_loop.h" 103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/string_number_conversions.h" 11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/task.h" 12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/values.h" 13731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "chrome/browser/extensions/extension_event_router.h" 14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/extensions/extension_history_api_constants.h" 15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/history/history.h" 16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/history/history_types.h" 1721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/profiles/profile.h" 18ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/notification_service.h" 19ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/notification_type.h" 20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace keys = extension_history_api_constants; 22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace { 24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochdouble MilliSecondsFromTime(const base::Time& time) { 26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return 1000 * time.ToDoubleT(); 27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid GetHistoryItemDictionary(const history::URLRow& row, 30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DictionaryValue* value) { 313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick value->SetString(keys::kIdKey, base::Int64ToString(row.id())); 32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch value->SetString(keys::kUrlKey, row.url().spec()); 333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick value->SetString(keys::kTitleKey, row.title()); 3472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen value->SetDouble(keys::kLastVisitdKey, 3572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen MilliSecondsFromTime(row.last_visit())); 36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch value->SetInteger(keys::kTypedCountKey, row.typed_count()); 37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch value->SetInteger(keys::kVisitCountKey, row.visit_count()); 38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid AddHistoryNode(const history::URLRow& row, ListValue* list) { 41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DictionaryValue* dict = new DictionaryValue(); 42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GetHistoryItemDictionary(row, dict); 43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch list->Append(dict); 44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid GetVisitInfoDictionary(const history::VisitRow& row, 47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DictionaryValue* value) { 483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick value->SetString(keys::kIdKey, base::Int64ToString(row.url_id)); 493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick value->SetString(keys::kVisitId, base::Int64ToString(row.visit_id)); 5072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen value->SetDouble(keys::kVisitTime, MilliSecondsFromTime(row.visit_time)); 51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch value->SetString(keys::kReferringVisitId, 523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick base::Int64ToString(row.referring_visit)); 53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const char* trans = PageTransition::CoreTransitionString(row.transition); 55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(trans) << "Invalid transition."; 56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch value->SetString(keys::kTransition, trans); 57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid AddVisitNode(const history::VisitRow& row, ListValue* list) { 60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DictionaryValue* dict = new DictionaryValue(); 61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GetVisitInfoDictionary(row, dict); 62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch list->Append(dict); 63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} // namespace 66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 67c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochExtensionHistoryEventRouter* ExtensionHistoryEventRouter::GetInstance() { 68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return Singleton<ExtensionHistoryEventRouter>::get(); 69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ExtensionHistoryEventRouter::ObserveProfile(Profile* profile) { 72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NotificationSource source = Source<Profile>(profile); 73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (profiles_.find(source.map_key()) == profiles_.end()) 74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch profiles_[source.map_key()] = profile; 75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (registrar_.IsEmpty()) { 77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch registrar_.Add(this, 78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NotificationType::HISTORY_URL_VISITED, 79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NotificationService::AllSources()); 80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch registrar_.Add(this, 81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NotificationType::HISTORY_URLS_DELETED, 82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NotificationService::AllSources()); 83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 86731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickExtensionHistoryEventRouter::ExtensionHistoryEventRouter() {} 87731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 88731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickExtensionHistoryEventRouter::~ExtensionHistoryEventRouter() {} 89731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ExtensionHistoryEventRouter::Observe(NotificationType type, 91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const NotificationSource& source, 92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const NotificationDetails& details) { 93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ProfileMap::iterator it = profiles_.find(source.map_key()); 94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (it != profiles_.end()) { 95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Profile* profile = it->second; 96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch switch (type.value) { 97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case NotificationType::HISTORY_URL_VISITED: 98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HistoryUrlVisited( 99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch profile, 100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Details<const history::URLVisitedDetails>(details).ptr()); 101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case NotificationType::HISTORY_URLS_DELETED: 103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HistoryUrlsRemoved( 104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch profile, 105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Details<const history::URLsDeletedDetails>(details).ptr()); 106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch default: 108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NOTREACHED(); 109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ExtensionHistoryEventRouter::HistoryUrlVisited( 114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Profile* profile, 115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const history::URLVisitedDetails* details) { 116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ListValue args; 117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DictionaryValue* dict = new DictionaryValue(); 118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GetHistoryItemDictionary(details->row, dict); 119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch args.Append(dict); 120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string json_args; 122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch base::JSONWriter::Write(&args, false, &json_args); 123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DispatchEvent(profile, keys::kOnVisited, json_args); 124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ExtensionHistoryEventRouter::HistoryUrlsRemoved( 127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Profile* profile, 128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const history::URLsDeletedDetails* details) { 129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ListValue args; 130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DictionaryValue* dict = new DictionaryValue(); 131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch dict->SetBoolean(keys::kAllHistoryKey, details->all_history); 132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ListValue* urls = new ListValue(); 133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (std::set<GURL>::const_iterator iterator = details->urls.begin(); 134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch iterator != details->urls.end(); 135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ++iterator) { 136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch urls->Append(new StringValue(iterator->spec())); 137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch dict->Set(keys::kUrlsKey, urls); 139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch args.Append(dict); 140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string json_args; 142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch base::JSONWriter::Write(&args, false, &json_args); 143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DispatchEvent(profile, keys::kOnVisitRemoved, json_args); 144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ExtensionHistoryEventRouter::DispatchEvent(Profile* profile, 147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const char* event_name, 148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const std::string& json_args) { 149731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (profile && profile->GetExtensionEventRouter()) { 150731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick profile->GetExtensionEventRouter()->DispatchEventToRenderers( 1513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick event_name, json_args, profile, GURL()); 152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid HistoryFunction::Run() { 156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!RunImpl()) { 157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SendResponse(false); 158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool HistoryFunction::GetUrlFromValue(Value* value, GURL* url) { 162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string url_string; 163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!value->GetAsString(&url_string)) { 164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bad_message_ = true; 165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GURL temp_url(url_string); 169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!temp_url.is_valid()) { 170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch error_ = keys::kInvalidUrlError; 171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch url->Swap(&temp_url); 174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool HistoryFunction::GetTimeFromValue(Value* value, base::Time* time) { 178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch double ms_from_epoch = 0.0; 17972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (!value->GetAsDouble(&ms_from_epoch)) { 180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int ms_from_epoch_as_int = 0; 181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!value->GetAsInteger(&ms_from_epoch_as_int)) 182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ms_from_epoch = static_cast<double>(ms_from_epoch_as_int); 184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The history service has seconds resolution, while javascript Date() has 186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // milliseconds resolution. 187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch double seconds_from_epoch = ms_from_epoch / 1000.0; 1883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Time::FromDoubleT converts double time 0 to empty Time object. So we need 1893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // to do special handling here. 1903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick *time = (seconds_from_epoch == 0) ? 1913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick base::Time::UnixEpoch() : base::Time::FromDoubleT(seconds_from_epoch); 192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1953345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickHistoryFunctionWithCallback::HistoryFunctionWithCallback() { 1963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 1973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1983345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickHistoryFunctionWithCallback::~HistoryFunctionWithCallback() { 1993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 2003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool HistoryFunctionWithCallback::RunImpl() { 202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch AddRef(); // Balanced in SendAysncRepose() and below. 203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool retval = RunAsyncImpl(); 204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (false == retval) 205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Release(); 206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return retval; 207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid HistoryFunctionWithCallback::SendAsyncResponse() { 210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MessageLoop::current()->PostTask( 211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch FROM_HERE, 212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NewRunnableMethod( 213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch this, 214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &HistoryFunctionWithCallback::SendResponseToCallback)); 215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid HistoryFunctionWithCallback::SendResponseToCallback() { 218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SendResponse(true); 219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Release(); // Balanced in RunImpl(). 220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool GetVisitsHistoryFunction::RunAsyncImpl() { 223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DictionaryValue* json; 224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &json)); 225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Value* value; 227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXTENSION_FUNCTION_VALIDATE(json->Get(keys::kUrlKey, &value)); 228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GURL url; 230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!GetUrlFromValue(value, &url)) 231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HistoryService* hs = profile()->GetHistoryService(Profile::EXPLICIT_ACCESS); 234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch hs->QueryURL(url, 235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch true, // Retrieve full history of a URL. 236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &cancelable_consumer_, 237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NewCallback(this, &GetVisitsHistoryFunction::QueryComplete)); 238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid GetVisitsHistoryFunction::QueryComplete( 243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HistoryService::Handle request_service, 244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool success, 245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const history::URLRow* url_row, 246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch history::VisitVector* visits) { 247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ListValue* list = new ListValue(); 248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (visits && !visits->empty()) { 249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (history::VisitVector::iterator iterator = visits->begin(); 250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch iterator != visits->end(); 251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ++iterator) { 252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch AddVisitNode(*iterator, list); 253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch result_.reset(list); 256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SendAsyncResponse(); 257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool SearchHistoryFunction::RunAsyncImpl() { 260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DictionaryValue* json; 261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &json)); 262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Initialize the HistoryQuery 264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch string16 search_text; 2653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXTENSION_FUNCTION_VALIDATE(json->GetString(keys::kTextKey, &search_text)); 266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 267c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch history::QueryOptions options; 268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch options.SetRecentDayRange(1); 269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch options.max_count = 100; 270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (json->HasKey(keys::kStartTimeKey)) { // Optional. 272c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Value* value; 273c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXTENSION_FUNCTION_VALIDATE(json->Get(keys::kStartTimeKey, &value)); 274c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXTENSION_FUNCTION_VALIDATE(GetTimeFromValue(value, &options.begin_time)); 275c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 276c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (json->HasKey(keys::kEndTimeKey)) { // Optional. 277c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Value* value; 278c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXTENSION_FUNCTION_VALIDATE(json->Get(keys::kEndTimeKey, &value)); 279c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXTENSION_FUNCTION_VALIDATE(GetTimeFromValue(value, &options.end_time)); 280c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 281c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (json->HasKey(keys::kMaxResultsKey)) { // Optional. 282c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXTENSION_FUNCTION_VALIDATE(json->GetInteger(keys::kMaxResultsKey, 283c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &options.max_count)); 284c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 285c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 286c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HistoryService* hs = profile()->GetHistoryService(Profile::EXPLICIT_ACCESS); 287c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch hs->QueryHistory(search_text, options, &cancelable_consumer_, 288c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NewCallback(this, &SearchHistoryFunction::SearchComplete)); 289c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 290c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 291c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 292c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 293c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid SearchHistoryFunction::SearchComplete( 294c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HistoryService::Handle request_handle, 295c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch history::QueryResults* results) { 296c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ListValue* list = new ListValue(); 297c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (results && !results->empty()) { 298c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (history::QueryResults::URLResultVector::const_iterator iterator = 299c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch results->begin(); 300c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch iterator != results->end(); 301c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ++iterator) { 302c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch AddHistoryNode(**iterator, list); 303c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 304c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 305c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch result_.reset(list); 306c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SendAsyncResponse(); 307c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 308c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 309c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool AddUrlHistoryFunction::RunImpl() { 310c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DictionaryValue* json; 311c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &json)); 312c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 313c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Value* value; 314c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXTENSION_FUNCTION_VALIDATE(json->Get(keys::kUrlKey, &value)); 315c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 316c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GURL url; 317c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!GetUrlFromValue(value, &url)) 318c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 319c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 320c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HistoryService* hs = profile()->GetHistoryService(Profile::EXPLICIT_ACCESS); 3213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick hs->AddPage(url, history::SOURCE_EXTENSION); 322c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 323c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SendResponse(true); 324c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 325c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 326c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 327c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool DeleteUrlHistoryFunction::RunImpl() { 328c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DictionaryValue* json; 329c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &json)); 330c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 331c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Value* value; 332c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXTENSION_FUNCTION_VALIDATE(json->Get(keys::kUrlKey, &value)); 333c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 334c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GURL url; 335c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!GetUrlFromValue(value, &url)) 336c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 337c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 338c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HistoryService* hs = profile()->GetHistoryService(Profile::EXPLICIT_ACCESS); 339c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch hs->DeleteURL(url); 340c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 341c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SendResponse(true); 342c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 343c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 344c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 345c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool DeleteRangeHistoryFunction::RunAsyncImpl() { 346c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DictionaryValue* json; 347c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &json)); 348c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 349c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Value* value = NULL; 350c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXTENSION_FUNCTION_VALIDATE(json->Get(keys::kStartTimeKey, &value)); 351c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch base::Time begin_time; 352c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXTENSION_FUNCTION_VALIDATE(GetTimeFromValue(value, &begin_time)); 353c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 354c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXTENSION_FUNCTION_VALIDATE(json->Get(keys::kEndTimeKey, &value)); 355c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch base::Time end_time; 356c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXTENSION_FUNCTION_VALIDATE(GetTimeFromValue(value, &end_time)); 357c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 358c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::set<GURL> restrict_urls; 359c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HistoryService* hs = profile()->GetHistoryService(Profile::EXPLICIT_ACCESS); 360c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch hs->ExpireHistoryBetween( 361c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch restrict_urls, 362c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch begin_time, 363c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch end_time, 364c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &cancelable_consumer_, 365c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NewCallback(this, &DeleteRangeHistoryFunction::DeleteComplete)); 366c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 367c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 368c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 369c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 370c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid DeleteRangeHistoryFunction::DeleteComplete() { 371c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SendAsyncResponse(); 372c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 373c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 374c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool DeleteAllHistoryFunction::RunAsyncImpl() { 375c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::set<GURL> restrict_urls; 376c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HistoryService* hs = profile()->GetHistoryService(Profile::EXPLICIT_ACCESS); 377c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch hs->ExpireHistoryBetween( 378c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch restrict_urls, 3793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick base::Time::UnixEpoch(), // From the beginning of the epoch. 380c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch base::Time::Now(), // To the current time. 381c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &cancelable_consumer_, 382c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NewCallback(this, &DeleteAllHistoryFunction::DeleteComplete)); 383c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 384c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 385c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 386c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 387c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid DeleteAllHistoryFunction::DeleteComplete() { 388c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SendAsyncResponse(); 389c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 390