summaryrefslogtreecommitdiffstats
path: root/chrome/browser
diff options
context:
space:
mode:
authorlimasdf@gmail.com <limasdf@gmail.com@0039d316-1c4b-4281-b951-d872f2087c98>2014-05-13 05:09:44 +0000
committerlimasdf@gmail.com <limasdf@gmail.com@0039d316-1c4b-4281-b951-d872f2087c98>2014-05-13 05:09:44 +0000
commitd0c44b74dc1c764c51ca4e9c0158265dca631120 (patch)
tree7c6ab517cf403e198509bf6399c6e4152c976d03 /chrome/browser
parentb9dfeb996c0ed9546071eae66fdfbeecbc6a1733 (diff)
downloadchromium_src-d0c44b74dc1c764c51ca4e9c0158265dca631120.zip
chromium_src-d0c44b74dc1c764c51ca4e9c0158265dca631120.tar.gz
chromium_src-d0c44b74dc1c764c51ca4e9c0158265dca631120.tar.bz2
Use ExtensionRegistryObserver instead of deprecated extension notification from c/b/e/api.
This clean up alarm, declarative, idle, push_messaing API. R=kalman@chromium.org BUG=354046, 354458 TEST=unit_tests Review URL: https://codereview.chromium.org/275383002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@270024 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser')
-rw-r--r--chrome/browser/extensions/api/alarms/alarm_manager.cc63
-rw-r--r--chrome/browser/extensions/api/alarms/alarm_manager.h21
-rw-r--r--chrome/browser/extensions/api/alarms/alarms_api.cc10
-rw-r--r--chrome/browser/extensions/api/declarative/rules_registry_service.cc36
-rw-r--r--chrome/browser/extensions/api/declarative/rules_registry_service.h18
-rw-r--r--chrome/browser/extensions/api/idle/idle_api_unittest.cc28
-rw-r--r--chrome/browser/extensions/api/idle/idle_manager.cc25
-rw-r--r--chrome/browser/extensions/api/idle/idle_manager.h21
-rw-r--r--chrome/browser/extensions/api/push_messaging/push_messaging_api.cc87
-rw-r--r--chrome/browser/extensions/api/push_messaging/push_messaging_api.h22
10 files changed, 178 insertions, 153 deletions
diff --git a/chrome/browser/extensions/api/alarms/alarm_manager.cc b/chrome/browser/extensions/api/alarms/alarm_manager.cc
index cc3267d..6866f2d 100644
--- a/chrome/browser/extensions/api/alarms/alarm_manager.cc
+++ b/chrome/browser/extensions/api/alarms/alarm_manager.cc
@@ -16,10 +16,10 @@
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/state_store.h"
-#include "chrome/browser/profiles/profile.h"
#include "chrome/common/extensions/api/alarms.h"
#include "content/public/browser/notification_service.h"
#include "extensions/browser/event_router.h"
+#include "extensions/browser/extension_registry.h"
#include "extensions/browser/extension_system.h"
namespace extensions {
@@ -97,16 +97,16 @@ scoped_ptr<base::ListValue> AlarmsToValue(const std::vector<Alarm>& alarms) {
// AlarmManager
AlarmManager::AlarmManager(content::BrowserContext* context)
- : profile_(Profile::FromBrowserContext(context)),
+ : browser_context_(context),
clock_(new base::DefaultClock()),
- delegate_(new DefaultAlarmDelegate(context)) {
+ delegate_(new DefaultAlarmDelegate(context)),
+ extension_registry_observer_(this) {
+ extension_registry_observer_.Add(ExtensionRegistry::Get(browser_context_));
registrar_.Add(this,
- chrome::NOTIFICATION_EXTENSION_LOADED_DEPRECATED,
- content::Source<Profile>(profile_));
- registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNINSTALLED,
- content::Source<Profile>(profile_));
+ chrome::NOTIFICATION_EXTENSION_UNINSTALLED,
+ content::Source<content::BrowserContext>(browser_context_));
- StateStore* storage = ExtensionSystem::Get(profile_)->state_store();
+ StateStore* storage = ExtensionSystem::Get(browser_context_)->state_store();
if (storage)
storage->RegisterKey(kRegisteredAlarms);
}
@@ -226,8 +226,8 @@ AlarmManager::GetFactoryInstance() {
}
// static
-AlarmManager* AlarmManager::Get(Profile* profile) {
- return BrowserContextKeyedAPIFactory<AlarmManager>::Get(profile);
+AlarmManager* AlarmManager::Get(content::BrowserContext* browser_context) {
+ return BrowserContextKeyedAPIFactory<AlarmManager>::Get(browser_context);
}
void AlarmManager::RemoveAlarmIterator(const AlarmIterator& iter) {
@@ -290,7 +290,7 @@ void AlarmManager::AddAlarmImpl(const std::string& extension_id,
}
void AlarmManager::WriteToStorage(const std::string& extension_id) {
- StateStore* storage = ExtensionSystem::Get(profile_)->state_store();
+ StateStore* storage = ExtensionSystem::Get(browser_context_)->state_store();
if (!storage)
return;
@@ -410,35 +410,26 @@ void AlarmManager::RunWhenReady(
it->second.push(action);
}
+void AlarmManager::OnExtensionLoaded(content::BrowserContext* browser_context,
+ const Extension* extension) {
+ StateStore* storage = ExtensionSystem::Get(browser_context_)->state_store();
+ if (storage) {
+ ready_actions_.insert(ReadyMap::value_type(extension->id(), ReadyQueue()));
+ storage->GetExtensionValue(
+ extension->id(),
+ kRegisteredAlarms,
+ base::Bind(
+ &AlarmManager::ReadFromStorage, AsWeakPtr(), extension->id()));
+ }
+}
+
void AlarmManager::Observe(
int type,
const content::NotificationSource& source,
const content::NotificationDetails& details) {
- switch (type) {
- case chrome::NOTIFICATION_EXTENSION_LOADED_DEPRECATED: {
- const Extension* extension =
- content::Details<const Extension>(details).ptr();
- StateStore* storage = ExtensionSystem::Get(profile_)->state_store();
- if (storage) {
- ready_actions_.insert(
- ReadyMap::value_type(extension->id(), ReadyQueue()));
- storage->GetExtensionValue(extension->id(), kRegisteredAlarms,
- base::Bind(&AlarmManager::ReadFromStorage,
- AsWeakPtr(), extension->id()));
- }
- break;
- }
- case chrome::NOTIFICATION_EXTENSION_UNINSTALLED: {
- const Extension* extension =
- content::Details<const Extension>(details).ptr();
- RemoveAllAlarms(
- extension->id(), base::Bind(RemoveAllOnUninstallCallback));
- break;
- }
- default:
- NOTREACHED();
- break;
- }
+ DCHECK_EQ(type, chrome::NOTIFICATION_EXTENSION_UNINSTALLED);
+ const Extension* extension = content::Details<const Extension>(details).ptr();
+ RemoveAllAlarms(extension->id(), base::Bind(RemoveAllOnUninstallCallback));
}
// AlarmManager::Alarm
diff --git a/chrome/browser/extensions/api/alarms/alarm_manager.h b/chrome/browser/extensions/api/alarms/alarm_manager.h
index 04515f1..95cfabc 100644
--- a/chrome/browser/extensions/api/alarms/alarm_manager.h
+++ b/chrome/browser/extensions/api/alarms/alarm_manager.h
@@ -12,14 +12,14 @@
#include "base/callback.h"
#include "base/memory/weak_ptr.h"
+#include "base/scoped_observer.h"
#include "base/timer/timer.h"
#include "chrome/common/extensions/api/alarms.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
#include "extensions/browser/browser_context_keyed_api_factory.h"
#include "extensions/browser/extension_function.h"
-
-class Profile;
+#include "extensions/browser/extension_registry_observer.h"
namespace base {
class Clock;
@@ -30,8 +30,8 @@ class BrowserContext;
} // namespace content
namespace extensions {
-
class ExtensionAlarmsSchedulingTest;
+class ExtensionRegistry;
struct Alarm {
Alarm();
@@ -57,6 +57,7 @@ struct Alarm {
// There is one manager per virtual Profile.
class AlarmManager : public BrowserContextKeyedAPI,
public content::NotificationObserver,
+ public ExtensionRegistryObserver,
public base::SupportsWeakPtr<AlarmManager> {
public:
typedef std::vector<Alarm> AlarmList;
@@ -114,8 +115,8 @@ class AlarmManager : public BrowserContextKeyedAPI,
// BrowserContextKeyedAPI implementation.
static BrowserContextKeyedAPIFactory<AlarmManager>* GetFactoryInstance();
- // Convenience method to get the AlarmManager for a profile.
- static AlarmManager* Get(Profile* profile);
+ // Convenience method to get the AlarmManager for a content::BrowserContext.
+ static AlarmManager* Get(content::BrowserContext* browser_context);
private:
friend void RunScheduleNextPoll(AlarmManager*);
@@ -208,17 +209,25 @@ class AlarmManager : public BrowserContextKeyedAPI,
const content::NotificationSource& source,
const content::NotificationDetails& details) OVERRIDE;
+ // Overridden from extensions::ExtensionRegistryObserver.
+ virtual void OnExtensionLoaded(content::BrowserContext* browser_context,
+ const Extension* extension) OVERRIDE;
+
// BrowserContextKeyedAPI implementation.
static const char* service_name() {
return "AlarmManager";
}
static const bool kServiceHasOwnInstanceInIncognito = true;
- Profile* const profile_;
+ content::BrowserContext* const browser_context_;
scoped_ptr<base::Clock> clock_;
content::NotificationRegistrar registrar_;
scoped_ptr<Delegate> delegate_;
+ // Listen to extension load notifications.
+ ScopedObserver<ExtensionRegistry, ExtensionRegistryObserver>
+ extension_registry_observer_;
+
// The timer for this alarm manager.
base::OneShotTimer<AlarmManager> timer_;
diff --git a/chrome/browser/extensions/api/alarms/alarms_api.cc b/chrome/browser/extensions/api/alarms/alarms_api.cc
index 4de1670..b8db084 100644
--- a/chrome/browser/extensions/api/alarms/alarms_api.cc
+++ b/chrome/browser/extensions/api/alarms/alarms_api.cc
@@ -119,7 +119,7 @@ bool AlarmsCreateFunction::RunAsync() {
Manifest::IsUnpackedLocation(GetExtension()->location()) ?
kDevDelayMinimum : kReleaseDelayMinimum),
clock_->Now());
- AlarmManager::Get(GetProfile())->AddAlarm(
+ AlarmManager::Get(browser_context())->AddAlarm(
extension_id(), alarm, base::Bind(&AlarmsCreateFunction::Callback, this));
return true;
@@ -134,7 +134,7 @@ bool AlarmsGetFunction::RunAsync() {
EXTENSION_FUNCTION_VALIDATE(params.get());
std::string name = params->name.get() ? *params->name : kDefaultAlarmName;
- AlarmManager::Get(GetProfile())
+ AlarmManager::Get(browser_context())
->GetAlarm(extension_id(),
name,
base::Bind(&AlarmsGetFunction::Callback, this, name));
@@ -151,7 +151,7 @@ void AlarmsGetFunction::Callback(
}
bool AlarmsGetAllFunction::RunAsync() {
- AlarmManager::Get(GetProfile())->GetAllAlarms(
+ AlarmManager::Get(browser_context())->GetAllAlarms(
extension_id(), base::Bind(&AlarmsGetAllFunction::Callback, this));
return true;
}
@@ -176,7 +176,7 @@ bool AlarmsClearFunction::RunAsync() {
EXTENSION_FUNCTION_VALIDATE(params.get());
std::string name = params->name.get() ? *params->name : kDefaultAlarmName;
- AlarmManager::Get(GetProfile())
+ AlarmManager::Get(browser_context())
->RemoveAlarm(extension_id(),
name,
base::Bind(&AlarmsClearFunction::Callback, this, name));
@@ -190,7 +190,7 @@ void AlarmsClearFunction::Callback(const std::string& name, bool success) {
}
bool AlarmsClearAllFunction::RunAsync() {
- AlarmManager::Get(GetProfile())->RemoveAllAlarms(
+ AlarmManager::Get(browser_context())->RemoveAllAlarms(
extension_id(), base::Bind(&AlarmsClearAllFunction::Callback, this));
return true;
}
diff --git a/chrome/browser/extensions/api/declarative/rules_registry_service.cc b/chrome/browser/extensions/api/declarative/rules_registry_service.cc
index 42d0ca4..567dd4e 100644
--- a/chrome/browser/extensions/api/declarative/rules_registry_service.cc
+++ b/chrome/browser/extensions/api/declarative/rules_registry_service.cc
@@ -20,6 +20,7 @@
#include "content/public/browser/notification_service.h"
#include "content/public/browser/notification_source.h"
#include "content/public/browser/render_process_host.h"
+#include "extensions/browser/extension_registry.h"
#include "extensions/common/extension.h"
namespace extensions {
@@ -43,17 +44,13 @@ bool IsWebView(const RulesRegistryService::WebViewKey& webview_key) {
RulesRegistryService::RulesRegistryService(content::BrowserContext* context)
: content_rules_registry_(NULL),
+ extension_registry_observer_(this),
profile_(Profile::FromBrowserContext(context)) {
if (profile_) {
- registrar_.Add(this,
- chrome::NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED,
- content::Source<Profile>(profile_->GetOriginalProfile()));
+ extension_registry_observer_.Add(ExtensionRegistry::Get(profile_));
registrar_.Add(this,
chrome::NOTIFICATION_EXTENSION_UNINSTALLED,
content::Source<Profile>(profile_->GetOriginalProfile()));
- registrar_.Add(this,
- chrome::NOTIFICATION_EXTENSION_LOADED_DEPRECATED,
- content::Source<Profile>(profile_->GetOriginalProfile()));
registrar_.Add(
this, content::NOTIFICATION_RENDERER_PROCESS_TERMINATED,
content::NotificationService::AllBrowserContextsAndSources());
@@ -206,18 +203,24 @@ void RulesRegistryService::NotifyRegistriesHelper(
}
}
+void RulesRegistryService::OnExtensionLoaded(
+ content::BrowserContext* browser_context,
+ const Extension* extension) {
+ NotifyRegistriesHelper(&RulesRegistry::OnExtensionLoaded, extension->id());
+}
+
+void RulesRegistryService::OnExtensionUnloaded(
+ content::BrowserContext* browser_context,
+ const Extension* extension,
+ UnloadedExtensionInfo::Reason reason) {
+ NotifyRegistriesHelper(&RulesRegistry::OnExtensionUnloaded, extension->id());
+}
+
void RulesRegistryService::Observe(
int type,
const content::NotificationSource& source,
const content::NotificationDetails& details) {
switch (type) {
- case chrome::NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED: {
- const Extension* extension =
- content::Details<UnloadedExtensionInfo>(details)->extension;
- NotifyRegistriesHelper(&RulesRegistry::OnExtensionUnloaded,
- extension->id());
- break;
- }
case chrome::NOTIFICATION_EXTENSION_UNINSTALLED: {
const Extension* extension =
content::Details<const Extension>(details).ptr();
@@ -225,13 +228,6 @@ void RulesRegistryService::Observe(
extension->id());
break;
}
- case chrome::NOTIFICATION_EXTENSION_LOADED_DEPRECATED: {
- const Extension* extension =
- content::Details<const Extension>(details).ptr();
- NotifyRegistriesHelper(&RulesRegistry::OnExtensionLoaded,
- extension->id());
- break;
- }
case content::NOTIFICATION_RENDERER_PROCESS_TERMINATED: {
content::RenderProcessHost* process =
content::Source<content::RenderProcessHost>(source).ptr();
diff --git a/chrome/browser/extensions/api/declarative/rules_registry_service.h b/chrome/browser/extensions/api/declarative/rules_registry_service.h
index ae23372..97097ea 100644
--- a/chrome/browser/extensions/api/declarative/rules_registry_service.h
+++ b/chrome/browser/extensions/api/declarative/rules_registry_service.h
@@ -12,11 +12,13 @@
#include "base/callback_forward.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_vector.h"
+#include "base/scoped_observer.h"
#include "chrome/browser/extensions/api/declarative/rules_registry.h"
#include "chrome/browser/profiles/profile.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
#include "extensions/browser/browser_context_keyed_api_factory.h"
+#include "extensions/browser/extension_registry_observer.h"
class Profile;
@@ -27,6 +29,7 @@ class NotificationSource;
namespace extensions {
class ContentRulesRegistry;
+class ExtensionRegistry;
class RulesRegistry;
class RulesRegistryStorageDelegate;
}
@@ -36,7 +39,8 @@ namespace extensions {
// This class owns all RulesRegistries implementations of an ExtensionService.
// This class lives on the UI thread.
class RulesRegistryService : public BrowserContextKeyedAPI,
- public content::NotificationObserver {
+ public content::NotificationObserver,
+ public ExtensionRegistryObserver {
public:
typedef RulesRegistry::WebViewKey WebViewKey;
struct RulesRegistryKey {
@@ -105,6 +109,14 @@ class RulesRegistryService : public BrowserContextKeyedAPI,
const content::NotificationSource& source,
const content::NotificationDetails& details) OVERRIDE;
+ // ExtensionRegistryObserver implementation.
+ virtual void OnExtensionLoaded(content::BrowserContext* browser_context,
+ const Extension* extension) OVERRIDE;
+ virtual void OnExtensionUnloaded(
+ content::BrowserContext* browser_context,
+ const Extension* extension,
+ UnloadedExtensionInfo::Reason reason) OVERRIDE;
+
// Iterates over all registries, and calls |notification_callback| on them
// with |extension_id| as the argument. If a registry lives on a different
// thread, the call is posted to that thread, so no guarantee of synchronous
@@ -131,6 +143,10 @@ class RulesRegistryService : public BrowserContextKeyedAPI,
content::NotificationRegistrar registrar_;
+ // Listen to extension load, unloaded notification.
+ ScopedObserver<ExtensionRegistry, ExtensionRegistryObserver>
+ extension_registry_observer_;
+
Profile* profile_;
DISALLOW_COPY_AND_ASSIGN(RulesRegistryService);
diff --git a/chrome/browser/extensions/api/idle/idle_api_unittest.cc b/chrome/browser/extensions/api/idle/idle_api_unittest.cc
index 83c03cb..cb49004 100644
--- a/chrome/browser/extensions/api/idle/idle_api_unittest.cc
+++ b/chrome/browser/extensions/api/idle/idle_api_unittest.cc
@@ -17,6 +17,7 @@
#include "content/public/browser/notification_details.h"
#include "content/public/browser/notification_source.h"
#include "extensions/browser/event_router.h"
+#include "extensions/browser/extension_registry.h"
#include "extensions/common/extension.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -509,12 +510,9 @@ TEST_F(IdleTest, UnloadCleanup) {
}
// Threshold will reset after unload (and listen count == 0)
- UnloadedExtensionInfo details(extension(),
- UnloadedExtensionInfo::REASON_UNINSTALL);
- idle_manager_->Observe(
- chrome::NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED,
- content::Source<Profile>(browser()->profile()),
- content::Details<UnloadedExtensionInfo>(&details));
+ ExtensionRegistry* registry = ExtensionRegistry::Get(browser()->profile());
+ registry->TriggerOnUnloaded(extension(),
+ UnloadedExtensionInfo::REASON_UNINSTALL);
{
ScopedListen listen(idle_manager_, extension()->id());
@@ -530,24 +528,18 @@ TEST_F(IdleTest, UnloadCleanup) {
// Verifies that unloading an extension with no listeners or threshold works.
TEST_F(IdleTest, UnloadOnly) {
- UnloadedExtensionInfo details(extension(),
- UnloadedExtensionInfo::REASON_UNINSTALL);
- idle_manager_->Observe(
- chrome::NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED,
- content::Source<Profile>(browser()->profile()),
- content::Details<UnloadedExtensionInfo>(&details));
+ ExtensionRegistry* registry = ExtensionRegistry::Get(browser()->profile());
+ registry->TriggerOnUnloaded(extension(),
+ UnloadedExtensionInfo::REASON_UNINSTALL);
}
// Verifies that its ok for the unload notification to happen before all the
// listener removals.
TEST_F(IdleTest, UnloadWhileListening) {
ScopedListen listen(idle_manager_, extension()->id());
- UnloadedExtensionInfo details(extension(),
- UnloadedExtensionInfo::REASON_UNINSTALL);
- idle_manager_->Observe(
- chrome::NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED,
- content::Source<Profile>(browser()->profile()),
- content::Details<UnloadedExtensionInfo>(&details));
+ ExtensionRegistry* registry = ExtensionRegistry::Get(browser()->profile());
+ registry->TriggerOnUnloaded(extension(),
+ UnloadedExtensionInfo::REASON_UNINSTALL);
}
// Verifies that re-adding a listener after a state change doesn't immediately
diff --git a/chrome/browser/extensions/api/idle/idle_manager.cc b/chrome/browser/extensions/api/idle/idle_manager.cc
index 6e97ec0..ab88387 100644
--- a/chrome/browser/extensions/api/idle/idle_manager.cc
+++ b/chrome/browser/extensions/api/idle/idle_manager.cc
@@ -7,14 +7,12 @@
#include <utility>
#include "base/stl_util.h"
-#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/extensions/api/idle/idle_api_constants.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/common/extensions/api/idle.h"
#include "chrome/common/extensions/extension_constants.h"
-#include "content/public/browser/notification_details.h"
-#include "content/public/browser/notification_source.h"
#include "extensions/browser/event_router.h"
+#include "extensions/browser/extension_registry.h"
#include "extensions/common/extension.h"
namespace keys = extensions::idle_api_constants;
@@ -125,15 +123,15 @@ IdleManager::IdleManager(Profile* profile)
last_state_(IDLE_STATE_ACTIVE),
weak_factory_(this),
idle_time_provider_(new DefaultIdleProvider()),
- event_delegate_(new DefaultEventDelegate(profile)) {
+ event_delegate_(new DefaultEventDelegate(profile)),
+ extension_registry_observer_(this) {
}
IdleManager::~IdleManager() {
}
void IdleManager::Init() {
- registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED,
- content::Source<Profile>(profile_->GetOriginalProfile()));
+ extension_registry_observer_.Add(ExtensionRegistry::Get(profile_));
event_delegate_->RegisterObserver(this);
}
@@ -142,18 +140,11 @@ void IdleManager::Shutdown() {
event_delegate_->UnregisterObserver(this);
}
-void IdleManager::Observe(int type,
- const content::NotificationSource& source,
- const content::NotificationDetails& details) {
+void IdleManager::OnExtensionUnloaded(content::BrowserContext* browser_context,
+ const Extension* extension,
+ UnloadedExtensionInfo::Reason reason) {
DCHECK(thread_checker_.CalledOnValidThread());
-
- if (type == chrome::NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED) {
- const Extension* extension =
- content::Details<extensions::UnloadedExtensionInfo>(details)->extension;
- monitors_.erase(extension->id());
- } else {
- NOTREACHED();
- }
+ monitors_.erase(extension->id());
}
void IdleManager::OnListenerAdded(const EventListenerInfo& details) {
diff --git a/chrome/browser/extensions/api/idle/idle_manager.h b/chrome/browser/extensions/api/idle/idle_manager.h
index e93b0b2..4752917 100644
--- a/chrome/browser/extensions/api/idle/idle_manager.h
+++ b/chrome/browser/extensions/api/idle/idle_manager.h
@@ -11,13 +11,13 @@
#include "base/callback_forward.h"
#include "base/gtest_prod_util.h"
#include "base/memory/weak_ptr.h"
+#include "base/scoped_observer.h"
#include "base/threading/thread_checker.h"
#include "base/timer/timer.h"
#include "chrome/browser/idle.h"
#include "components/keyed_service/core/keyed_service.h"
-#include "content/public/browser/notification_observer.h"
-#include "content/public/browser/notification_registrar.h"
#include "extensions/browser/event_router.h"
+#include "extensions/browser/extension_registry_observer.h"
namespace base {
class StringValue;
@@ -26,6 +26,7 @@ class StringValue;
class Profile;
namespace extensions {
+class ExtensionRegistry;
typedef base::Callback<void(IdleState)> QueryStateCallback;
@@ -37,7 +38,7 @@ struct IdleMonitor {
int threshold;
};
-class IdleManager : public content::NotificationObserver,
+class IdleManager : public ExtensionRegistryObserver,
public EventRouter::Observer,
public KeyedService {
public:
@@ -75,10 +76,11 @@ class IdleManager : public content::NotificationObserver,
// KeyedService implementation.
virtual void Shutdown() OVERRIDE;
- // content::NotificationDelegate implementation.
- virtual void Observe(int type,
- const content::NotificationSource& source,
- const content::NotificationDetails& details) OVERRIDE;
+ // ExtensionRegistryObserver implementation.
+ virtual void OnExtensionUnloaded(
+ content::BrowserContext* browser_context,
+ const Extension* extension,
+ UnloadedExtensionInfo::Reason reason) OVERRIDE;
// EventRouter::Observer implementation.
virtual void OnListenerAdded(const EventListenerInfo& details) OVERRIDE;
@@ -125,13 +127,16 @@ class IdleManager : public content::NotificationObserver,
base::RepeatingTimer<IdleManager> poll_timer_;
base::WeakPtrFactory<IdleManager> weak_factory_;
- content::NotificationRegistrar registrar_;
scoped_ptr<IdleTimeProvider> idle_time_provider_;
scoped_ptr<EventDelegate> event_delegate_;
base::ThreadChecker thread_checker_;
+ // Listen to extension unloaded notification.
+ ScopedObserver<ExtensionRegistry, ExtensionRegistryObserver>
+ extension_registry_observer_;
+
DISALLOW_COPY_AND_ASSIGN(IdleManager);
};
diff --git a/chrome/browser/extensions/api/push_messaging/push_messaging_api.cc b/chrome/browser/extensions/api/push_messaging/push_messaging_api.cc
index 95684dd..e1effd90 100644
--- a/chrome/browser/extensions/api/push_messaging/push_messaging_api.cc
+++ b/chrome/browser/extensions/api/push_messaging/push_messaging_api.cc
@@ -28,6 +28,7 @@
#include "content/public/browser/notification_details.h"
#include "content/public/browser/notification_source.h"
#include "extensions/browser/event_router.h"
+#include "extensions/browser/extension_registry.h"
#include "extensions/browser/extension_system_provider.h"
#include "extensions/browser/extensions_browser_client.h"
#include "extensions/common/extension.h"
@@ -75,8 +76,7 @@ void PushMessagingEventRouter::OnMessage(const std::string& extension_id,
<< "' extension = '" << extension_id << "'";
scoped_ptr<base::ListValue> args(glue::OnMessage::Create(message));
- scoped_ptr<extensions::Event> event(
- new extensions::Event(glue::OnMessage::kEventName, args.Pass()));
+ scoped_ptr<Event> event(new Event(glue::OnMessage::kEventName, args.Pass()));
event->restrict_to_browser_context = profile_;
EventRouter::Get(profile_)->DispatchEventToExtension(
extension_id, event.Pass());
@@ -287,14 +287,11 @@ void PushMessagingGetChannelIdFunction::OnObfuscatedGaiaIdFetchFailure(
}
PushMessagingAPI::PushMessagingAPI(content::BrowserContext* context)
- : profile_(Profile::FromBrowserContext(context)) {
+ : extension_registry_observer_(this),
+ profile_(Profile::FromBrowserContext(context)) {
+ extension_registry_observer_.Add(ExtensionRegistry::Get(profile_));
registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_INSTALLED,
content::Source<Profile>(profile_->GetOriginalProfile()));
- registrar_.Add(this,
- chrome::NOTIFICATION_EXTENSION_LOADED_DEPRECATED,
- content::Source<Profile>(profile_->GetOriginalProfile()));
- registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED,
- content::Source<Profile>(profile_->GetOriginalProfile()));
}
PushMessagingAPI::~PushMessagingAPI() {
@@ -319,46 +316,56 @@ PushMessagingAPI::GetFactoryInstance() {
return g_factory.Pointer();
}
-void PushMessagingAPI::Observe(int type,
- const content::NotificationSource& source,
- const content::NotificationDetails& details) {
+bool PushMessagingAPI::InitEventRouterAndHandler() {
invalidation::InvalidationService* invalidation_service =
invalidation::InvalidationServiceFactory::GetForProfile(profile_);
if (!invalidation_service)
- return;
+ return false;
if (!event_router_)
event_router_.reset(new PushMessagingEventRouter(profile_));
if (!handler_) {
- handler_.reset(new PushMessagingInvalidationHandler(
- invalidation_service, event_router_.get()));
+ handler_.reset(new PushMessagingInvalidationHandler(invalidation_service,
+ event_router_.get()));
}
- switch (type) {
- case chrome::NOTIFICATION_EXTENSION_INSTALLED: {
- const Extension* extension =
- content::Details<const InstalledExtensionInfo>(details)->extension;
- if (extension->HasAPIPermission(APIPermission::kPushMessaging)) {
- handler_->SuppressInitialInvalidationsForExtension(extension->id());
- }
- break;
- }
- case chrome::NOTIFICATION_EXTENSION_LOADED_DEPRECATED: {
- const Extension* extension = content::Details<Extension>(details).ptr();
- if (extension->HasAPIPermission(APIPermission::kPushMessaging)) {
- handler_->RegisterExtension(extension->id());
- }
- break;
- }
- case chrome::NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED: {
- const Extension* extension =
- content::Details<UnloadedExtensionInfo>(details)->extension;
- if (extension->HasAPIPermission(APIPermission::kPushMessaging)) {
- handler_->UnregisterExtension(extension->id());
- }
- break;
- }
- default:
- NOTREACHED();
+
+ return true;
+}
+
+void PushMessagingAPI::OnExtensionLoaded(
+ content::BrowserContext* browser_context,
+ const Extension* extension) {
+ if (!InitEventRouterAndHandler())
+ return;
+
+ if (extension->HasAPIPermission(APIPermission::kPushMessaging)) {
+ handler_->RegisterExtension(extension->id());
+ }
+}
+
+void PushMessagingAPI::OnExtensionUnloaded(
+ content::BrowserContext* browser_context,
+ const Extension* extension,
+ UnloadedExtensionInfo::Reason reason) {
+ if (!InitEventRouterAndHandler())
+ return;
+
+ if (extension->HasAPIPermission(APIPermission::kPushMessaging)) {
+ handler_->UnregisterExtension(extension->id());
+ }
+}
+
+void PushMessagingAPI::Observe(int type,
+ const content::NotificationSource& source,
+ const content::NotificationDetails& details) {
+ DCHECK_EQ(type, chrome::NOTIFICATION_EXTENSION_INSTALLED);
+ if (!InitEventRouterAndHandler())
+ return;
+
+ const Extension* extension =
+ content::Details<const InstalledExtensionInfo>(details)->extension;
+ if (extension->HasAPIPermission(APIPermission::kPushMessaging)) {
+ handler_->SuppressInitialInvalidationsForExtension(extension->id());
}
}
diff --git a/chrome/browser/extensions/api/push_messaging/push_messaging_api.h b/chrome/browser/extensions/api/push_messaging/push_messaging_api.h
index 0b5884b..9600a28 100644
--- a/chrome/browser/extensions/api/push_messaging/push_messaging_api.h
+++ b/chrome/browser/extensions/api/push_messaging/push_messaging_api.h
@@ -11,6 +11,7 @@
#include "base/compiler_specific.h"
#include "base/gtest_prod_util.h"
#include "base/memory/scoped_ptr.h"
+#include "base/scoped_observer.h"
#include "chrome/browser/extensions/api/push_messaging/obfuscated_gaia_id_fetcher.h"
#include "chrome/browser/extensions/api/push_messaging/push_messaging_invalidation_handler_delegate.h"
#include "chrome/browser/extensions/chrome_extension_function.h"
@@ -18,6 +19,7 @@
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
#include "extensions/browser/browser_context_keyed_api_factory.h"
+#include "extensions/browser/extension_registry_observer.h"
#include "google_apis/gaia/google_service_auth_error.h"
#include "google_apis/gaia/oauth2_token_service.h"
@@ -28,7 +30,7 @@ class BrowserContext;
}
namespace extensions {
-
+class ExtensionRegistry;
class PushMessagingInvalidationMapper;
// Observes a single InvalidationHandler and generates onMessage events.
@@ -109,7 +111,8 @@ class PushMessagingGetChannelIdFunction
};
class PushMessagingAPI : public BrowserContextKeyedAPI,
- public content::NotificationObserver {
+ public content::NotificationObserver,
+ public ExtensionRegistryObserver {
public:
explicit PushMessagingAPI(content::BrowserContext* context);
virtual ~PushMessagingAPI();
@@ -146,6 +149,17 @@ class PushMessagingAPI : public BrowserContextKeyedAPI,
const content::NotificationSource& source,
const content::NotificationDetails& details) OVERRIDE;
+ // Overridden from ExtensionRegistryObserver.
+ virtual void OnExtensionLoaded(content::BrowserContext* browser_context,
+ const Extension* extension) OVERRIDE;
+ virtual void OnExtensionUnloaded(
+ content::BrowserContext* browser_context,
+ const Extension* extension,
+ UnloadedExtensionInfo::Reason reason) OVERRIDE;
+
+ // Initialize |event_router_| and |handler_|.
+ bool InitEventRouterAndHandler();
+
// Created lazily when an app or extension with the push messaging permission
// is loaded.
scoped_ptr<PushMessagingEventRouter> event_router_;
@@ -153,6 +167,10 @@ class PushMessagingAPI : public BrowserContextKeyedAPI,
content::NotificationRegistrar registrar_;
+ // Listen to extension load, unload notifications.
+ ScopedObserver<ExtensionRegistry, ExtensionRegistryObserver>
+ extension_registry_observer_;
+
Profile* profile_;
DISALLOW_COPY_AND_ASSIGN(PushMessagingAPI);