Home | History | Annotate | Download | only in browser_context_keyed_service
      1 // Copyright (c) 2012 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 "components/browser_context_keyed_service/browser_context_keyed_service_factory.h"
      6 
      7 #include <map>
      8 
      9 #include "base/logging.h"
     10 #include "base/stl_util.h"
     11 #include "components/browser_context_keyed_service/browser_context_dependency_manager.h"
     12 #include "components/browser_context_keyed_service/browser_context_keyed_service.h"
     13 #include "content/public/browser/browser_context.h"
     14 
     15 void BrowserContextKeyedServiceFactory::SetTestingFactory(
     16     content::BrowserContext* context, FactoryFunction factory) {
     17   // Destroying the context may cause us to lose data about whether |context|
     18   // has our preferences registered on it (since the context object itself
     19   // isn't dead). See if we need to readd it once we've gone through normal
     20   // destruction.
     21   bool add_context = ArePreferencesSetOn(context);
     22 
     23   // We have to go through the shutdown and destroy mechanisms because there
     24   // are unit tests that create a service on a context and then change the
     25   // testing service mid-test.
     26   BrowserContextShutdown(context);
     27   BrowserContextDestroyed(context);
     28 
     29   if (add_context)
     30     MarkPreferencesSetOn(context);
     31 
     32   factories_[context] = factory;
     33 }
     34 
     35 BrowserContextKeyedService*
     36 BrowserContextKeyedServiceFactory::SetTestingFactoryAndUse(
     37     content::BrowserContext* context,
     38     FactoryFunction factory) {
     39   DCHECK(factory);
     40   SetTestingFactory(context, factory);
     41   return GetServiceForBrowserContext(context, true);
     42 }
     43 
     44 BrowserContextKeyedServiceFactory::BrowserContextKeyedServiceFactory(
     45     const char* name, BrowserContextDependencyManager* manager)
     46     : BrowserContextKeyedBaseFactory(name, manager) {
     47 }
     48 
     49 BrowserContextKeyedServiceFactory::~BrowserContextKeyedServiceFactory() {
     50   DCHECK(mapping_.empty());
     51 }
     52 
     53 BrowserContextKeyedService*
     54 BrowserContextKeyedServiceFactory::GetServiceForBrowserContext(
     55     content::BrowserContext* context,
     56     bool create) {
     57   context = GetBrowserContextToUse(context);
     58   if (!context)
     59     return NULL;
     60 
     61   // NOTE: If you modify any of the logic below, make sure to update the
     62   // refcounted version in refcounted_context_keyed_service_factory.cc!
     63   BrowserContextKeyedServices::const_iterator it = mapping_.find(context);
     64   if (it != mapping_.end())
     65     return it->second;
     66 
     67   // Object not found.
     68   if (!create)
     69     return NULL;  // And we're forbidden from creating one.
     70 
     71   // Create new object.
     72   // Check to see if we have a per-BrowserContext testing factory that we should
     73   // use instead of default behavior.
     74   BrowserContextKeyedService* service = NULL;
     75   BrowserContextOverriddenFunctions::const_iterator jt =
     76       factories_.find(context);
     77   if (jt != factories_.end()) {
     78     if (jt->second) {
     79       if (!context->IsOffTheRecord())
     80         RegisterUserPrefsOnBrowserContext(context);
     81       service = jt->second(context);
     82     }
     83   } else {
     84     service = BuildServiceInstanceFor(context);
     85   }
     86 
     87   Associate(context, service);
     88   return service;
     89 }
     90 
     91 void BrowserContextKeyedServiceFactory::Associate(
     92     content::BrowserContext* context,
     93     BrowserContextKeyedService* service) {
     94   DCHECK(!ContainsKey(mapping_, context));
     95   mapping_.insert(std::make_pair(context, service));
     96 }
     97 
     98 void BrowserContextKeyedServiceFactory::BrowserContextShutdown(
     99     content::BrowserContext* context) {
    100   BrowserContextKeyedServices::iterator it = mapping_.find(context);
    101   if (it != mapping_.end() && it->second)
    102     it->second->Shutdown();
    103 }
    104 
    105 void BrowserContextKeyedServiceFactory::BrowserContextDestroyed(
    106     content::BrowserContext* context) {
    107   BrowserContextKeyedServices::iterator it = mapping_.find(context);
    108   if (it != mapping_.end()) {
    109     delete it->second;
    110     mapping_.erase(it);
    111   }
    112 
    113   // For unit tests, we also remove the factory function both so we don't
    114   // maintain a big map of dead pointers, but also since we may have a second
    115   // object that lives at the same address (see other comments about unit tests
    116   // in this file).
    117   factories_.erase(context);
    118 
    119   BrowserContextKeyedBaseFactory::BrowserContextDestroyed(context);
    120 }
    121 
    122 void BrowserContextKeyedServiceFactory::SetEmptyTestingFactory(
    123     content::BrowserContext* context) {
    124   SetTestingFactory(context, NULL);
    125 }
    126 
    127 void BrowserContextKeyedServiceFactory::CreateServiceNow(
    128     content::BrowserContext* context) {
    129   GetServiceForBrowserContext(context, true);
    130 }
    131