15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "components/visitedlink/browser/visitedlink_event_listener.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 77dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "base/memory/shared_memory.h" 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "components/visitedlink/browser/visitedlink_delegate.h" 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "components/visitedlink/common/visitedlink_messages.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_service.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_types.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/render_process_host.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/render_widget_host.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::Time; 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::TimeDelta; 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::RenderWidgetHost; 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The amount of time we wait to accumulate visited link additions. 2290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)const int kCommitIntervalMs = 100; 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Size of the buffer after which individual link updates deemed not warranted 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// and the overall update should be used instead. 2690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)const unsigned kVisitedLinkBufferThreshold = 50; 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)namespace visitedlink { 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This class manages buffering and sending visited link hashes (fingerprints) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// to renderer based on widget visibility. 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// As opposed to the VisitedLinkEventListener, which coalesces to 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// reduce the rate of messages being sent to render processes, this class 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ensures that the updates occur only when explicitly requested. This is 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// used for RenderProcessHostImpl to only send Add/Reset link events to the 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// renderers when their tabs are visible and the corresponding RenderViews are 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// created. 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class VisitedLinkUpdater { 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit VisitedLinkUpdater(int render_process_id) 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : reset_needed_(false), render_process_id_(render_process_id) { 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Informs the renderer about a new visited link table. 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SendVisitedLinkTable(base::SharedMemory* table_memory) { 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::RenderProcessHost* process = 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::RenderProcessHost::FromID(render_process_id_); 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!process) 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; // Happens in tests 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::SharedMemoryHandle handle_for_process; 535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) table_memory->ShareReadOnlyToProcess(process->GetHandle(), 545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) &handle_for_process); 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (base::SharedMemory::IsHandleValid(handle_for_process)) 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) process->Send(new ChromeViewMsg_VisitedLink_NewTable( 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) handle_for_process)); 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Buffers |links| to update, but doesn't actually relay them. 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void AddLinks(const VisitedLinkCommon::Fingerprints& links) { 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (reset_needed_) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pending_.size() + links.size() > kVisitedLinkBufferThreshold) { 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Once the threshold is reached, there's no need to store pending visited 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // link updates -- we opt for resetting the state for all links. 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddReset(); 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pending_.insert(pending_.end(), links.begin(), links.end()); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Tells the updater that sending individual link updates is no longer 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // necessary and the visited state for all links should be reset. 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void AddReset() { 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reset_needed_ = true; 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pending_.clear(); 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Sends visited link update messages: a list of links whose visited state 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // changed or reset of visited state for all links. 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Update() { 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::RenderProcessHost* process = 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::RenderProcessHost::FromID(render_process_id_); 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!process) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; // Happens in tests 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!process->VisibleWidgetCount()) 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (reset_needed_) { 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) process->Send(new ChromeViewMsg_VisitedLink_Reset()); 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reset_needed_ = false; 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pending_.empty()) 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) process->Send(new ChromeViewMsg_VisitedLink_Add(pending_)); 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pending_.clear(); 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool reset_needed_; 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int render_process_id_; 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VisitedLinkCommon::Fingerprints pending_; 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)VisitedLinkEventListener::VisitedLinkEventListener( 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) VisitedLinkMaster* master, 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::BrowserContext* browser_context) 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : master_(master), 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) browser_context_(browser_context) { 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CREATED, 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::NotificationService::AllBrowserContextsAndSources()); 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_TERMINATED, 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::NotificationService::AllBrowserContextsAndSources()); 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) registrar_.Add(this, content::NOTIFICATION_RENDER_WIDGET_VISIBILITY_CHANGED, 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::NotificationService::AllBrowserContextsAndSources()); 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)VisitedLinkEventListener::~VisitedLinkEventListener() { 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!pending_visited_links_.empty()) 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pending_visited_links_.clear(); 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void VisitedLinkEventListener::NewTable(base::SharedMemory* table_memory) { 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!table_memory) 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Send to all RenderProcessHosts. 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (Updaters::iterator i = updaters_.begin(); i != updaters_.end(); ++i) { 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Make sure to not send to incognito renderers. 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::RenderProcessHost* process = 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::RenderProcessHost::FromID(i->first); 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!process) 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) i->second->SendVisitedLinkTable(table_memory); 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void VisitedLinkEventListener::Add(VisitedLinkMaster::Fingerprint fingerprint) { 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pending_visited_links_.push_back(fingerprint); 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!coalesce_timer_.IsRunning()) { 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) coalesce_timer_.Start(FROM_HERE, 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TimeDelta::FromMilliseconds(kCommitIntervalMs), this, 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &VisitedLinkEventListener::CommitVisitedLinks); 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void VisitedLinkEventListener::Reset() { 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pending_visited_links_.clear(); 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) coalesce_timer_.Stop(); 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (Updaters::iterator i = updaters_.begin(); i != updaters_.end(); ++i) { 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i->second->AddReset(); 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i->second->Update(); 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void VisitedLinkEventListener::CommitVisitedLinks() { 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Send to all RenderProcessHosts. 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (Updaters::iterator i = updaters_.begin(); i != updaters_.end(); ++i) { 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i->second->AddLinks(pending_visited_links_); 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i->second->Update(); 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pending_visited_links_.clear(); 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void VisitedLinkEventListener::Observe( 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int type, 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const content::NotificationSource& source, 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const content::NotificationDetails& details) { 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (type) { 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case content::NOTIFICATION_RENDERER_PROCESS_CREATED: { 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::RenderProcessHost* process = 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::Source<content::RenderProcessHost>(source).ptr(); 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (browser_context_ != process->GetBrowserContext()) 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Happens on browser start up. 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!master_->shared_memory()) 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) updaters_[process->GetID()] = 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) make_linked_ptr(new VisitedLinkUpdater(process->GetID())); 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) updaters_[process->GetID()]->SendVisitedLinkTable( 1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) master_->shared_memory()); 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case content::NOTIFICATION_RENDERER_PROCESS_TERMINATED: { 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::RenderProcessHost* process = 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::Source<content::RenderProcessHost>(source).ptr(); 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (updaters_.count(process->GetID())) { 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) updaters_.erase(process->GetID()); 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case content::NOTIFICATION_RENDER_WIDGET_VISIBILITY_CHANGED: { 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RenderWidgetHost* widget = 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::Source<RenderWidgetHost>(source).ptr(); 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int child_id = widget->GetProcess()->GetID(); 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (updaters_.count(child_id)) 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) updaters_[child_id]->Update(); 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 22090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} // namespace visitedlink 221