summaryrefslogtreecommitdiffstats
path: root/chrome/browser/extensions/api/profile_keyed_api_factory.h
blob: d6267de2a6230550dcedc23ed12962ecfd28e903 (plain)
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
// Copyright (c) 2012 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.

#ifndef CHROME_BROWSER_EXTENSIONS_API_PROFILE_KEYED_API_FACTORY_H_
#define CHROME_BROWSER_EXTENSIONS_API_PROFILE_KEYED_API_FACTORY_H_

#include "chrome/browser/extensions/extension_system_factory.h"
#include "chrome/browser/profiles/incognito_helpers.h"
#include "chrome/browser/profiles/profile.h"
#include "components/browser_context_keyed_service/browser_context_dependency_manager.h"
#include "components/browser_context_keyed_service/browser_context_keyed_service.h"
#include "components/browser_context_keyed_service/browser_context_keyed_service_factory.h"

namespace extensions {

template <typename T>
class ProfileKeyedAPIFactory;

// Instantiations of ProfileKeyedAPIFactory should use this base class
// and also define a static const char* service_name() function (used in the
// ProfileKeyedBaseFactory constructor). These fields should be accessible
// to the ProfileKeyedAPIFactory for the service.
class ProfileKeyedAPI : public ProfileKeyedService {
 protected:
  // Defaults for flags that control ProfileKeyedAPIFactory behavior.
  // See ProfileKeyedBaseFactory for usage.
  static const bool kServiceRedirectedInIncognito = false;
  static const bool kServiceIsNULLWhileTesting = false;
  static const bool kServiceHasOwnInstanceInIncognito = false;

  // Users of this factory template must define a GetFactoryInstance()
  // and manage their own instances (typically using LazyInstance or
  // Singleton), because those cannot be included in more than one
  // translation unit (and thus cannot be initialized in a header file).
  //
  // In the header file, declare GetFactoryInstance(), e.g.:
  //   class ProcessesAPI {
  //   ...
  //    public:
  //     static ProfileKeyedAPIFactory<ProcessesAPI>* GetFactoryInstance();
  //   };
  //
  // In the cc file, provide the implementation, e.g.:
  //   static base::LazyInstance<ProfileKeyedAPIFactory<ProcessesAPI> >
  //   g_factory = LAZY_INSTANCE_INITIALIZER;
  //
  //   // static
  //   ProfileKeyedAPIFactory<ProcessesAPI>*
  //   ProcessesAPI::GetFactoryInstance() {
  //     return &g_factory.Get();
  //   }
};

// A template for factories for ProfileKeyedServices that manage extension APIs.
// T is a ProfileKeyedService that uses this factory template instead of
// its own separate factory definition to manage its per-profile instances.
template <typename T>
class ProfileKeyedAPIFactory : public ProfileKeyedServiceFactory {
 public:
  static T* GetForProfile(Profile* profile) {
    return static_cast<T*>(
        T::GetFactoryInstance()->GetServiceForProfile(profile, true));
  }

  // Declare dependencies on other factories.
  // By default, ExtensionSystemFactory is the only dependency; however,
  // specializations can override this. Declare your specialization in
  // your header file after the ProfileKeyedAPI class definition.
  // Then in the cc file (or inline in the header), define it, e.g.:
  //   template <>
  //   ProfileKeyedAPIFactory<PushMessagingAPI>::DeclareFactoryDependencies() {
  //     DependsOn(ExtensionSystemFactory::GetInstance());
  //     DependsOn(ProfileSyncServiceFactory::GetInstance());
  // }
  void DeclareFactoryDependencies() {
    DependsOn(ExtensionSystemFactory::GetInstance());
  }

  ProfileKeyedAPIFactory()
  : ProfileKeyedServiceFactory(T::service_name(),
                               ProfileDependencyManager::GetInstance()) {
    DeclareFactoryDependencies();
  }

  virtual ~ProfileKeyedAPIFactory() {
  }

 private:
  // ProfileKeyedServiceFactory implementation.
  virtual ProfileKeyedService* BuildServiceInstanceFor(
      content::BrowserContext* profile) const OVERRIDE {
    return new T(static_cast<Profile*>(profile));
  }

  // ProfileKeyedBaseFactory implementation.
  // These can be effectively overridden with template specializations.
  virtual content::BrowserContext* GetBrowserContextToUse(
      content::BrowserContext* context) const OVERRIDE {
    if (T::kServiceRedirectedInIncognito)
      return chrome::GetBrowserContextRedirectedInIncognito(context);

    if (T::kServiceHasOwnInstanceInIncognito)
      return chrome::GetBrowserContextOwnInstanceInIncognito(context);

    return ProfileKeyedServiceFactory::GetBrowserContextToUse(context);
  }

  virtual bool ServiceIsCreatedWithProfile() const OVERRIDE {
    return true;
  }

  virtual bool ServiceIsNULLWhileTesting() const OVERRIDE {
    return T::kServiceIsNULLWhileTesting;
  }

  DISALLOW_COPY_AND_ASSIGN(ProfileKeyedAPIFactory);
};

}  // namespace extensions

#endif  // CHROME_BROWSER_EXTENSIONS_API_PROFILE_KEYED_API_FACTORY_H_