Home | History | Annotate | Download | only in activity_log
      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