// Copyright (c) 2006-2008 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 "chrome/browser/chrome_plugin_browsing_context.h" #include "base/message_loop.h" #include "base/singleton.h" #include "chrome/browser/chrome_thread.h" CPBrowsingContextManager* CPBrowsingContextManager::Instance() { #ifndef NDEBUG // IO loop is NULL in unit tests. if (ChromeThread::GetMessageLoop(ChromeThread::IO)) { DCHECK(MessageLoop::current() == ChromeThread::GetMessageLoop(ChromeThread::IO)); } #endif return Singleton::get(); } CPBrowsingContextManager::CPBrowsingContextManager() { NotificationService::current()->AddObserver( this, NOTIFY_URL_REQUEST_CONTEXT_RELEASED, NotificationService::AllSources()); } CPBrowsingContextManager::~CPBrowsingContextManager() { // We don't remove ourselves as an observer because we are a Singleton object, // and NotifcationService is likely gone by this point. } CPBrowsingContext CPBrowsingContextManager::Allocate( URLRequestContext* context) { int32 map_id = map_.Add(context); return static_cast(map_id); } URLRequestContext* CPBrowsingContextManager::ToURLRequestContext( CPBrowsingContext id) { return map_.Lookup(static_cast(id)); } CPBrowsingContext CPBrowsingContextManager::Lookup(URLRequestContext* context) { ReverseMap::const_iterator it = reverse_map_.find(context); if (it == reverse_map_.end()) { CPBrowsingContext id = Allocate(context); reverse_map_[context] = id; return id; } else { return it->second; } } void CPBrowsingContextManager::Observe(NotificationType type, const NotificationSource& source, const NotificationDetails& details) { DCHECK(type == NOTIFY_URL_REQUEST_CONTEXT_RELEASED); URLRequestContext* context = Source(source).ptr(); // Multiple CPBrowsingContexts may refer to the same URLRequestContext. // Remove after collecting all entries, since removing may invalidate // iterators. std::vector ids_to_remove; for (Map::const_iterator it = map_.begin(); it != map_.end(); ++it) { if (it->second == context) ids_to_remove.push_back(it->first); } for (size_t i = 0; i < ids_to_remove.size(); ++i) { map_.Remove(ids_to_remove[i]); } reverse_map_.erase(context); }