File: keyed_service_factory.cc

package info (click to toggle)
chromium-browser 57.0.2987.98-1~deb8u1
  • links: PTS, VCS
  • area: main
  • in suites: jessie
  • size: 2,637,852 kB
  • ctags: 2,544,394
  • sloc: cpp: 12,815,961; ansic: 3,676,222; python: 1,147,112; asm: 526,608; java: 523,212; xml: 286,794; perl: 92,654; sh: 86,408; objc: 73,271; makefile: 27,698; cs: 18,487; yacc: 13,031; tcl: 12,957; pascal: 4,875; ml: 4,716; lex: 3,904; sql: 3,862; ruby: 1,982; lisp: 1,508; php: 1,368; exp: 404; awk: 325; csh: 117; jsp: 39; sed: 37
file content (141 lines) | stat: -rw-r--r-- 4,782 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
// Copyright 2014 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/keyed_service/core/keyed_service_factory.h"

#include <utility>

#include "base/logging.h"
#include "base/stl_util.h"
#include "base/trace_event/trace_event.h"
#include "components/keyed_service/core/dependency_manager.h"
#include "components/keyed_service/core/keyed_service.h"

KeyedServiceFactory::KeyedServiceFactory(const char* name,
                                         DependencyManager* manager)
    : KeyedServiceBaseFactory(name, manager) {
}

KeyedServiceFactory::~KeyedServiceFactory() {
  DCHECK(mapping_.empty());
}

void KeyedServiceFactory::SetTestingFactory(
    base::SupportsUserData* context,
    TestingFactoryFunction testing_factory) {
  // Destroying the context may cause us to lose data about whether |context|
  // has our preferences registered on it (since the context object itself
  // isn't dead). See if we need to readd it once we've gone through normal
  // destruction.
  bool add_context = ArePreferencesSetOn(context);

#ifndef NDEBUG
  // Ensure that |context| is not marked as stale (e.g., due to it aliasing an
  // instance that was destroyed in an earlier test) in order to avoid accesses
  // to |context| in |BrowserContextShutdown| from causing
  // |AssertBrowserContextWasntDestroyed| to raise an error.
  MarkContextLiveForTesting(context);
#endif

  // We have to go through the shutdown and destroy mechanisms because there
  // are unit tests that create a service on a context and then change the
  // testing service mid-test.
  ContextShutdown(context);
  ContextDestroyed(context);

  if (add_context)
    MarkPreferencesSetOn(context);

  testing_factories_[context] = testing_factory;
}

KeyedService* KeyedServiceFactory::SetTestingFactoryAndUse(
    base::SupportsUserData* context,
    TestingFactoryFunction testing_factory) {
  DCHECK(testing_factory);
  SetTestingFactory(context, testing_factory);
  return GetServiceForContext(context, true);
}

KeyedService* KeyedServiceFactory::GetServiceForContext(
    base::SupportsUserData* context,
    bool create) {
  TRACE_EVENT0("browser,startup", "KeyedServiceFactory::GetServiceForContext");
  context = GetContextToUse(context);
  if (!context)
    return nullptr;

  // NOTE: If you modify any of the logic below, make sure to update the
  // refcounted version in refcounted_context_keyed_service_factory.cc!
  const auto& it = mapping_.find(context);
  if (it != mapping_.end())
    return it->second;

  // Object not found.
  if (!create)
    return nullptr;  // And we're forbidden from creating one.

  // Create new object.
  // Check to see if we have a per-context testing factory that we should use
  // instead of default behavior.
  std::unique_ptr<KeyedService> service;
  const auto& jt = testing_factories_.find(context);
  if (jt != testing_factories_.end()) {
    if (jt->second) {
      if (!IsOffTheRecord(context))
        RegisterUserPrefsOnContextForTest(context);
      service = jt->second(context);
    }
  } else {
    service = BuildServiceInstanceFor(context);
  }

  Associate(context, std::move(service));
  return mapping_[context];
}

void KeyedServiceFactory::Associate(base::SupportsUserData* context,
                                    std::unique_ptr<KeyedService> service) {
  DCHECK(!base::ContainsKey(mapping_, context));
  mapping_.insert(std::make_pair(context, service.release()));
}

void KeyedServiceFactory::Disassociate(base::SupportsUserData* context) {
  const auto& it = mapping_.find(context);
  if (it != mapping_.end()) {
    delete it->second;
    mapping_.erase(it);
  }
}

void KeyedServiceFactory::ContextShutdown(base::SupportsUserData* context) {
  const auto& it = mapping_.find(context);
  if (it != mapping_.end() && it->second)
    it->second->Shutdown();
}

void KeyedServiceFactory::ContextDestroyed(base::SupportsUserData* context) {
  Disassociate(context);

  // For unit tests, we also remove the factory function both so we don't
  // maintain a big map of dead pointers, but also since we may have a second
  // object that lives at the same address (see other comments about unit tests
  // in this file).
  testing_factories_.erase(context);

  KeyedServiceBaseFactory::ContextDestroyed(context);
}

void KeyedServiceFactory::SetEmptyTestingFactory(
    base::SupportsUserData* context) {
  SetTestingFactory(context, nullptr);
}

bool KeyedServiceFactory::HasTestingFactory(base::SupportsUserData* context) {
  return testing_factories_.find(context) != testing_factories_.end();
}

void KeyedServiceFactory::CreateServiceNow(base::SupportsUserData* context) {
  GetServiceForContext(context, true);
}