1a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// found in the LICENSE file.
490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
5a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#ifndef COMPONENTS_KEYED_SERVICE_CONTENT_BROWSER_CONTEXT_DEPENDENCY_MANAGER_H_
6a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#define COMPONENTS_KEYED_SERVICE_CONTENT_BROWSER_CONTEXT_DEPENDENCY_MANAGER_H_
790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
80529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "base/callback_forward.h"
90529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "base/callback_list.h"
1090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/memory/singleton.h"
11a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "components/keyed_service/core/dependency_graph.h"
12a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "components/keyed_service/core/keyed_service_export.h"
1390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
1490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#ifndef NDEBUG
1590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include <set>
1690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#endif
1790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
1890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)class BrowserContextKeyedBaseFactory;
1990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
2090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)namespace content {
2190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)class BrowserContext;
2290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
2390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
24a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)namespace user_prefs {
25a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)class PrefRegistrySyncable;
26a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
27a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
2890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// A singleton that listens for context destruction notifications and
2990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// rebroadcasts them to each BrowserContextKeyedBaseFactory in a safe order
3090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// based on the stated dependencies by each service.
31a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)class KEYED_SERVICE_EXPORT BrowserContextDependencyManager {
3290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) public:
3390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Adds/Removes a component from our list of live components. Removing will
3490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // also remove live dependency links.
3590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  void AddComponent(BrowserContextKeyedBaseFactory* component);
3690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  void RemoveComponent(BrowserContextKeyedBaseFactory* component);
3790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
3890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Adds a dependency between two factories.
3990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  void AddEdge(BrowserContextKeyedBaseFactory* depended,
4090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)               BrowserContextKeyedBaseFactory* dependee);
4190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
42a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Registers profile-specific preferences for all services via |registry|.
43a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // |context| should be the BrowserContext containing |registry| and is used as
44a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // a key to prevent multiple registrations on the same BrowserContext in
45a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // tests.
46a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void RegisterProfilePrefsForServices(
47a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      const content::BrowserContext* context,
48a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      user_prefs::PrefRegistrySyncable* registry);
49a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
50a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Called by each BrowserContext to alert us of its creation. Several
51a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // services want to be started when a context is created. If you want your
52a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // KeyedService to be started with the BrowserContext, override
533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // BrowserContextKeyedBaseFactory::ServiceIsCreatedWithBrowserContext() to
543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // return true. This method also registers any service-related preferences
553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // for non-incognito profiles.
563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  void CreateBrowserContextServices(content::BrowserContext* context);
573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Similar to CreateBrowserContextServices(), except this is used for creating
593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // test BrowserContexts - these contexts will not create services for any
603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // BrowserContextKeyedBaseFactories that return true from
61a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // ServiceIsNULLWhileTesting().
62a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void CreateBrowserContextServicesForTest(content::BrowserContext* context);
6390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
6490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Called by each BrowserContext to alert us that we should destroy services
6590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // associated with it.
6690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  void DestroyBrowserContextServices(content::BrowserContext* context);
6790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
680529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Registers a |callback| that will be called just before executing
690529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // CreateBrowserContextServices() or CreateBrowserContextServicesForTest().
700529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // This can be useful in browser tests which wish to substitute test or mock
710529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // builders for the keyed services.
720529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scoped_ptr<base::CallbackList<void(content::BrowserContext*)>::Subscription>
730529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  RegisterWillCreateBrowserContextServicesCallbackForTesting(
740529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      const base::Callback<void(content::BrowserContext*)>& callback);
750529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
7690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#ifndef NDEBUG
7790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Debugging assertion called as part of GetServiceForBrowserContext in debug
7890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // mode. This will NOTREACHED() whenever the user is trying to access a stale
7990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // BrowserContext*.
8090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  void AssertBrowserContextWasntDestroyed(content::BrowserContext* context);
815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Marks |context| as live (i.e., not stale). This method can be called as a
835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // safeguard against |AssertBrowserContextWasntDestroyed()| checks going off
845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // due to |context| aliasing a BrowserContext instance from a prior test
855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // (i.e., 0xWhatever might be created, be destroyed, and then a new
865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // BrowserContext object might be created at 0xWhatever).
875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void MarkBrowserContextLiveForTesting(content::BrowserContext* context);
8890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#endif
8990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
9090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  static BrowserContextDependencyManager* GetInstance();
9190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
9290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) private:
9390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  friend class BrowserContextDependencyManagerUnittests;
9490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  friend struct DefaultSingletonTraits<BrowserContextDependencyManager>;
9590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Helper function used by CreateBrowserContextServices[ForTest].
973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  void DoCreateBrowserContextServices(content::BrowserContext* context,
98a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                      bool is_testing_context);
993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
10090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  BrowserContextDependencyManager();
10190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  virtual ~BrowserContextDependencyManager();
10290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
10390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#ifndef NDEBUG
10490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  void DumpBrowserContextDependencies(content::BrowserContext* context);
10590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#endif
10690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
10790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DependencyGraph dependency_graph_;
10890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
1090529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // A list of callbacks to call just before executing
1100529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // CreateBrowserContextServices() or CreateBrowserContextServicesForTest().
1110529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  base::CallbackList<void(content::BrowserContext*)>
1120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      will_create_browser_context_services_callbacks_;
1130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
11490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#ifndef NDEBUG
11590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // A list of context objects that have gone through the Shutdown()
11690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // phase. These pointers are most likely invalid, but we keep track of their
11790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // locations in memory so we can nicely assert if we're asked to do anything
11890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // with them.
11990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  std::set<content::BrowserContext*> dead_context_pointers_;
12090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#endif
12190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)};
12290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
123a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#endif  // COMPONENTS_KEYED_SERVICE_CONTENT_BROWSER_CONTEXT_DEPENDENCY_MANAGER_H_
124