Home | History | Annotate | Download | only in error_console
      1 // Copyright 2013 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_ERROR_CONSOLE_ERROR_CONSOLE_H_
      6 #define CHROME_BROWSER_EXTENSIONS_ERROR_CONSOLE_ERROR_CONSOLE_H_
      7 
      8 #include "base/memory/scoped_ptr.h"
      9 #include "base/observer_list.h"
     10 #include "base/prefs/pref_change_registrar.h"
     11 #include "base/scoped_observer.h"
     12 #include "base/threading/thread_checker.h"
     13 #include "content/public/browser/notification_observer.h"
     14 #include "content/public/browser/notification_registrar.h"
     15 #include "extensions/browser/error_map.h"
     16 #include "extensions/browser/extension_error.h"
     17 #include "extensions/browser/extension_registry_observer.h"
     18 
     19 namespace content {
     20 class NotificationDetails;
     21 class NotificationSource;
     22 class RenderViewHost;
     23 }
     24 
     25 class Profile;
     26 
     27 namespace extensions {
     28 class Extension;
     29 class ExtensionPrefs;
     30 class ExtensionRegistry;
     31 
     32 // The ErrorConsole is a central object to which all extension errors are
     33 // reported. This includes errors detected in extensions core, as well as
     34 // runtime Javascript errors. If FeatureSwitch::error_console() is enabled these
     35 // errors can be viewed at chrome://extensions in developer mode.
     36 // This class is owned by ExtensionSystem, making it, in effect, a
     37 // BrowserContext-keyed service.
     38 class ErrorConsole : public content::NotificationObserver,
     39                      public ExtensionRegistryObserver {
     40  public:
     41   class Observer {
     42    public:
     43     // Sent when a new error is reported to the error console.
     44     virtual void OnErrorAdded(const ExtensionError* error) = 0;
     45 
     46     // Sent upon destruction to allow any observers to invalidate any references
     47     // they have to the error console.
     48     virtual void OnErrorConsoleDestroyed();
     49   };
     50 
     51   explicit ErrorConsole(Profile* profile);
     52   virtual ~ErrorConsole();
     53 
     54   // Convenience method to return the ErrorConsole for a given profile.
     55   static ErrorConsole* Get(Profile* profile);
     56 
     57   // Set whether or not errors of the specified |type| are stored for the
     58   // extension with the given |extension_id|. This will be stored in the
     59   // preferences.
     60   void SetReportingForExtension(const std::string& extension_id,
     61                                 ExtensionError::Type type,
     62                                 bool enabled);
     63 
     64   // Set whether or not errors of all types are stored for the extension with
     65   // the given |extension_id|.
     66   void SetReportingAllForExtension(const std::string& extension_id,
     67                                            bool enabled);
     68 
     69   // Returns true if reporting for either manifest or runtime errors is enabled
     70   // for the extension with the given |extension_id|.
     71   bool IsReportingEnabledForExtension(const std::string& extension_id) const;
     72 
     73   // Restore default reporting to the given extension.
     74   void UseDefaultReportingForExtension(const std::string& extension_id);
     75 
     76   // Report an extension error, and add it to the list.
     77   void ReportError(scoped_ptr<ExtensionError> error);
     78 
     79   // Get a collection of weak pointers to all errors relating to the extension
     80   // with the given |extension_id|.
     81   const ErrorList& GetErrorsForExtension(const std::string& extension_id) const;
     82 
     83   // Add or remove observers of the ErrorConsole to be notified of any errors
     84   // added.
     85   void AddObserver(Observer* observer);
     86   void RemoveObserver(Observer* observer);
     87 
     88   // Returns whether or not the ErrorConsole is enabled for the
     89   // chrome:extensions page or the Chrome Apps Developer Tools.
     90   //
     91   // TODO(rdevlin.cronin): These have different answers - ErrorConsole is
     92   // enabled by default in ADT, but only Dev Channel for chrome:extensions (or
     93   // with the commandline switch). Once we do a full launch, clean all this up.
     94   bool IsEnabledForChromeExtensionsPage() const;
     95   bool IsEnabledForAppsDeveloperTools() const;
     96 
     97   // Return whether or not the ErrorConsole is enabled.
     98   bool enabled() const { return enabled_; }
     99 
    100   // Return the number of entries (extensions) in the error map.
    101   size_t get_num_entries_for_test() const { return errors_.size(); }
    102 
    103   // Set the default reporting for all extensions.
    104   void set_default_reporting_for_test(ExtensionError::Type type, bool enabled) {
    105     default_mask_ =
    106         enabled ? default_mask_ | (1 << type) : default_mask_ & ~(1 << type);
    107   }
    108 
    109  private:
    110   // Checks whether or not the ErrorConsole should be enabled or disabled. If it
    111   // is in the wrong state, enables or disables it appropriately.
    112   void CheckEnabled();
    113 
    114   // Enable the error console for error collection and retention. This involves
    115   // subscribing to the appropriate notifications and fetching manifest errors.
    116   void Enable();
    117 
    118   // Disable the error console, removing the subscriptions to notifications and
    119   // removing all current errors.
    120   void Disable();
    121 
    122   // Called when the Developer Mode preference is changed; this is important
    123   // since we use this as a heuristic to determine if the console is enabled or
    124   // not.
    125   void OnPrefChanged();
    126 
    127   // ExtensionRegistry implementation. If the Apps Developer Tools app is
    128   // installed or uninstalled, we may need to turn the ErrorConsole on/off.
    129   virtual void OnExtensionUnloaded(
    130       content::BrowserContext* browser_context,
    131       const Extension* extension,
    132       UnloadedExtensionInfo::Reason reason) OVERRIDE;
    133   virtual void OnExtensionLoaded(content::BrowserContext* browser_context,
    134                                  const Extension* extension) OVERRIDE;
    135   virtual void OnExtensionInstalled(content::BrowserContext* browser_context,
    136                                     const Extension* extension) OVERRIDE;
    137   virtual void OnExtensionUninstalled(content::BrowserContext* browser_context,
    138                                       const Extension* extension) OVERRIDE;
    139 
    140   // Add manifest errors from an extension's install warnings.
    141   void AddManifestErrorsForExtension(const Extension* extension);
    142 
    143   // content::NotificationObserver implementation.
    144   virtual void Observe(int type,
    145                        const content::NotificationSource& source,
    146                        const content::NotificationDetails& details) OVERRIDE;
    147 
    148   // Returns the applicable bit mask of reporting preferences for the extension.
    149   int GetMaskForExtension(const std::string& extension_id) const;
    150 
    151   // Whether or not the error console should record errors. This is true if
    152   // the user is in developer mode, and at least one of the following is true:
    153   // - The Chrome Apps Developer Tools are installed.
    154   // - FeatureSwitch::error_console() is enabled.
    155   // - This is a Dev Channel release.
    156   bool enabled_;
    157 
    158   // Needed because ObserverList is not thread-safe.
    159   base::ThreadChecker thread_checker_;
    160 
    161   // The list of all observers for the ErrorConsole.
    162   ObserverList<Observer> observers_;
    163 
    164   // The errors which we have received so far.
    165   ErrorMap errors_;
    166 
    167   // The default mask to use if an Extension does not have specific settings.
    168   int32 default_mask_;
    169 
    170   // The profile with which the ErrorConsole is associated. Only collect errors
    171   // from extensions and RenderViews associated with this Profile (and it's
    172   // incognito fellow).
    173   Profile* profile_;
    174 
    175   // The ExtensionPrefs with which the ErrorConsole is associated. This weak
    176   // pointer is safe because ErrorConsole is owned by ExtensionSystem, which
    177   // is dependent on ExtensionPrefs.
    178   ExtensionPrefs* prefs_;
    179 
    180   content::NotificationRegistrar notification_registrar_;
    181   PrefChangeRegistrar pref_registrar_;
    182 
    183   ScopedObserver<ExtensionRegistry, ExtensionRegistryObserver>
    184       registry_observer_;
    185 
    186   DISALLOW_COPY_AND_ASSIGN(ErrorConsole);
    187 };
    188 
    189 }  // namespace extensions
    190 
    191 #endif  // CHROME_BROWSER_EXTENSIONS_ERROR_CONSOLE_ERROR_CONSOLE_H_
    192