| Index: headless/lib/browser/domain_h.template | 
| diff --git a/headless/lib/browser/domain_h.template b/headless/lib/browser/domain_h.template | 
| index 0cd03c3bc5380328c4766933f1345c5a27034542..bf53d0ee6c8eef7a0fc57a55f9a5d48f9838c6fd 100644 | 
| --- a/headless/lib/browser/domain_h.template | 
| +++ b/headless/lib/browser/domain_h.template | 
| @@ -8,6 +8,7 @@ | 
| #define HEADLESS_PUBLIC_DOMAINS_{{domain.domain | camelcase_to_hacker_style | upper}}_H_ | 
|  | 
| #include "base/callback.h" | 
| +#include "base/observer_list.h" | 
| #include "base/values.h" | 
| #include "headless/public/domains/types.h" | 
| #include "headless/public/headless_export.h" | 
| @@ -15,6 +16,18 @@ | 
|  | 
| namespace headless { | 
| namespace {{domain.domain | camelcase_to_hacker_style}} { | 
| +{% if "events" in domain %} | 
| +class Observer { | 
| + public: | 
| +  virtual ~Observer() {} | 
| +  {% for event in domain.events %} | 
| +  virtual void On{{event.name | to_title_case}}({# -#} | 
| +    {% if "parameters" in event %}{# -#} | 
| +      const {{event.name | to_title_case}}Params& params{# -#} | 
| +    {% endif %}) {} | 
| +  {% endfor %} | 
| +}; | 
| +{% endif %} | 
|  | 
| {% if domain.description %} | 
| // {{domain.description}} | 
| @@ -24,6 +37,13 @@ class HEADLESS_EXPORT Domain { | 
| Domain(internal::MessageDispatcher* dispatcher); | 
| ~Domain(); | 
|  | 
| +  {% if "events" in domain %} | 
| +  // Add or remove an observer. |observer| must be removed before being | 
| +  // destroyed. | 
| +  void AddObserver(Observer* observer); | 
| +  void RemoveObserver(Observer* observer); | 
| +  {% endif %} | 
| + | 
| {# Generate methods for each command. #} | 
| {% for command in domain.commands %} | 
| {# Skip redirected commands. #} | 
| @@ -66,7 +86,18 @@ class HEADLESS_EXPORT Domain { | 
| static void Handle{{method_name}}Response(base::Callback<void(std::unique_ptr<{{method_name}}Result>)> callback, const base::Value& response); | 
| {% endfor %} | 
|  | 
| +  {# Generate event dispatchers. #} | 
| +  {% for event in domain.events %} | 
| +  void Dispatch{{event.name | to_title_case}}Event({# -#} | 
| +    {% if "parameters" in event %}{# -#} | 
| +      const base::Value& params{# -#} | 
| +    {% endif %}); | 
| +  {% endfor %} | 
| + | 
| internal::MessageDispatcher* dispatcher_;  // Not owned. | 
| +  {% if "events" in domain %} | 
| +  base::ObserverList<Observer> observers_; | 
| +  {% endif %} | 
|  | 
| DISALLOW_COPY_AND_ASSIGN(Domain); | 
| }; | 
|  |