Commit d0c44b74 authored by limasdf@gmail.com's avatar limasdf@gmail.com

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
parent b9dfeb99
...@@ -16,10 +16,10 @@ ...@@ -16,10 +16,10 @@
#include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/state_store.h" #include "chrome/browser/extensions/state_store.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/common/extensions/api/alarms.h" #include "chrome/common/extensions/api/alarms.h"
#include "content/public/browser/notification_service.h" #include "content/public/browser/notification_service.h"
#include "extensions/browser/event_router.h" #include "extensions/browser/event_router.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/extension_system.h" #include "extensions/browser/extension_system.h"
namespace extensions { namespace extensions {
...@@ -97,16 +97,16 @@ scoped_ptr<base::ListValue> AlarmsToValue(const std::vector<Alarm>& alarms) { ...@@ -97,16 +97,16 @@ scoped_ptr<base::ListValue> AlarmsToValue(const std::vector<Alarm>& alarms) {
// AlarmManager // AlarmManager
AlarmManager::AlarmManager(content::BrowserContext* context) AlarmManager::AlarmManager(content::BrowserContext* context)
: profile_(Profile::FromBrowserContext(context)), : browser_context_(context),
clock_(new base::DefaultClock()), 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, registrar_.Add(this,
chrome::NOTIFICATION_EXTENSION_LOADED_DEPRECATED, chrome::NOTIFICATION_EXTENSION_UNINSTALLED,
content::Source<Profile>(profile_)); content::Source<content::BrowserContext>(browser_context_));
registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNINSTALLED,
content::Source<Profile>(profile_));
StateStore* storage = ExtensionSystem::Get(profile_)->state_store(); StateStore* storage = ExtensionSystem::Get(browser_context_)->state_store();
if (storage) if (storage)
storage->RegisterKey(kRegisteredAlarms); storage->RegisterKey(kRegisteredAlarms);
} }
...@@ -226,8 +226,8 @@ AlarmManager::GetFactoryInstance() { ...@@ -226,8 +226,8 @@ AlarmManager::GetFactoryInstance() {
} }
// static // static
AlarmManager* AlarmManager::Get(Profile* profile) { AlarmManager* AlarmManager::Get(content::BrowserContext* browser_context) {
return BrowserContextKeyedAPIFactory<AlarmManager>::Get(profile); return BrowserContextKeyedAPIFactory<AlarmManager>::Get(browser_context);
} }
void AlarmManager::RemoveAlarmIterator(const AlarmIterator& iter) { void AlarmManager::RemoveAlarmIterator(const AlarmIterator& iter) {
...@@ -290,7 +290,7 @@ void AlarmManager::AddAlarmImpl(const std::string& extension_id, ...@@ -290,7 +290,7 @@ void AlarmManager::AddAlarmImpl(const std::string& extension_id,
} }
void AlarmManager::WriteToStorage(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) if (!storage)
return; return;
...@@ -410,35 +410,26 @@ void AlarmManager::RunWhenReady( ...@@ -410,35 +410,26 @@ void AlarmManager::RunWhenReady(
it->second.push(action); 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( void AlarmManager::Observe(
int type, int type,
const content::NotificationSource& source, const content::NotificationSource& source,
const content::NotificationDetails& details) { const content::NotificationDetails& details) {
switch (type) { DCHECK_EQ(type, chrome::NOTIFICATION_EXTENSION_UNINSTALLED);
case chrome::NOTIFICATION_EXTENSION_LOADED_DEPRECATED: { const Extension* extension = content::Details<const Extension>(details).ptr();
const Extension* extension = RemoveAllAlarms(extension->id(), base::Bind(RemoveAllOnUninstallCallback));
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;
}
} }
// AlarmManager::Alarm // AlarmManager::Alarm
......
...@@ -12,14 +12,14 @@ ...@@ -12,14 +12,14 @@
#include "base/callback.h" #include "base/callback.h"
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "base/scoped_observer.h"
#include "base/timer/timer.h" #include "base/timer/timer.h"
#include "chrome/common/extensions/api/alarms.h" #include "chrome/common/extensions/api/alarms.h"
#include "content/public/browser/notification_observer.h" #include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h" #include "content/public/browser/notification_registrar.h"
#include "extensions/browser/browser_context_keyed_api_factory.h" #include "extensions/browser/browser_context_keyed_api_factory.h"
#include "extensions/browser/extension_function.h" #include "extensions/browser/extension_function.h"
#include "extensions/browser/extension_registry_observer.h"
class Profile;
namespace base { namespace base {
class Clock; class Clock;
...@@ -30,8 +30,8 @@ class BrowserContext; ...@@ -30,8 +30,8 @@ class BrowserContext;
} // namespace content } // namespace content
namespace extensions { namespace extensions {
class ExtensionAlarmsSchedulingTest; class ExtensionAlarmsSchedulingTest;
class ExtensionRegistry;
struct Alarm { struct Alarm {
Alarm(); Alarm();
...@@ -57,6 +57,7 @@ struct Alarm { ...@@ -57,6 +57,7 @@ struct Alarm {
// There is one manager per virtual Profile. // There is one manager per virtual Profile.
class AlarmManager : public BrowserContextKeyedAPI, class AlarmManager : public BrowserContextKeyedAPI,
public content::NotificationObserver, public content::NotificationObserver,
public ExtensionRegistryObserver,
public base::SupportsWeakPtr<AlarmManager> { public base::SupportsWeakPtr<AlarmManager> {
public: public:
typedef std::vector<Alarm> AlarmList; typedef std::vector<Alarm> AlarmList;
...@@ -114,8 +115,8 @@ class AlarmManager : public BrowserContextKeyedAPI, ...@@ -114,8 +115,8 @@ class AlarmManager : public BrowserContextKeyedAPI,
// BrowserContextKeyedAPI implementation. // BrowserContextKeyedAPI implementation.
static BrowserContextKeyedAPIFactory<AlarmManager>* GetFactoryInstance(); static BrowserContextKeyedAPIFactory<AlarmManager>* GetFactoryInstance();
// Convenience method to get the AlarmManager for a profile. // Convenience method to get the AlarmManager for a content::BrowserContext.
static AlarmManager* Get(Profile* profile); static AlarmManager* Get(content::BrowserContext* browser_context);
private: private:
friend void RunScheduleNextPoll(AlarmManager*); friend void RunScheduleNextPoll(AlarmManager*);
...@@ -208,17 +209,25 @@ class AlarmManager : public BrowserContextKeyedAPI, ...@@ -208,17 +209,25 @@ class AlarmManager : public BrowserContextKeyedAPI,
const content::NotificationSource& source, const content::NotificationSource& source,
const content::NotificationDetails& details) OVERRIDE; const content::NotificationDetails& details) OVERRIDE;
// Overridden from extensions::ExtensionRegistryObserver.
virtual void OnExtensionLoaded(content::BrowserContext* browser_context,
const Extension* extension) OVERRIDE;
// BrowserContextKeyedAPI implementation. // BrowserContextKeyedAPI implementation.
static const char* service_name() { static const char* service_name() {
return "AlarmManager"; return "AlarmManager";
} }
static const bool kServiceHasOwnInstanceInIncognito = true; static const bool kServiceHasOwnInstanceInIncognito = true;
Profile* const profile_; content::BrowserContext* const browser_context_;
scoped_ptr<base::Clock> clock_; scoped_ptr<base::Clock> clock_;
content::NotificationRegistrar registrar_; content::NotificationRegistrar registrar_;
scoped_ptr<Delegate> delegate_; scoped_ptr<Delegate> delegate_;
// Listen to extension load notifications.
ScopedObserver<ExtensionRegistry, ExtensionRegistryObserver>
extension_registry_observer_;
// The timer for this alarm manager. // The timer for this alarm manager.
base::OneShotTimer<AlarmManager> timer_; base::OneShotTimer<AlarmManager> timer_;
......
...@@ -119,7 +119,7 @@ bool AlarmsCreateFunction::RunAsync() { ...@@ -119,7 +119,7 @@ bool AlarmsCreateFunction::RunAsync() {
Manifest::IsUnpackedLocation(GetExtension()->location()) ? Manifest::IsUnpackedLocation(GetExtension()->location()) ?
kDevDelayMinimum : kReleaseDelayMinimum), kDevDelayMinimum : kReleaseDelayMinimum),
clock_->Now()); clock_->Now());
AlarmManager::Get(GetProfile())->AddAlarm( AlarmManager::Get(browser_context())->AddAlarm(
extension_id(), alarm, base::Bind(&AlarmsCreateFunction::Callback, this)); extension_id(), alarm, base::Bind(&AlarmsCreateFunction::Callback, this));
return true; return true;
...@@ -134,7 +134,7 @@ bool AlarmsGetFunction::RunAsync() { ...@@ -134,7 +134,7 @@ bool AlarmsGetFunction::RunAsync() {
EXTENSION_FUNCTION_VALIDATE(params.get()); EXTENSION_FUNCTION_VALIDATE(params.get());
std::string name = params->name.get() ? *params->name : kDefaultAlarmName; std::string name = params->name.get() ? *params->name : kDefaultAlarmName;
AlarmManager::Get(GetProfile()) AlarmManager::Get(browser_context())
->GetAlarm(extension_id(), ->GetAlarm(extension_id(),
name, name,
base::Bind(&AlarmsGetFunction::Callback, this, name)); base::Bind(&AlarmsGetFunction::Callback, this, name));
...@@ -151,7 +151,7 @@ void AlarmsGetFunction::Callback( ...@@ -151,7 +151,7 @@ void AlarmsGetFunction::Callback(
} }
bool AlarmsGetAllFunction::RunAsync() { bool AlarmsGetAllFunction::RunAsync() {
AlarmManager::Get(GetProfile())->GetAllAlarms( AlarmManager::Get(browser_context())->GetAllAlarms(
extension_id(), base::Bind(&AlarmsGetAllFunction::Callback, this)); extension_id(), base::Bind(&AlarmsGetAllFunction::Callback, this));
return true; return true;
} }
...@@ -176,7 +176,7 @@ bool AlarmsClearFunction::RunAsync() { ...@@ -176,7 +176,7 @@ bool AlarmsClearFunction::RunAsync() {
EXTENSION_FUNCTION_VALIDATE(params.get()); EXTENSION_FUNCTION_VALIDATE(params.get());
std::string name = params->name.get() ? *params->name : kDefaultAlarmName; std::string name = params->name.get() ? *params->name : kDefaultAlarmName;
AlarmManager::Get(GetProfile()) AlarmManager::Get(browser_context())
->RemoveAlarm(extension_id(), ->RemoveAlarm(extension_id(),
name, name,
base::Bind(&AlarmsClearFunction::Callback, this, name)); base::Bind(&AlarmsClearFunction::Callback, this, name));
...@@ -190,7 +190,7 @@ void AlarmsClearFunction::Callback(const std::string& name, bool success) { ...@@ -190,7 +190,7 @@ void AlarmsClearFunction::Callback(const std::string& name, bool success) {
} }
bool AlarmsClearAllFunction::RunAsync() { bool AlarmsClearAllFunction::RunAsync() {
AlarmManager::Get(GetProfile())->RemoveAllAlarms( AlarmManager::Get(browser_context())->RemoveAllAlarms(
extension_id(), base::Bind(&AlarmsClearAllFunction::Callback, this)); extension_id(), base::Bind(&AlarmsClearAllFunction::Callback, this));
return true; return true;
} }
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include "content/public/browser/notification_service.h" #include "content/public/browser/notification_service.h"
#include "content/public/browser/notification_source.h" #include "content/public/browser/notification_source.h"
#include "content/public/browser/render_process_host.h" #include "content/public/browser/render_process_host.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/common/extension.h" #include "extensions/common/extension.h"
namespace extensions { namespace extensions {
...@@ -43,17 +44,13 @@ bool IsWebView(const RulesRegistryService::WebViewKey& webview_key) { ...@@ -43,17 +44,13 @@ bool IsWebView(const RulesRegistryService::WebViewKey& webview_key) {
RulesRegistryService::RulesRegistryService(content::BrowserContext* context) RulesRegistryService::RulesRegistryService(content::BrowserContext* context)
: content_rules_registry_(NULL), : content_rules_registry_(NULL),
extension_registry_observer_(this),
profile_(Profile::FromBrowserContext(context)) { profile_(Profile::FromBrowserContext(context)) {
if (profile_) { if (profile_) {
registrar_.Add(this, extension_registry_observer_.Add(ExtensionRegistry::Get(profile_));
chrome::NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED,
content::Source<Profile>(profile_->GetOriginalProfile()));
registrar_.Add(this, registrar_.Add(this,
chrome::NOTIFICATION_EXTENSION_UNINSTALLED, chrome::NOTIFICATION_EXTENSION_UNINSTALLED,
content::Source<Profile>(profile_->GetOriginalProfile())); content::Source<Profile>(profile_->GetOriginalProfile()));
registrar_.Add(this,
chrome::NOTIFICATION_EXTENSION_LOADED_DEPRECATED,
content::Source<Profile>(profile_->GetOriginalProfile()));
registrar_.Add( registrar_.Add(
this, content::NOTIFICATION_RENDERER_PROCESS_TERMINATED, this, content::NOTIFICATION_RENDERER_PROCESS_TERMINATED,
content::NotificationService::AllBrowserContextsAndSources()); content::NotificationService::AllBrowserContextsAndSources());
...@@ -206,18 +203,24 @@ void RulesRegistryService::NotifyRegistriesHelper( ...@@ -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( void RulesRegistryService::Observe(
int type, int type,
const content::NotificationSource& source, const content::NotificationSource& source,
const content::NotificationDetails& details) { const content::NotificationDetails& details) {
switch (type) { 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: { case chrome::NOTIFICATION_EXTENSION_UNINSTALLED: {
const Extension* extension = const Extension* extension =
content::Details<const Extension>(details).ptr(); content::Details<const Extension>(details).ptr();
...@@ -225,13 +228,6 @@ void RulesRegistryService::Observe( ...@@ -225,13 +228,6 @@ void RulesRegistryService::Observe(
extension->id()); extension->id());
break; 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: { case content::NOTIFICATION_RENDERER_PROCESS_TERMINATED: {
content::RenderProcessHost* process = content::RenderProcessHost* process =
content::Source<content::RenderProcessHost>(source).ptr(); content::Source<content::RenderProcessHost>(source).ptr();
......
...@@ -12,11 +12,13 @@ ...@@ -12,11 +12,13 @@
#include "base/callback_forward.h" #include "base/callback_forward.h"
#include "base/memory/ref_counted.h" #include "base/memory/ref_counted.h"
#include "base/memory/scoped_vector.h" #include "base/memory/scoped_vector.h"
#include "base/scoped_observer.h"
#include "chrome/browser/extensions/api/declarative/rules_registry.h" #include "chrome/browser/extensions/api/declarative/rules_registry.h"
#include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile.h"
#include "content/public/browser/notification_observer.h" #include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h" #include "content/public/browser/notification_registrar.h"
#include "extensions/browser/browser_context_keyed_api_factory.h" #include "extensions/browser/browser_context_keyed_api_factory.h"
#include "extensions/browser/extension_registry_observer.h"
class Profile; class Profile;
...@@ -27,6 +29,7 @@ class NotificationSource; ...@@ -27,6 +29,7 @@ class NotificationSource;
namespace extensions { namespace extensions {
class ContentRulesRegistry; class ContentRulesRegistry;
class ExtensionRegistry;
class RulesRegistry; class RulesRegistry;
class RulesRegistryStorageDelegate; class RulesRegistryStorageDelegate;
} }
...@@ -36,7 +39,8 @@ namespace extensions { ...@@ -36,7 +39,8 @@ namespace extensions {
// This class owns all RulesRegistries implementations of an ExtensionService. // This class owns all RulesRegistries implementations of an ExtensionService.
// This class lives on the UI thread. // This class lives on the UI thread.
class RulesRegistryService : public BrowserContextKeyedAPI, class RulesRegistryService : public BrowserContextKeyedAPI,
public content::NotificationObserver { public content::NotificationObserver,
public ExtensionRegistryObserver {
public: public:
typedef RulesRegistry::WebViewKey WebViewKey; typedef RulesRegistry::WebViewKey WebViewKey;
struct RulesRegistryKey { struct RulesRegistryKey {
...@@ -105,6 +109,14 @@ class RulesRegistryService : public BrowserContextKeyedAPI, ...@@ -105,6 +109,14 @@ class RulesRegistryService : public BrowserContextKeyedAPI,
const content::NotificationSource& source, const content::NotificationSource& source,
const content::NotificationDetails& details) OVERRIDE; 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 // Iterates over all registries, and calls |notification_callback| on them
// with |extension_id| as the argument. If a registry lives on a different // 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 // thread, the call is posted to that thread, so no guarantee of synchronous
...@@ -131,6 +143,10 @@ class RulesRegistryService : public BrowserContextKeyedAPI, ...@@ -131,6 +143,10 @@ class RulesRegistryService : public BrowserContextKeyedAPI,
content::NotificationRegistrar registrar_; content::NotificationRegistrar registrar_;
// Listen to extension load, unloaded notification.
ScopedObserver<ExtensionRegistry, ExtensionRegistryObserver>
extension_registry_observer_;
Profile* profile_; Profile* profile_;
DISALLOW_COPY_AND_ASSIGN(RulesRegistryService); DISALLOW_COPY_AND_ASSIGN(RulesRegistryService);
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include "content/public/browser/notification_details.h" #include "content/public/browser/notification_details.h"
#include "content/public/browser/notification_source.h" #include "content/public/browser/notification_source.h"
#include "extensions/browser/event_router.h" #include "extensions/browser/event_router.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/common/extension.h" #include "extensions/common/extension.h"
#include "testing/gmock/include/gmock/gmock.h" #include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
...@@ -509,12 +510,9 @@ TEST_F(IdleTest, UnloadCleanup) { ...@@ -509,12 +510,9 @@ TEST_F(IdleTest, UnloadCleanup) {
} }
// Threshold will reset after unload (and listen count == 0) // Threshold will reset after unload (and listen count == 0)
UnloadedExtensionInfo details(extension(), ExtensionRegistry* registry = ExtensionRegistry::Get(browser()->profile());
UnloadedExtensionInfo::REASON_UNINSTALL); registry->TriggerOnUnloaded(extension(),
idle_manager_->Observe( UnloadedExtensionInfo::REASON_UNINSTALL);
chrome::NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED,
content::Source<Profile>(browser()->profile()),
content::Details<UnloadedExtensionInfo>(&details));
{ {
ScopedListen listen(idle_manager_, extension()->id()); ScopedListen listen(idle_manager_, extension()->id());
...@@ -530,24 +528,18 @@ TEST_F(IdleTest, UnloadCleanup) { ...@@ -530,24 +528,18 @@ TEST_F(IdleTest, UnloadCleanup) {
// Verifies that unloading an extension with no listeners or threshold works. // Verifies that unloading an extension with no listeners or threshold works.
TEST_F(IdleTest, UnloadOnly) { TEST_F(IdleTest, UnloadOnly) {
UnloadedExtensionInfo details(extension(), ExtensionRegistry* registry = ExtensionRegistry::Get(browser()->profile());
UnloadedExtensionInfo::REASON_UNINSTALL); registry->TriggerOnUnloaded(extension(),
idle_manager_->Observe( UnloadedExtensionInfo::REASON_UNINSTALL);
chrome::NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED,
content::Source<Profile>(browser()->profile()),
content::Details<UnloadedExtensionInfo>(&details));
} }
// Verifies that its ok for the unload notification to happen before all the // Verifies that its ok for the unload notification to happen before all the
// listener removals. // listener removals.
TEST_F(IdleTest, UnloadWhileListening) { TEST_F(IdleTest, UnloadWhileListening) {
ScopedListen listen(idle_manager_, extension()->id()); ScopedListen listen(idle_manager_, extension()->id());
UnloadedExtensionInfo details(extension(), ExtensionRegistry* registry = ExtensionRegistry::Get(browser()->profile());
UnloadedExtensionInfo::REASON_UNINSTALL); registry->TriggerOnUnloaded(extension(),
idle_manager_->Observe( UnloadedExtensionInfo::REASON_UNINSTALL);
chrome::NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED,
content::Source<Profile>(browser()->profile()),
content::Details<UnloadedExtensionInfo>(&details));
} }
// Verifies that re-adding a listener after a state change doesn't immediately // Verifies that re-adding a listener after a state change doesn't immediately
......
...@@ -7,14 +7,12 @@ ...@@ -7,14 +7,12 @@
#include <utility> #include <utility>
#include "base/stl_util.h" #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/extensions/api/idle/idle_api_constants.h"
#include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile.h"
#include "chrome/common/extensions/api/idle.h" #include "chrome/common/extensions/api/idle.h"
#include "chrome/common/extensions/extension_constants.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/event_router.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/common/extension.h" #include "extensions/common/extension.h"
namespace keys = extensions::idle_api_constants; namespace keys = extensions::idle_api_constants;
...@@ -125,15 +123,15 @@ IdleManager::IdleManager(Profile* profile) ...@@ -125,15 +123,15 @@ IdleManager::IdleManager(Profile* profile)
last_state_(IDLE_STATE_ACTIVE), last_state_(IDLE_STATE_ACTIVE),
weak_factory_(this), weak_factory_(this),
idle_time_provider_(new DefaultIdleProvider()), idle_time_provider_(new DefaultIdleProvider()),
event_delegate_(new DefaultEventDelegate(profile)) { event_delegate_(new DefaultEventDelegate(profile)),
extension_registry_observer_(this) {
} }
IdleManager::~IdleManager() { IdleManager::~IdleManager() {
} }
void IdleManager::Init() { void IdleManager::Init() {
registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED, extension_registry_observer_.Add(ExtensionRegistry::Get(profile_));
content::Source<Profile>(profile_->GetOriginalProfile()));
event_delegate_->RegisterObserver(this); event_delegate_->RegisterObserver(this);
} }
...@@ -142,18 +140,11 @@ void IdleManager::Shutdown() { ...@@ -142,18 +140,11 @@ void IdleManager::Shutdown() {
event_delegate_->UnregisterObserver(this); event_delegate_->UnregisterObserver(this);
} }
void IdleManager::Observe(int type, void IdleManager::OnExtensionUnloaded(content::BrowserContext* browser_context,
const content::NotificationSource& source, const Extension* extension,
const content::NotificationDetails& details) { UnloadedExtensionInfo::Reason reason) {
DCHECK(thread_checker_.CalledOnValidThread()); DCHECK(thread_checker_.CalledOnValidThread());
monitors_.erase(extension->id());
if (type == chrome::NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED) {
const Extension* extension =
content::Details<extensions::UnloadedExtensionInfo>(details)->extension;
monitors_.erase(extension->id());
} else {
NOTREACHED();
}
} }
void IdleManager::OnListenerAdded(const EventListenerInfo& details) { void IdleManager::OnListenerAdded(const EventListenerInfo& details) {
......
...@@ -11,13 +11,13 @@ ...@@ -11,13 +11,13 @@
#include "base/callback_forward.h" #include "base/callback_forward.h"
#include "base/gtest_prod_util.h" #include "base/gtest_prod_util.h"
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "base/scoped_observer.h"
#include "base/threading/thread_checker.h" #include "base/threading/thread_checker.h"
#include "base/timer/timer.h" #include "base/timer/timer.h"
#include "chrome/browser/idle.h" #include "chrome/browser/idle.h"
#include "components/keyed_service/core/keyed_service.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/event_router.h"
#include "extensions/browser/extension_registry_observer.h"
namespace base { namespace base {
class StringValue; class StringValue;
...@@ -26,6 +26,7 @@ class StringValue; ...@@ -26,6 +26,7 @@ class StringValue;
class Profile; class Profile;
namespace extensions { namespace extensions {
class ExtensionRegistry;
typedef base::Callback<void(IdleState)> QueryStateCallback; typedef base::Callback<void(IdleState)> QueryStateCallback;
...@@ -37,7 +38,7 @@ struct IdleMonitor { ...@@ -37,7 +38,7 @@ struct IdleMonitor {
int threshold; int threshold;
}; };
class IdleManager : public content::NotificationObserver, class IdleManager : public ExtensionRegistryObserver,
public EventRouter::Observer, public EventRouter::Observer,
public KeyedService { public KeyedService {
public: public:
...@@ -75,10 +76,11 @@ class IdleManager : public content::NotificationObserver, ...@@ -75,10 +76,11 @@ class IdleManager : public content::NotificationObserver,
// KeyedService implementation. // KeyedService implementation.
virtual void Shutdown() OVERRIDE; virtual void Shutdown() OVERRIDE;
// content::NotificationDelegate implementation. // ExtensionRegistryObserver implementation.
virtual void Observe(int type, virtual void OnExtensionUnloaded(
const content::NotificationSource& source, content::BrowserContext* browser_context,
const content::NotificationDetails& details) OVERRIDE; const Extension* extension,
UnloadedExtensionInfo::Reason reason) OVERRIDE;
// EventRouter::Observer implementation. // EventRouter::Observer implementation.
virtual void OnListenerAdded(const EventListenerInfo& details) OVERRIDE; virtual void OnListenerAdded(const EventListenerInfo& details) OVERRIDE;
...@@ -125,13 +127,16 @@ class IdleManager : public content::NotificationObserver, ...@@ -125,13 +127,16 @@ class IdleManager : public content::NotificationObserver,
base::RepeatingTimer<IdleManager> poll_timer_; base::RepeatingTimer<IdleManager> poll_timer_;
base::WeakPtrFactory<IdleManager> weak_factory_; base::WeakPtrFactory<IdleManager> weak_factory_;
content::NotificationRegistrar registrar_;
scoped_ptr<IdleTimeProvider> idle_time_provider_; scoped_ptr<IdleTimeProvider> idle_time_provider_;
scoped_ptr<EventDelegate> event_delegate_; scoped_ptr<EventDelegate> event_delegate_;
base::ThreadChecker thread_checker_; base::ThreadChecker thread_checker_;
// Listen to extension unloaded notification.
ScopedObserver<ExtensionRegistry, ExtensionRegistryObserver>
extension_registry_observer_;
DISALLOW_COPY_AND_ASSIGN(IdleManager); DISALLOW_COPY_AND_ASSIGN(IdleManager);
}; };
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include "content/public/browser/notification_details.h" #include "content/public/browser/notification_details.h"
#include "content/public/browser/notification_source.h" #include "content/public/browser/notification_source.h"
#include "extensions/browser/event_router.h" #include "extensions/browser/event_router.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/extension_system_provider.h" #include "extensions/browser/extension_system_provider.h"
#include "extensions/browser/extensions_browser_client.h" #include "extensions/browser/extensions_browser_client.h"
#include "extensions/common/extension.h" #include "extensions/common/extension.h"
...@@ -75,8 +76,7 @@ void PushMessagingEventRouter::OnMessage(const std::string& extension_id, ...@@ -75,8 +76,7 @@ void PushMessagingEventRouter::OnMessage(const std::string& extension_id,
<< "' extension = '" << extension_id << "'"; << "' extension = '" << extension_id << "'";
scoped_ptr<base::ListValue> args(glue::OnMessage::Create(message)); scoped_ptr<base::ListValue> args(glue::OnMessage::Create(message));
scoped_ptr<extensions::Event> event( scoped_ptr<Event> event(new Event(glue::OnMessage::kEventName, args.Pass()));
new extensions::Event(glue::OnMessage::kEventName, args.Pass()));
event->restrict_to_browser_context = profile_; event->restrict_to_browser_context = profile_;
EventRouter::Get(profile_)->DispatchEventToExtension( EventRouter::Get(profile_)->DispatchEventToExtension(
extension_id, event.Pass()); extension_id, event.Pass());
...@@ -287,14 +287,11 @@ void PushMessagingGetChannelIdFunction::OnObfuscatedGaiaIdFetchFailure( ...@@ -287,14 +287,11 @@ void PushMessagingGetChannelIdFunction::OnObfuscatedGaiaIdFetchFailure(
} }
PushMessagingAPI::PushMessagingAPI(content::BrowserContext* context) 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, registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_INSTALLED,
content::Source<Profile>(profile_->GetOriginalProfile())); 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() { PushMessagingAPI::~PushMessagingAPI() {
...@@ -319,46 +316,56 @@ PushMessagingAPI::GetFactoryInstance() { ...@@ -319,46 +316,56 @@ PushMessagingAPI::GetFactoryInstance() {
return g_factory.Pointer(); return g_factory.Pointer();
} }
void PushMessagingAPI::Observe(int type, bool PushMessagingAPI::InitEventRouterAndHandler() {
const content::NotificationSource& source,
const content::NotificationDetails& details) {
invalidation::InvalidationService* invalidation_service = invalidation::InvalidationService* invalidation_service =
invalidation::InvalidationServiceFactory::GetForProfile(profile_); invalidation::InvalidationServiceFactory::GetForProfile(profile_);
if (!invalidation_service) if (!invalidation_service)
return; return false;
if (!event_router_) if (!event_router_)
event_router_.reset(new PushMessagingEventRouter(profile_)); event_router_.reset(new PushMessagingEventRouter(profile_));
if (!handler_) { if (!handler_) {
handler_.reset(new PushMessagingInvalidationHandler( handler_.reset(new PushMessagingInvalidationHandler(invalidation_service,
invalidation_service, event_router_.get())); event_router_.get()));
} }
switch (type) {
case chrome::NOTIFICATION_EXTENSION_INSTALLED: { return true;
const Extension* extension = }
content::Details<const InstalledExtensionInfo>(details)->extension;
if (extension->HasAPIPermission(APIPermission::kPushMessaging)) { void PushMessagingAPI::OnExtensionLoaded(
handler_->SuppressInitialInvalidationsForExtension(extension->id()); content::BrowserContext* browser_context,
} const Extension* extension) {
break; if (!InitEventRouterAndHandler())
} return;
case chrome::NOTIFICATION_EXTENSION_LOADED_DEPRECATED: {
const Extension* extension = content::Details<Extension>(details).ptr(); if (extension->HasAPIPermission(APIPermission::kPushMessaging)) {
if (extension->HasAPIPermission(APIPermission::kPushMessaging)) { handler_->RegisterExtension(extension->id());
handler_->RegisterExtension(extension->id()); }
} }
break;
} void PushMessagingAPI::OnExtensionUnloaded(
case chrome::NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED: { content::BrowserContext* browser_context,
const Extension* extension = const Extension* extension,
content::Details<UnloadedExtensionInfo>(details)->extension; UnloadedExtensionInfo::Reason reason) {
if (extension->HasAPIPermission(APIPermission::kPushMessaging)) { if (!InitEventRouterAndHandler())
handler_->UnregisterExtension(extension->id()); return;
}
break; if (extension->HasAPIPermission(APIPermission::kPushMessaging)) {
} handler_->UnregisterExtension(extension->id());
default: }
NOTREACHED(); }
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());
} }
} }
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include "base/compiler_specific.h" #include "base/compiler_specific.h"
#include "base/gtest_prod_util.h" #include "base/gtest_prod_util.h"
#include "base/memory/scoped_ptr.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/obfuscated_gaia_id_fetcher.h"
#include "chrome/browser/extensions/api/push_messaging/push_messaging_invalidation_handler_delegate.h" #include "chrome/browser/extensions/api/push_messaging/push_messaging_invalidation_handler_delegate.h"
#include "chrome/browser/extensions/chrome_extension_function.h" #include "chrome/browser/extensions/chrome_extension_function.h"
...@@ -18,6 +19,7 @@ ...@@ -18,6 +19,7 @@
#include "content/public/browser/notification_observer.h" #include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h" #include "content/public/browser/notification_registrar.h"
#include "extensions/browser/browser_context_keyed_api_factory.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/google_service_auth_error.h"
#include "google_apis/gaia/oauth2_token_service.h" #include "google_apis/gaia/oauth2_token_service.h"
...@@ -28,7 +30,7 @@ class BrowserContext; ...@@ -28,7 +30,7 @@ class BrowserContext;
} }
namespace extensions { namespace extensions {
class ExtensionRegistry;
class PushMessagingInvalidationMapper; class PushMessagingInvalidationMapper;
// Observes a single InvalidationHandler and generates onMessage events. // Observes a single InvalidationHandler and generates onMessage events.
...@@ -109,7 +111,8 @@ class PushMessagingGetChannelIdFunction ...@@ -109,7 +111,8 @@ class PushMessagingGetChannelIdFunction
}; };
class PushMessagingAPI : public BrowserContextKeyedAPI, class PushMessagingAPI : public BrowserContextKeyedAPI,
public content::NotificationObserver { public content::NotificationObserver,
public ExtensionRegistryObserver {
public: public:
explicit PushMessagingAPI(content::BrowserContext* context); explicit PushMessagingAPI(content::BrowserContext* context);
virtual ~PushMessagingAPI(); virtual ~PushMessagingAPI();
...@@ -146,6 +149,17 @@ class PushMessagingAPI : public BrowserContextKeyedAPI, ...@@ -146,6 +149,17 @@ class PushMessagingAPI : public BrowserContextKeyedAPI,
const content::NotificationSource& source, const content::NotificationSource& source,
const content::NotificationDetails& details) OVERRIDE; 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 // Created lazily when an app or extension with the push messaging permission
// is loaded. // is loaded.
scoped_ptr<PushMessagingEventRouter> event_router_; scoped_ptr<PushMessagingEventRouter> event_router_;
...@@ -153,6 +167,10 @@ class PushMessagingAPI : public BrowserContextKeyedAPI, ...@@ -153,6 +167,10 @@ class PushMessagingAPI : public BrowserContextKeyedAPI,
content::NotificationRegistrar registrar_; content::NotificationRegistrar registrar_;
// Listen to extension load, unload notifications.
ScopedObserver<ExtensionRegistry, ExtensionRegistryObserver>
extension_registry_observer_;
Profile* profile_; Profile* profile_;
DISALLOW_COPY_AND_ASSIGN(PushMessagingAPI); DISALLOW_COPY_AND_ASSIGN(PushMessagingAPI);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment