Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1320)

Side by Side Diff: chrome/browser/sync/util/extensions_activity_monitor.cc

Issue 333041: Take 2 at browser_sync::ExtensionsActivityMonitor.... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/sync/util/extensions_activity_monitor.h" 5 #include "chrome/browser/sync/util/extensions_activity_monitor.h"
6 6
7 #include "base/task.h" 7 #include "base/task.h"
8 #include "chrome/browser/chrome_thread.h" 8 #include "chrome/browser/chrome_thread.h"
9 #include "chrome/browser/extensions/extension_bookmarks_module.h" 9 #include "chrome/browser/extensions/extension_bookmarks_module.h"
10 #include "chrome/common/extensions/extension.h" 10 #include "chrome/common/extensions/extension.h"
11 #include "chrome/common/notification_service.h" 11 #include "chrome/common/notification_service.h"
12 12
13 namespace browser_sync { 13 namespace browser_sync {
14 14
15 namespace { 15 namespace {
16 // A helper task to register an ExtensionsActivityMonitor as an observer of 16 // A helper task to register an ExtensionsActivityMonitor as an observer of
17 // events on the UI thread (even though the monitor may live on another thread). 17 // events on the UI thread (even though the monitor may live on another thread).
18 // This liberates ExtensionsActivityMonitor from having to be ref counted. 18 // This liberates ExtensionsActivityMonitor from having to be ref counted.
19 class RegistrationTask : public Task { 19 class RegistrationTask : public Task {
20 public: 20 public:
21 RegistrationTask(ExtensionsActivityMonitor* monitor, 21 RegistrationTask(ExtensionsActivityMonitor* monitor,
22 MessageLoop* ui_loop,
23 NotificationRegistrar* registrar) 22 NotificationRegistrar* registrar)
24 : monitor_(monitor), ui_loop_(ui_loop), registrar_(registrar) {} 23 : monitor_(monitor), registrar_(registrar) {}
25 virtual ~RegistrationTask() {} 24 virtual ~RegistrationTask() {}
26 25
27 virtual void Run() { 26 virtual void Run() {
28 DCHECK_EQ(MessageLoop::current(), 27 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
29 ChromeThread::GetMessageLoop(ChromeThread::UI));
30 28
31 // It would be nice if we could specify a Source for each specific function 29 // It would be nice if we could specify a Source for each specific function
32 // we wanted to observe, but the actual function objects are allocated on 30 // we wanted to observe, but the actual function objects are allocated on
33 // the fly so there is no reliable object to point to (same problem if we 31 // the fly so there is no reliable object to point to (same problem if we
34 // wanted to use the string name). Thus, we use all sources and filter in 32 // wanted to use the string name). Thus, we use all sources and filter in
35 // Observe. 33 // Observe.
36 registrar_->Add(monitor_, NotificationType::EXTENSION_BOOKMARKS_API_INVOKED, 34 registrar_->Add(monitor_, NotificationType::EXTENSION_BOOKMARKS_API_INVOKED,
37 NotificationService::AllSources()); 35 NotificationService::AllSources());
38 } 36 }
39 37
40 private: 38 private:
41 ExtensionsActivityMonitor* monitor_; 39 ExtensionsActivityMonitor* monitor_;
42 MessageLoop* const ui_loop_;
43 NotificationRegistrar* registrar_; 40 NotificationRegistrar* registrar_;
44 DISALLOW_COPY_AND_ASSIGN(RegistrationTask); 41 DISALLOW_COPY_AND_ASSIGN(RegistrationTask);
45 }; 42 };
46 } // namespace 43 } // namespace
47 44
48 ExtensionsActivityMonitor::ExtensionsActivityMonitor(MessageLoop* ui_loop) 45 ExtensionsActivityMonitor::ExtensionsActivityMonitor() {
49 : ui_loop_(ui_loop) { 46 ChromeThread::PostTask(ChromeThread::UI, FROM_HERE,
50 ui_loop_->PostTask(FROM_HERE, new RegistrationTask(this, ui_loop, 47 new RegistrationTask(this, &registrar_));
51 &registrar_));
52 } 48 }
53 49
54 ExtensionsActivityMonitor::~ExtensionsActivityMonitor() { 50 ExtensionsActivityMonitor::~ExtensionsActivityMonitor() {
55 DCHECK_EQ(MessageLoop::current(), ui_loop_); 51 // In some unrelated unit tests, there is no running UI loop. In this case,
56 // The registrar calls RemoveAll in its dtor (which would happen in a moment) 52 // the PostTask in our ctor will not result in anything running, so |this|
57 // but explicitly call this so it is clear why we need to be on the ui_loop_. 53 // won't be used for anything. In this case (or whenever no registration took
58 registrar_.RemoveAll(); 54 // place) and only this case we allow destruction on another loop, but this
55 // isn't something a client of this class can control; it happens implicitly
56 // by not having a running UI thread.
57 if (!registrar_.IsEmpty()) {
58 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
59
60 // The registrar calls RemoveAll in its dtor (which would happen in a
61 // moment but explicitly call this so it is clear why we need to be on the
62 // ui_loop_.
63 registrar_.RemoveAll();
64 }
59 } 65 }
60 66
61 void ExtensionsActivityMonitor::GetAndClearRecords(Records* buffer) { 67 void ExtensionsActivityMonitor::GetAndClearRecords(Records* buffer) {
62 AutoLock lock(records_lock_); 68 AutoLock lock(records_lock_);
63 buffer->clear(); 69 buffer->clear();
64 buffer->swap(records_); 70 buffer->swap(records_);
65 } 71 }
66 72
67 void ExtensionsActivityMonitor::PutRecords(const Records& records) { 73 void ExtensionsActivityMonitor::PutRecords(const Records& records) {
68 AutoLock lock(records_lock_); 74 AutoLock lock(records_lock_);
69 for (Records::const_iterator i = records.begin(); i != records.end(); ++i) { 75 for (Records::const_iterator i = records.begin(); i != records.end(); ++i) {
70 records_[i->first].extension_id = i->second.extension_id; 76 records_[i->first].extension_id = i->second.extension_id;
71 records_[i->first].bookmark_write_count += i->second.bookmark_write_count; 77 records_[i->first].bookmark_write_count += i->second.bookmark_write_count;
72 } 78 }
73 } 79 }
74 80
75 void ExtensionsActivityMonitor::Observe(NotificationType type, 81 void ExtensionsActivityMonitor::Observe(NotificationType type,
76 const NotificationSource& source, 82 const NotificationSource& source,
77 const NotificationDetails& details) { 83 const NotificationDetails& details) {
78 AutoLock lock(records_lock_); 84 AutoLock lock(records_lock_);
79 DCHECK_EQ(MessageLoop::current(), ui_loop_); 85 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
80 const Extension* extension = Source<const Extension>(source).ptr(); 86 const Extension* extension = Source<const Extension>(source).ptr();
81 const BookmarksFunction* f = Details<const BookmarksFunction>(details).ptr(); 87 const BookmarksFunction* f = Details<const BookmarksFunction>(details).ptr();
82 if (f->name() == "bookmarks.update" || 88 if (f->name() == "bookmarks.update" ||
83 f->name() == "bookmarks.move" || 89 f->name() == "bookmarks.move" ||
84 f->name() == "bookmarks.create" || 90 f->name() == "bookmarks.create" ||
85 f->name() == "bookmarks.removeTree" || 91 f->name() == "bookmarks.removeTree" ||
86 f->name() == "bookmarks.remove") { 92 f->name() == "bookmarks.remove") {
87 Record& record = records_[extension->id()]; 93 Record& record = records_[extension->id()];
88 record.extension_id = extension->id(); 94 record.extension_id = extension->id();
89 record.bookmark_write_count++; 95 record.bookmark_write_count++;
90 } 96 }
91 } 97 }
92 98
93 } // namespace browser_sync 99 } // namespace browser_sync
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698