Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / content / browser / devtools / devtools_manager.cc
index 6d8da53..f405185 100644 (file)
@@ -6,13 +6,20 @@
 
 #include "base/bind.h"
 #include "base/message_loop/message_loop.h"
+#include "content/browser/devtools/devtools_agent_host_impl.h"
 #include "content/browser/devtools/devtools_netlog_observer.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/content_browser_client.h"
-#include "content/public/browser/devtools_manager_delegate.h"
+#include "content/public/browser/devtools_target.h"
 
 namespace content {
 
+namespace {
+
+int kObserverThrottleInterval = 500; // ms
+
+}  // namespace
+
 // static
 DevToolsManager* DevToolsManager::GetInstance() {
   return Singleton<DevToolsManager>::get();
@@ -20,31 +27,104 @@ DevToolsManager* DevToolsManager::GetInstance() {
 
 DevToolsManager::DevToolsManager()
     : delegate_(GetContentClient()->browser()->GetDevToolsManagerDelegate()),
-      client_count_(0) {
+      update_target_list_required_(false),
+      update_target_list_scheduled_(false),
+      update_target_list_callback_(base::Bind(
+          &DevToolsManager::UpdateTargetListThrottled,
+          base::Unretained(this))) {
 }
 
 DevToolsManager::~DevToolsManager() {
-  DCHECK(!client_count_);
+  DCHECK(!attached_hosts_.size());
+  update_target_list_callback_.Cancel();
 }
 
-void DevToolsManager::OnClientAttached() {
-  if (!client_count_) {
-    BrowserThread::PostTask(
-        BrowserThread::IO,
-        FROM_HERE,
-        base::Bind(&DevToolsNetLogObserver::Attach));
+void DevToolsManager::RenderViewCreated(
+    WebContents* web_contents, RenderViewHost* rvh) {
+  if (observer_list_.might_have_observers()) {
+    // Force agent host creation.
+    DevToolsAgentHost::GetOrCreateFor(web_contents);
+  }
+}
+
+void DevToolsManager::AgentHostChanged(
+    scoped_refptr<DevToolsAgentHost> agent_host) {
+  bool was_attached =
+      attached_hosts_.find(agent_host.get()) != attached_hosts_.end();
+  if (agent_host->IsAttached() && !was_attached) {
+    if (!attached_hosts_.size()) {
+      BrowserThread::PostTask(
+          BrowserThread::IO,
+          FROM_HERE,
+          base::Bind(&DevToolsNetLogObserver::Attach));
+    }
+    attached_hosts_.insert(agent_host.get());
+  } else if (!agent_host->IsAttached() && was_attached) {
+    attached_hosts_.erase(agent_host.get());
+    if (!attached_hosts_.size()) {
+      BrowserThread::PostTask(
+          BrowserThread::IO,
+          FROM_HERE,
+          base::Bind(&DevToolsNetLogObserver::Detach));
+    }
   }
-  client_count_++;
+
+  UpdateTargetList();
+}
+
+void DevToolsManager::AddObserver(Observer* observer) {
+  observer_list_.AddObserver(observer);
+  UpdateTargetList();
+}
+
+void DevToolsManager::RemoveObserver(Observer* observer) {
+  observer_list_.RemoveObserver(observer);
 }
 
-void DevToolsManager::OnClientDetached() {
-  client_count_--;
-  if (!client_count_) {
-    BrowserThread::PostTask(
-        BrowserThread::IO,
+void DevToolsManager::UpdateTargetList() {
+  if (!observer_list_.might_have_observers())
+    return;
+
+  update_target_list_required_ = true;
+  if (!update_target_list_scheduled_)
+    UpdateTargetListThrottled();
+}
+
+void DevToolsManager::UpdateTargetListThrottled() {
+  if (!update_target_list_required_) {
+    update_target_list_scheduled_ = false;
+    return;
+  }
+
+  update_target_list_scheduled_ = true;
+  if (scheduler_.is_null()) {
+    base::MessageLoop::current()->PostDelayedTask(
         FROM_HERE,
-        base::Bind(&DevToolsNetLogObserver::Detach));
+        update_target_list_callback_.callback(),
+        base::TimeDelta::FromMilliseconds(kObserverThrottleInterval));
+  } else {
+    scheduler_.Run(update_target_list_callback_.callback());
   }
+
+  update_target_list_required_ = false;
+  if (!delegate_) {
+    Observer::TargetList empty_list;
+    NotifyTargetListChanged(empty_list);
+    return;
+  }
+  delegate_->EnumerateTargets(base::Bind(
+      &DevToolsManager::NotifyTargetListChanged,
+      base::Unretained(this)));
+}
+
+void DevToolsManager::NotifyTargetListChanged(
+    const Observer::TargetList& targets) {
+  FOR_EACH_OBSERVER(Observer, observer_list_, TargetListChanged(targets));
+  STLDeleteContainerPointers(targets.begin(), targets.end());
+}
+
+void DevToolsManager::SetSchedulerForTest(Scheduler scheduler) {
+  scheduler_ = scheduler;
 }
 
 }  // namespace content