OLD | NEW |
| (Empty) |
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 | |
3 // found in the LICENSE file. | |
4 | |
5 #include "chrome/browser/sync/util/extensions_activity_monitor.h" | |
6 | |
7 #include "base/task.h" | |
8 #include "chrome/browser/chrome_thread.h" | |
9 #include "chrome/browser/extensions/extension_bookmarks_module.h" | |
10 #include "chrome/common/extensions/extension.h" | |
11 #include "chrome/common/notification_service.h" | |
12 | |
13 namespace browser_sync { | |
14 | |
15 namespace { | |
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). | |
18 // This liberates ExtensionsActivityMonitor from having to be ref counted. | |
19 class RegistrationTask : public Task { | |
20 public: | |
21 RegistrationTask(ExtensionsActivityMonitor* monitor, | |
22 MessageLoop* ui_loop, | |
23 NotificationRegistrar* registrar) | |
24 : monitor_(monitor), ui_loop_(ui_loop), registrar_(registrar) {} | |
25 virtual ~RegistrationTask() {} | |
26 | |
27 virtual void Run() { | |
28 DCHECK_EQ(MessageLoop::current(), | |
29 ChromeThread::GetMessageLoop(ChromeThread::UI)); | |
30 | |
31 // 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 | |
33 // 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 | |
35 // Observe. | |
36 registrar_->Add(monitor_, NotificationType::EXTENSION_BOOKMARKS_API_INVOKED, | |
37 NotificationService::AllSources()); | |
38 } | |
39 | |
40 private: | |
41 ExtensionsActivityMonitor* monitor_; | |
42 MessageLoop* const ui_loop_; | |
43 NotificationRegistrar* registrar_; | |
44 DISALLOW_COPY_AND_ASSIGN(RegistrationTask); | |
45 }; | |
46 } // namespace | |
47 | |
48 ExtensionsActivityMonitor::ExtensionsActivityMonitor(MessageLoop* ui_loop) | |
49 : ui_loop_(ui_loop) { | |
50 ui_loop_->PostTask(FROM_HERE, new RegistrationTask(this, ui_loop, | |
51 ®istrar_)); | |
52 } | |
53 | |
54 ExtensionsActivityMonitor::~ExtensionsActivityMonitor() { | |
55 DCHECK_EQ(MessageLoop::current(), ui_loop_); | |
56 // The registrar calls RemoveAll in its dtor (which would happen in a moment) | |
57 // but explicitly call this so it is clear why we need to be on the ui_loop_. | |
58 registrar_.RemoveAll(); | |
59 } | |
60 | |
61 void ExtensionsActivityMonitor::GetAndClearRecords(Records* buffer) { | |
62 AutoLock lock(records_lock_); | |
63 buffer->clear(); | |
64 buffer->swap(records_); | |
65 } | |
66 | |
67 void ExtensionsActivityMonitor::PutRecords(const Records& records) { | |
68 AutoLock lock(records_lock_); | |
69 for (Records::const_iterator i = records.begin(); i != records.end(); ++i) { | |
70 records_[i->first].extension_id = i->second.extension_id; | |
71 records_[i->first].bookmark_write_count += i->second.bookmark_write_count; | |
72 } | |
73 } | |
74 | |
75 void ExtensionsActivityMonitor::Observe(NotificationType type, | |
76 const NotificationSource& source, | |
77 const NotificationDetails& details) { | |
78 AutoLock lock(records_lock_); | |
79 DCHECK_EQ(MessageLoop::current(), ui_loop_); | |
80 const Extension* extension = Source<const Extension>(source).ptr(); | |
81 const BookmarksFunction* f = Details<const BookmarksFunction>(details).ptr(); | |
82 if (f->name() == "bookmarks.update" || | |
83 f->name() == "bookmarks.move" || | |
84 f->name() == "bookmarks.create" || | |
85 f->name() == "bookmarks.removeTree" || | |
86 f->name() == "bookmarks.remove") { | |
87 Record& record = records_[extension->id()]; | |
88 record.extension_id = extension->id(); | |
89 record.bookmark_write_count++; | |
90 } | |
91 } | |
92 | |
93 } // namespace browser_sync | |
OLD | NEW |