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.
5 #include "chrome/browser/profiles/refcounted_profile_keyed_service_factory.h"
7 #include "base/logging.h"
8 #include "base/stl_util.h"
9 #include "chrome/browser/profiles/profile.h"
10 #include "chrome/browser/profiles/profile_keyed_service.h"
11 #include "chrome/browser/profiles/refcounted_profile_keyed_service.h"
13 void RefcountedProfileKeyedServiceFactory::SetTestingFactory(
15 FactoryFunction factory
) {
16 // Destroying the profile may cause us to lose data about whether |profile|
17 // has our preferences registered on it (since the profile object itself
18 // isn't dead). See if we need to readd it once we've gone through normal
20 bool add_profile
= ArePreferencesSetOn(profile
);
22 // We have to go through the shutdown and destroy mechanisms because there
23 // are unit tests that create a service on a profile and then change the
24 // testing service mid-test.
25 ProfileShutdown(profile
);
26 ProfileDestroyed(profile
);
29 MarkPreferencesSetOn(profile
);
31 factories_
[profile
] = factory
;
34 scoped_refptr
<RefcountedProfileKeyedService
>
35 RefcountedProfileKeyedServiceFactory::SetTestingFactoryAndUse(
37 FactoryFunction factory
) {
39 SetTestingFactory(profile
, factory
);
40 return GetServiceForProfile(profile
, true);
43 RefcountedProfileKeyedServiceFactory::RefcountedProfileKeyedServiceFactory(
45 ProfileDependencyManager
* manager
)
46 : ProfileKeyedBaseFactory(name
, manager
) {
49 RefcountedProfileKeyedServiceFactory::~RefcountedProfileKeyedServiceFactory() {
50 DCHECK(mapping_
.empty());
53 scoped_refptr
<RefcountedProfileKeyedService
>
54 RefcountedProfileKeyedServiceFactory::GetServiceForProfile(
57 profile
= GetProfileToUse(profile
);
61 // NOTE: If you modify any of the logic below, make sure to update the
62 // non-refcounted version in profile_keyed_service_factory.cc!
63 RefCountedStorage::const_iterator it
= mapping_
.find(profile
);
64 if (it
!= mapping_
.end())
69 return NULL
; // And we're forbidden from creating one.
72 // Check to see if we have a per-Profile testing factory that we should use
73 // instead of default behavior.
74 scoped_refptr
<RefcountedProfileKeyedService
> service
;
75 ProfileOverriddenFunctions::const_iterator jt
= factories_
.find(profile
);
76 if (jt
!= factories_
.end()) {
78 if (!profile
->IsOffTheRecord())
79 RegisterUserPrefsOnProfile(profile
);
80 service
= jt
->second(profile
);
83 service
= BuildServiceInstanceFor(profile
);
86 Associate(profile
, service
);
90 void RefcountedProfileKeyedServiceFactory::Associate(
92 const scoped_refptr
<RefcountedProfileKeyedService
>& service
) {
93 DCHECK(!ContainsKey(mapping_
, profile
));
94 mapping_
.insert(std::make_pair(profile
, service
));
97 void RefcountedProfileKeyedServiceFactory::ProfileShutdown(Profile
* profile
) {
98 RefCountedStorage::iterator it
= mapping_
.find(profile
);
99 if (it
!= mapping_
.end() && it
->second
)
100 it
->second
->ShutdownOnUIThread();
103 void RefcountedProfileKeyedServiceFactory::ProfileDestroyed(Profile
* profile
) {
104 // We "merely" drop our reference to the service. Hopefully this will cause
105 // the service to be destroyed. If not, oh well.
106 mapping_
.erase(profile
);
108 // For unit tests, we also remove the factory function both so we don't
109 // maintain a big map of dead pointers, but also since we may have a second
110 // object that lives at the same address (see other comments about unit tests
112 factories_
.erase(profile
);
114 ProfileKeyedBaseFactory::ProfileDestroyed(profile
);
117 void RefcountedProfileKeyedServiceFactory::SetEmptyTestingFactory(
119 SetTestingFactory(profile
, NULL
);
122 void RefcountedProfileKeyedServiceFactory::CreateServiceNow(Profile
* profile
) {
123 GetServiceForProfile(profile
, true);