Index: components/framelet/browser/framelet_memory_tracker.cc |
diff --git a/components/framelet/browser/framelet_memory_tracker.cc b/components/framelet/browser/framelet_memory_tracker.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..a426528d0aef164ccac218a6ff7b1616b34b7f59 |
--- /dev/null |
+++ b/components/framelet/browser/framelet_memory_tracker.cc |
@@ -0,0 +1,103 @@ |
+// Copyright 2015 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 "components/framelet/browser/framelet_memory_tracker.h" |
+ |
+#include "components/framelet/browser/framelet_memory_tracker_client.h" |
+#include "components/framelet/common/framelet_constants.h" |
+#include "components/framelet/common/framelet_messages.h" |
+#include "content/public/browser/browser_context.h" |
+#include "content/public/browser/render_view_host.h" |
+#include "content/public/common/child_process_host.h" |
+ |
+namespace framelet { |
+ |
+namespace { |
+ |
+bool SendMessageToClient(const FrameletMemoryTracker::ClientID& client_id, |
+ IPC::Message* message) { |
+ content::RenderViewHost* rvh = content::RenderViewHost::FromID( |
+ client_id.render_process_id(), client_id.routing_id()); |
+ if (!rvh) { |
+ delete message; |
+ return false; |
+ } |
+ return rvh->Send(message); |
+} |
+ |
+} // namespace |
+ |
+FrameletMemoryTracker::ClientID::ClientID() |
+ : render_process_id_(content::ChildProcessHost::kInvalidUniqueID), |
+ routing_id_(MSG_ROUTING_NONE) {} |
+ |
+FrameletMemoryTracker::ClientID::ClientID(int render_process_id, int routing_id) |
+ : render_process_id_(render_process_id), routing_id_(routing_id) {} |
+ |
+FrameletMemoryTracker::ClientID::~ClientID() {} |
+ |
+bool FrameletMemoryTracker::ClientID::operator<(const ClientID& other) const { |
+ return std::tie(render_process_id_, routing_id_) < |
+ std::tie(other.render_process_id_, other.routing_id_); |
+} |
+ |
+bool FrameletMemoryTracker::ClientID::operator==(const ClientID& other) const { |
+ return (render_process_id_ == other.render_process_id_) && |
+ (routing_id_ == other.routing_id_); |
+} |
+ |
+// static |
+FrameletMemoryTracker* FrameletMemoryTracker::FromBrowserContext( |
+ content::BrowserContext* context) { |
+ FrameletMemoryTracker* tracker = static_cast<FrameletMemoryTracker*>( |
+ context->GetUserData(kFrameletMemoryTrackerKeyName)); |
+ if (!tracker) { |
+ tracker = new FrameletMemoryTracker(); |
+ context->SetUserData(kFrameletMemoryTrackerKeyName, tracker); |
+ } |
+ return tracker; |
+} |
+ |
+void FrameletMemoryTracker::ReportHeapSize(const ClientID& client_id, |
+ int heap_size) { |
+ DCHECK_LT(0u, acks_pending_.count(client_id)); |
+ // The client might have been removed since we issued the heap size request. |
+ if (!clients_.count(client_id)) |
+ return; |
+ clients_[client_id]->ReportHeapSize(heap_size); |
+ acks_pending_.erase(client_id); |
+} |
+ |
+void FrameletMemoryTracker::AddClient(const ClientID& client_id, |
+ FrameletMemoryTrackerClient* client) { |
+ clients_.insert(std::make_pair(client_id, client)); |
+ if (!timer_.IsRunning()) { |
+ timer_.Start(FROM_HERE, base::TimeDelta::FromSeconds(1), this, |
+ &FrameletMemoryTracker::OnElapsedTime); |
+ } |
+} |
+ |
+void FrameletMemoryTracker::RemoveClient(const ClientID& client_id) { |
+ clients_.erase(client_id); |
+ if (clients_.empty() && timer_.IsRunning()) |
+ timer_.Stop(); |
+} |
+ |
+FrameletMemoryTracker::FrameletMemoryTracker() {} |
+ |
+FrameletMemoryTracker::~FrameletMemoryTracker() {} |
+ |
+void FrameletMemoryTracker::OnElapsedTime() { |
+ for (auto& kv : clients_) { |
+ const ClientID& client_id = kv.first; |
+ if (acks_pending_.count(client_id)) |
+ continue; |
+ if (SendMessageToClient(client_id, new ChromeGuestViewMsg_RequestHeapSize( |
+ client_id.routing_id()))) { |
+ acks_pending_.insert(client_id); |
+ } |
+ } |
+} |
+ |
+} // namespace framelet |