1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef CHROME_BROWSER_EXTENSIONS_ACTIVITY_LOG_ACTIVITY_LOG_H_ 6 #define CHROME_BROWSER_EXTENSIONS_ACTIVITY_LOG_ACTIVITY_LOG_H_ 7 8 #include <map> 9 #include <string> 10 #include <vector> 11 12 #include "base/callback.h" 13 #include "base/memory/singleton.h" 14 #include "base/observer_list_threadsafe.h" 15 #include "base/synchronization/lock.h" 16 #include "base/threading/thread.h" 17 #include "chrome/browser/extensions/activity_log/activity_actions.h" 18 #include "chrome/browser/extensions/activity_log/activity_database.h" 19 #include "chrome/browser/extensions/activity_log/activity_log_policy.h" 20 #include "chrome/browser/extensions/install_observer.h" 21 #include "chrome/browser/extensions/install_tracker.h" 22 #include "chrome/browser/extensions/tab_helper.h" 23 #include "chrome/browser/profiles/profile.h" 24 #include "chrome/common/extensions/dom_action_types.h" 25 #include "components/browser_context_keyed_service/browser_context_dependency_manager.h" 26 #include "components/browser_context_keyed_service/browser_context_keyed_service.h" 27 #include "components/browser_context_keyed_service/browser_context_keyed_service_factory.h" 28 29 class Profile; 30 using content::BrowserThread; 31 32 namespace extensions { 33 class Extension; 34 class ActivityLogPolicy; 35 36 // A utility for tracing interesting activity for each extension. 37 // It writes to an ActivityDatabase on a separate thread to record the activity. 38 class ActivityLog : public BrowserContextKeyedService, 39 public TabHelper::ScriptExecutionObserver, 40 public InstallObserver { 41 public: 42 // Observers can listen for activity events. There is probably only one 43 // observer: the activityLogPrivate API. 44 class Observer { 45 public: 46 virtual void OnExtensionActivity(scoped_refptr<Action> activity) = 0; 47 }; 48 49 // ActivityLog is a singleton, so don't instantiate it with the constructor; 50 // use GetInstance instead. 51 static ActivityLog* GetInstance(Profile* profile); 52 53 // Provides up-to-date information about whether the AL is enabled for a 54 // profile. The AL is enabled if the user has installed the whitelisted 55 // AL extension *or* set the --enable-extension-activity-logging flag. 56 bool IsLogEnabled(); 57 58 // If you want to know whether the log is enabled but DON'T have a profile 59 // object yet, use this method. However, it's preferable for the caller to 60 // use IsLogEnabled when possible. 61 static bool IsLogEnabledOnAnyProfile(); 62 63 // Add/remove observer: the activityLogPrivate API only listens when the 64 // ActivityLog extension is registered for an event. 65 void AddObserver(Observer* observer); 66 void RemoveObserver(Observer* observer); 67 68 // Logs an extension action: passes it to any installed policy to be logged 69 // to the database, to any observers, and logs to the console if in testing 70 // mode. 71 void LogAction(scoped_refptr<Action> action); 72 73 // Retrieves the list of actions for a given extension on a specific day. 74 // Today is 0, yesterday is 1, etc. Returns one day at a time. 75 // Response is sent to the method/function in the callback. 76 // Use base::Bind to create the callback. 77 void GetActions(const std::string& extension_id, 78 const int day, 79 const base::Callback 80 <void(scoped_ptr<std::vector<scoped_refptr<Action> > >)>& 81 callback); 82 83 // Extension::InstallObserver 84 // We keep track of whether the whitelisted extension is installed; if it is, 85 // we want to recompute whether to have logging enabled. 86 virtual void OnExtensionInstalled( 87 const extensions::Extension* extension) OVERRIDE {} 88 virtual void OnExtensionLoaded( 89 const extensions::Extension* extension) OVERRIDE; 90 virtual void OnExtensionUnloaded( 91 const extensions::Extension* extension) OVERRIDE; 92 virtual void OnExtensionUninstalled( 93 const extensions::Extension* extension) OVERRIDE {} 94 // We also have to list the following from InstallObserver. 95 virtual void OnBeginExtensionInstall(const std::string& extension_id, 96 const std::string& extension_name, 97 const gfx::ImageSkia& installing_icon, 98 bool is_app, 99 bool is_platform_app) OVERRIDE {} 100 virtual void OnDownloadProgress(const std::string& extension_id, 101 int percent_downloaded) OVERRIDE {} 102 virtual void OnInstallFailure(const std::string& extension_id) OVERRIDE {} 103 virtual void OnAppsReordered() OVERRIDE {} 104 virtual void OnAppInstalledToAppList( 105 const std::string& extension_id) OVERRIDE {} 106 virtual void OnShutdown() OVERRIDE {} 107 108 // BrowserContextKeyedService 109 virtual void Shutdown() OVERRIDE; 110 111 private: 112 friend class ActivityLogFactory; 113 friend class ActivityLogTest; 114 friend class RenderViewActivityLogTest; 115 116 explicit ActivityLog(Profile* profile); 117 virtual ~ActivityLog(); 118 119 // Some setup needs to wait until after the ExtensionSystem/ExtensionService 120 // are done with their own setup. 121 void Init(); 122 123 // TabHelper::ScriptExecutionObserver implementation. 124 // Fires when a ContentScript is executed. 125 virtual void OnScriptsExecuted( 126 const content::WebContents* web_contents, 127 const ExecutingScriptsMap& extension_ids, 128 int32 page_id, 129 const GURL& on_url) OVERRIDE; 130 131 // For unit tests only. Does not call Init again! 132 // Sets whether logging should be enabled for the whole current profile. 133 static void RecomputeLoggingIsEnabled(bool profile_enabled); 134 135 // At the moment, ActivityLog will use only one policy for summarization. 136 // These methods are used to choose and set the most appropriate policy. 137 void ChooseDefaultPolicy(); 138 void SetDefaultPolicy(ActivityLogPolicy::PolicyType policy_type); 139 140 typedef ObserverListThreadSafe<Observer> ObserverList; 141 scoped_refptr<ObserverList> observers_; 142 143 // The policy object takes care of data summarization, compression, and 144 // logging. The policy object is owned by the ActivityLog, but this cannot 145 // be a scoped_ptr since some cleanup work must happen on the database 146 // thread. Calling policy_->Close() will free the object; see the comments 147 // on the ActivityDatabase class for full details. 148 extensions::ActivityLogPolicy* policy_; 149 150 // TODO(dbabic,felt) change this into a list of policy types later. 151 ActivityLogPolicy::PolicyType policy_type_; 152 153 Profile* profile_; 154 bool enabled_; // Whether logging is currently enabled. 155 bool initialized_; // Whether Init() has already been called. 156 bool policy_chosen_; // Whether we've already set the default policy. 157 // testing_mode_ controls whether to log API call arguments. By default, we 158 // don't log most arguments to avoid saving too much data. In testing mode, 159 // argument collection is enabled. We also whitelist some arguments for 160 // collection regardless of whether this bool is true. 161 // When testing_mode_ is enabled, we also print to the console. 162 bool testing_mode_; 163 // We need the DB, FILE, and IO threads to operate. In some cases (tests), 164 // these threads might not exist, so we avoid dispatching anything to the 165 // ActivityDatabase to prevent things from exploding. 166 bool has_threads_; 167 168 // Used to track whether the whitelisted extension is installed. If it's 169 // added or removed, enabled_ may change. 170 InstallTracker* tracker_; 171 172 DISALLOW_COPY_AND_ASSIGN(ActivityLog); 173 }; 174 175 // Each profile has different extensions, so we keep a different database for 176 // each profile. 177 class ActivityLogFactory : public BrowserContextKeyedServiceFactory { 178 public: 179 static ActivityLog* GetForProfile(Profile* profile) { 180 return static_cast<ActivityLog*>( 181 GetInstance()->GetServiceForBrowserContext(profile, true)); 182 } 183 184 static ActivityLogFactory* GetInstance(); 185 186 private: 187 friend struct DefaultSingletonTraits<ActivityLogFactory>; 188 ActivityLogFactory(); 189 virtual ~ActivityLogFactory(); 190 191 virtual BrowserContextKeyedService* BuildServiceInstanceFor( 192 content::BrowserContext* profile) const OVERRIDE; 193 194 virtual content::BrowserContext* GetBrowserContextToUse( 195 content::BrowserContext* context) const OVERRIDE; 196 197 DISALLOW_COPY_AND_ASSIGN(ActivityLogFactory); 198 }; 199 200 201 } // namespace extensions 202 203 #endif // CHROME_BROWSER_EXTENSIONS_ACTIVITY_LOG_ACTIVITY_LOG_H_ 204