diff options
Diffstat (limited to 'chrome/browser/sync/util/extensions_activity_monitor.cc')
-rw-r--r-- | chrome/browser/sync/util/extensions_activity_monitor.cc | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/chrome/browser/sync/util/extensions_activity_monitor.cc b/chrome/browser/sync/util/extensions_activity_monitor.cc new file mode 100644 index 0000000..bb94d07 --- /dev/null +++ b/chrome/browser/sync/util/extensions_activity_monitor.cc @@ -0,0 +1,99 @@ +// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/sync/util/extensions_activity_monitor.h" + +#include "base/task.h" +#include "chrome/browser/chrome_thread.h" +#include "chrome/browser/extensions/extension_bookmarks_module.h" +#include "chrome/common/extensions/extension.h" +#include "chrome/common/notification_service.h" + +namespace browser_sync { + +namespace { +// A helper task to register an ExtensionsActivityMonitor as an observer of +// events on the UI thread (even though the monitor may live on another thread). +// This liberates ExtensionsActivityMonitor from having to be ref counted. +class RegistrationTask : public Task { + public: + RegistrationTask(ExtensionsActivityMonitor* monitor, + NotificationRegistrar* registrar) + : monitor_(monitor), registrar_(registrar) {} + virtual ~RegistrationTask() {} + + virtual void Run() { + DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); + + // It would be nice if we could specify a Source for each specific function + // we wanted to observe, but the actual function objects are allocated on + // the fly so there is no reliable object to point to (same problem if we + // wanted to use the string name). Thus, we use all sources and filter in + // Observe. + registrar_->Add(monitor_, NotificationType::EXTENSION_BOOKMARKS_API_INVOKED, + NotificationService::AllSources()); + } + + private: + ExtensionsActivityMonitor* monitor_; + NotificationRegistrar* registrar_; + DISALLOW_COPY_AND_ASSIGN(RegistrationTask); +}; +} // namespace + +ExtensionsActivityMonitor::ExtensionsActivityMonitor() { + ChromeThread::PostTask(ChromeThread::UI, FROM_HERE, + new RegistrationTask(this, ®istrar_)); +} + +ExtensionsActivityMonitor::~ExtensionsActivityMonitor() { + // In some unrelated unit tests, there is no running UI loop. In this case, + // the PostTask in our ctor will not result in anything running, so |this| + // won't be used for anything. In this case (or whenever no registration took + // place) and only this case we allow destruction on another loop, but this + // isn't something a client of this class can control; it happens implicitly + // by not having a running UI thread. + if (!registrar_.IsEmpty()) { + DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); + + // The registrar calls RemoveAll in its dtor (which would happen in a + // moment but explicitly call this so it is clear why we need to be on the + // ui_loop_. + registrar_.RemoveAll(); + } +} + +void ExtensionsActivityMonitor::GetAndClearRecords(Records* buffer) { + AutoLock lock(records_lock_); + buffer->clear(); + buffer->swap(records_); +} + +void ExtensionsActivityMonitor::PutRecords(const Records& records) { + AutoLock lock(records_lock_); + for (Records::const_iterator i = records.begin(); i != records.end(); ++i) { + records_[i->first].extension_id = i->second.extension_id; + records_[i->first].bookmark_write_count += i->second.bookmark_write_count; + } +} + +void ExtensionsActivityMonitor::Observe(NotificationType type, + const NotificationSource& source, + const NotificationDetails& details) { + AutoLock lock(records_lock_); + DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); + const Extension* extension = Source<const Extension>(source).ptr(); + const BookmarksFunction* f = Details<const BookmarksFunction>(details).ptr(); + if (f->name() == "bookmarks.update" || + f->name() == "bookmarks.move" || + f->name() == "bookmarks.create" || + f->name() == "bookmarks.removeTree" || + f->name() == "bookmarks.remove") { + Record& record = records_[extension->id()]; + record.extension_id = extension->id(); + record.bookmark_write_count++; + } +} + +} // namespace browser_sync |