15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2011 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "chrome/browser/extensions/activity_log/activity_log.h" 6a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <set> 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <vector> 9a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h" 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/json/json_string_value_serializer.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 135e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/string_util.h" 14558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "base/strings/utf_string_conversions.h" 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/threading/thread_checker.h" 16558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "chrome/browser/extensions/activity_log/activity_action_constants.h" 174311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch#include "chrome/browser/extensions/activity_log/counting_policy.h" 184311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch#include "chrome/browser/extensions/activity_log/fullstream_ui_policy.h" 19868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/extensions/api/activity_log_private/activity_log_private_api.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_service.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_system.h" 22868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/extensions/extension_system_factory.h" 23a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "chrome/browser/extensions/extension_tab_util.h" 24868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/extensions/install_tracker_factory.h" 25868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/prerender/prerender_manager.h" 26868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/prerender/prerender_manager_factory.h" 27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/profiles/incognito_helpers.h" 28a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "chrome/browser/ui/browser.h" 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/chrome_constants.h" 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_switches.h" 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/extensions/extension.h" 32868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "components/browser_context_keyed_service/browser_context_dependency_manager.h" 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_contents.h" 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "third_party/re2/re2/re2.h" 357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "url/gurl.h" 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 37558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochnamespace constants = activity_log_constants; 38558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace { 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Concatenate arguments. 42eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochstd::string MakeArgList(const base::ListValue* args) { 43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string call_signature; 44eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::ListValue::const_iterator it = args->begin(); 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (; it != args->end(); ++it) { 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string arg; 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) JSONStringValueSerializer serializer(&arg); 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (serializer.SerializeAndOmitBinaryValues(**it)) { 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (it != args->begin()) 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) call_signature += ", "; 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) call_signature += arg; 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return call_signature; 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 57868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// This is a hack for AL callers who don't have access to a profile object 58868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// when deciding whether or not to do the work required for logging. The state 59868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// is accessed through the static ActivityLog::IsLogEnabledOnAnyProfile() 60868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// method. It returns true if --enable-extension-activity-logging is set on the 61868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// command line OR *ANY* profile has the activity log whitelisted extension 62868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// installed. 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class LogIsEnabled { 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 65868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) LogIsEnabled() : any_profile_enabled_(false) { 66868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ComputeIsFlagEnabled(); 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 69868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) void ComputeIsFlagEnabled() { 70868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::AutoLock auto_lock(lock_); 71868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) cmd_line_enabled_ = CommandLine::ForCurrentProcess()-> 72868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) HasSwitch(switches::kEnableExtensionActivityLogging); 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static LogIsEnabled* GetInstance() { 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Singleton<LogIsEnabled>::get(); 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 79868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool IsEnabled() { 80868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::AutoLock auto_lock(lock_); 81868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return cmd_line_enabled_ || any_profile_enabled_; 82868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 83868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 84868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) void SetProfileEnabled(bool any_profile_enabled) { 85868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::AutoLock auto_lock(lock_); 86868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) any_profile_enabled_ = any_profile_enabled; 87868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private: 90868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::Lock lock_; 91868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool any_profile_enabled_; 92868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool cmd_line_enabled_; 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 95a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// Gets the URL for a given tab ID. Helper method for LookupTabId. Returns 96a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// true if able to perform the lookup. The URL is stored to *url, and 97a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// *is_incognito is set to indicate whether the URL is for an incognito tab. 98a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)bool GetUrlForTabId(int tab_id, 99a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) Profile* profile, 100a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) GURL* url, 101a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) bool* is_incognito) { 102a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) content::WebContents* contents = NULL; 103a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) Browser* browser = NULL; 104a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) bool found = ExtensionTabUtil::GetTabById(tab_id, 105a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) profile, 106a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) true, // search incognito tabs too 107a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) &browser, 108a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) NULL, 109a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) &contents, 110a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) NULL); 111a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (found) { 112a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) *url = contents->GetURL(); 113a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) *is_incognito = browser->profile()->IsOffTheRecord(); 114a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return true; 115a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } else { 116a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return false; 117a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 118a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 119a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 120a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// Translate tab IDs to URLs in tabs API calls. Mutates the Action object in 121a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// place. There is a small chance that the URL translation could be wrong, if 122a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// the tab has already been navigated by the time of invocation. 123a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// 124a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// If a single tab ID is translated to a URL, the URL is stored into arg_url 125a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// where it can more easily be searched for in the database. For APIs that 126a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// take a list of tab IDs, replace each tab ID with the URL in the argument 127a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// list; we can only extract a single URL into arg_url so arbitrarily pull out 128a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// the first one. 129a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void LookupTabIds(scoped_refptr<extensions::Action> action, Profile* profile) { 130a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const std::string& api_call = action->api_name(); 131a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (api_call == "tabs.get" || // api calls, ID as int 132a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) api_call == "tabs.connect" || 133a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) api_call == "tabs.sendMessage" || 134a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) api_call == "tabs.duplicate" || 135a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) api_call == "tabs.update" || 136a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) api_call == "tabs.reload" || 137a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) api_call == "tabs.detectLanguage" || 138a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) api_call == "tabs.executeScript" || 139a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) api_call == "tabs.insertCSS" || 140a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) api_call == "tabs.move" || // api calls, IDs in array 141a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) api_call == "tabs.remove" || 142a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) api_call == "tabs.onUpdated" || // events, ID as int 143a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) api_call == "tabs.onMoved" || 144a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) api_call == "tabs.onDetached" || 145a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) api_call == "tabs.onAttached" || 146a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) api_call == "tabs.onRemoved" || 147a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) api_call == "tabs.onReplaced") { 148a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) int tab_id; 149a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) base::ListValue* id_list; 150a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) base::ListValue* args = action->mutable_args(); 151a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (args->GetInteger(0, &tab_id)) { 152a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Single tab ID to translate. 153a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) GURL url; 154a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) bool is_incognito; 155a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (GetUrlForTabId(tab_id, profile, &url, &is_incognito)) { 156a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) action->set_arg_url(url); 157a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) action->set_arg_incognito(is_incognito); 158a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 159a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } else if ((api_call == "tabs.move" || api_call == "tabs.remove") && 160a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) args->GetList(0, &id_list)) { 161a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Array of tab IDs to translate. 162a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) for (int i = 0; i < static_cast<int>(id_list->GetSize()); ++i) { 163a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (id_list->GetInteger(i, &tab_id)) { 164a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) GURL url; 165a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) bool is_incognito; 166a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (GetUrlForTabId(tab_id, profile, &url, &is_incognito) && 167a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) !is_incognito) { 168a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) id_list->Set(i, new base::StringValue(url.spec())); 169a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (i == 0) { 170a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) action->set_arg_url(url); 171a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) action->set_arg_incognito(is_incognito); 172a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 173a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 174a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } else { 175a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) LOG(ERROR) << "The tab ID array is malformed at index " << i; 176a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 177a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 178a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 179a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 180a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 181a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace extensions { 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static 187868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)bool ActivityLog::IsLogEnabledOnAnyProfile() { 188868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return LogIsEnabled::GetInstance()->IsEnabled(); 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static 192868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void ActivityLog::RecomputeLoggingIsEnabled(bool profile_enabled) { 193868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) LogIsEnabled::GetInstance()->ComputeIsFlagEnabled(); 194868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) LogIsEnabled::GetInstance()->SetProfileEnabled(profile_enabled); 1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// ActivityLogFactory 1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ActivityLogFactory* ActivityLogFactory::GetInstance() { 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Singleton<ActivityLogFactory>::get(); 2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 20390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)BrowserContextKeyedService* ActivityLogFactory::BuildServiceInstanceFor( 204c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) content::BrowserContext* profile) const { 205c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return new ActivityLog(static_cast<Profile*>(profile)); 2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 208c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)content::BrowserContext* ActivityLogFactory::GetBrowserContextToUse( 209c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) content::BrowserContext* context) const { 210c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return chrome::GetBrowserContextRedirectedInIncognito(context); 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 213868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)ActivityLogFactory::ActivityLogFactory() 214868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) : BrowserContextKeyedServiceFactory( 215868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) "ActivityLog", 216868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) BrowserContextDependencyManager::GetInstance()) { 217868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DependsOn(ExtensionSystemFactory::GetInstance()); 218868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DependsOn(InstallTrackerFactory::GetInstance()); 219868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 220868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 221868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)ActivityLogFactory::~ActivityLogFactory() { 222868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 223868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// ActivityLog 2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void ActivityLog::SetDefaultPolicy(ActivityLogPolicy::PolicyType policy_type) { 2277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Can't use IsLogEnabled() here because this is called from inside Init. 2287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (policy_type != policy_type_ && enabled_) { 2297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Deleting the old policy takes place asynchronously, on the database 2307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // thread. Initializing a new policy below similarly happens 2317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // asynchronously. Since the two operations are both queued for the 2327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // database, the queue ordering should ensure that the deletion completes 2337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // before database initialization occurs. 2347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // 2357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // However, changing policies at runtime is still not recommended, and 2367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // likely only should be done for unit tests. 2377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (policy_) 2387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch policy_->Close(); 2397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 2407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) switch (policy_type) { 2417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) case ActivityLogPolicy::POLICY_FULLSTREAM: 2427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) policy_ = new FullStreamUIPolicy(profile_); 2437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) break; 2444311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch case ActivityLogPolicy::POLICY_COUNTS: 2454311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch policy_ = new CountingPolicy(profile_); 2467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) break; 2477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) default: 2487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch NOTREACHED(); 2497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 2507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) policy_type_ = policy_type; 2517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 2527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 2537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use GetInstance instead of directly creating an ActivityLog. 255868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)ActivityLog::ActivityLog(Profile* profile) 2567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) : policy_(NULL), 2577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) policy_type_(ActivityLogPolicy::POLICY_INVALID), 2587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) profile_(profile), 2597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch enabled_(false), 2607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch initialized_(false), 2617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch policy_chosen_(false), 2627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) testing_mode_(false), 2637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) has_threads_(true), 2647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) tracker_(NULL) { 2657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // This controls whether logging statements are printed, which policy is set, 2667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // etc. 2677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch testing_mode_ = CommandLine::ForCurrentProcess()->HasSwitch( 2687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch switches::kEnableExtensionActivityLogTesting); 2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 270868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Check that the right threads exist. If not, we shouldn't try to do things 271868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // that require them. 272868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!BrowserThread::IsMessageLoopValid(BrowserThread::DB) || 273868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) !BrowserThread::IsMessageLoopValid(BrowserThread::FILE) || 274868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) !BrowserThread::IsMessageLoopValid(BrowserThread::IO)) { 275868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) LOG(ERROR) << "Missing threads, disabling Activity Logging!"; 276868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) has_threads_ = false; 2777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } else { 2787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch enabled_ = IsLogEnabledOnAnyProfile(); 2797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ExtensionSystem::Get(profile_)->ready().Post( 2807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch FROM_HERE, base::Bind(&ActivityLog::Init, base::Unretained(this))); 281c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 282c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 283868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) observers_ = new ObserverListThreadSafe<Observer>; 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid ActivityLog::Init() { 2877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DCHECK(has_threads_); 2887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DCHECK(!initialized_); 2897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const Extension* whitelisted_extension = ExtensionSystem::Get(profile_)-> 2907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch extension_service()->GetExtensionById(kActivityLogExtensionId, false); 2917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (whitelisted_extension) { 2927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch enabled_ = true; 2937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch LogIsEnabled::GetInstance()->SetProfileEnabled(true); 2947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 2957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch tracker_ = InstallTrackerFactory::GetForProfile(profile_); 2967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch tracker_->AddObserver(this); 2977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ChooseDefaultPolicy(); 2987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch initialized_ = true; 2997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 3007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 3017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid ActivityLog::ChooseDefaultPolicy() { 3027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (policy_chosen_ || !enabled_) return; 3037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (testing_mode_) 3047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch SetDefaultPolicy(ActivityLogPolicy::POLICY_FULLSTREAM); 3057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch else 3064311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch SetDefaultPolicy(ActivityLogPolicy::POLICY_COUNTS); 3077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 3087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 309868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void ActivityLog::Shutdown() { 3107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (tracker_) tracker_->RemoveObserver(this); 311868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 312868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ActivityLog::~ActivityLog() { 3147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (policy_) 3157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch policy_->Close(); 316868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 317868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 318868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)bool ActivityLog::IsLogEnabled() { 3197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!has_threads_ || !initialized_) return false; 320868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return enabled_; 321868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 322868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 3237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid ActivityLog::OnExtensionLoaded(const Extension* extension) { 324868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (extension->id() != kActivityLogExtensionId) return; 325868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) enabled_ = true; 326868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) LogIsEnabled::GetInstance()->SetProfileEnabled(true); 3277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ChooseDefaultPolicy(); 328868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 329868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 3307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid ActivityLog::OnExtensionUnloaded(const Extension* extension) { 331868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (extension->id() != kActivityLogExtensionId) return; 332868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!CommandLine::ForCurrentProcess()->HasSwitch( 333868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) switches::kEnableExtensionActivityLogging)) 334868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) enabled_ = false; 335c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 336c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ActivityLog* ActivityLog::GetInstance(Profile* profile) { 3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return ActivityLogFactory::GetForProfile(profile); 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 342868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void ActivityLog::AddObserver(ActivityLog::Observer* observer) { 343868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) observers_->AddObserver(observer); 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 346868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void ActivityLog::RemoveObserver(ActivityLog::Observer* observer) { 347868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) observers_->RemoveObserver(observer); 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 350558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochvoid ActivityLog::LogAction(scoped_refptr<Action> action) { 351868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!IsLogEnabled() || 352a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ActivityLogAPI::IsExtensionWhitelisted(action->extension_id())) 353a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return; 354a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 355a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Perform some preprocessing of the Action data: convert tab IDs to URLs and 356a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // mask out incognito URLs if appropriate. 357a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if ((action->action_type() == Action::ACTION_API_CALL || 358a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) action->action_type() == Action::ACTION_API_EVENT) && 359a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) StartsWithASCII(action->api_name(), "tabs.", true)) { 360a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) LookupTabIds(action, profile_); 3617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 3627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 363a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // TODO(mvrable): Add any necessary processing of incognito URLs here, for 364a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // crbug.com/253368 3657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 366a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (policy_) 367a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) policy_->ProcessAction(action); 368a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) observers_->Notify(&Observer::OnExtensionActivity, action); 369a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (testing_mode_) 370a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) LOG(INFO) << action->PrintForDebug(); 3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ActivityLog::GetActions( 3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& extension_id, 3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const int day, 3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::Callback 3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) <void(scoped_ptr<std::vector<scoped_refptr<Action> > >)>& callback) { 3787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (policy_) { 3797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) policy_->ReadData(extension_id, day, callback); 3807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ActivityLog::OnScriptsExecuted( 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const content::WebContents* web_contents, 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ExecutingScriptsMap& extension_ids, 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32 on_page_id, 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& on_url) { 3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!IsLogEnabled()) return; 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Profile* profile = 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Profile::FromBrowserContext(web_contents->GetBrowserContext()); 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ExtensionService* extension_service = 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionSystem::Get(profile)->extension_service(); 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ExtensionSet* extensions = extension_service->extensions(); 394868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const prerender::PrerenderManager* prerender_manager = 395868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) prerender::PrerenderManagerFactory::GetForProfile( 396868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) Profile::FromBrowserContext(web_contents->GetBrowserContext())); 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (ExecutingScriptsMap::const_iterator it = extension_ids.begin(); 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it != extension_ids.end(); ++it) { 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Extension* extension = extensions->GetByID(it->first); 401868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!extension || ActivityLogAPI::IsExtensionWhitelisted(extension->id())) 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If OnScriptsExecuted is fired because of tabs.executeScript, the list 4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // of content scripts will be empty. We don't want to log it because 4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // the call to tabs.executeScript will have already been logged anyway. 4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!it->second.empty()) { 408a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) scoped_refptr<Action> action; 409a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) action = new Action(extension->id(), 410a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) base::Time::Now(), 411a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) Action::ACTION_CONTENT_SCRIPT, 412a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ""); // no API call here 413a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) action->set_page_url(on_url); 414a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) action->set_page_title(base::UTF16ToUTF8(web_contents->GetTitle())); 415a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) action->set_page_incognito( 416a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) web_contents->GetBrowserContext()->IsOffTheRecord()); 417a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (prerender_manager && 418a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) prerender_manager->IsWebContentsPrerendering(web_contents, NULL)) 419a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) action->mutable_other()->SetBoolean(constants::kActionPrerender, true); 4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (std::set<std::string>::const_iterator it2 = it->second.begin(); 421c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) it2 != it->second.end(); 422c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ++it2) { 423a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) action->mutable_args()->AppendString(*it2); 4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 425a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) LogAction(action); 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace extensions 431