1 // Copyright 2020 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 "chrome/browser/query_tiles/tile_service_factory.h"
6 
7 #include "base/command_line.h"
8 #include "base/memory/singleton.h"
9 #include "chrome/browser/browser_process.h"
10 #include "chrome/browser/image_fetcher/image_fetcher_service_factory.h"
11 #include "chrome/browser/net/system_network_context_manager.h"
12 #include "chrome/browser/profiles/profile.h"
13 #include "chrome/browser/profiles/profile_key.h"
14 #include "chrome/common/channel_info.h"
15 #include "chrome/common/chrome_constants.h"
16 #include "components/background_task_scheduler/background_task_scheduler.h"
17 #include "components/background_task_scheduler/background_task_scheduler_factory.h"
18 #include "components/image_fetcher/core/image_fetcher_service.h"
19 #include "components/keyed_service/core/simple_dependency_manager.h"
20 #include "components/language/core/browser/locale_util.h"
21 #include "components/language/core/browser/pref_names.h"
22 #include "components/prefs/pref_service.h"
23 #include "components/query_tiles/switches.h"
24 #include "components/query_tiles/tile_service_factory_helper.h"
25 #include "components/variations/service/variations_service.h"
26 #include "components/version_info/version_info.h"
27 #include "google_apis/google_api_keys.h"
28 #include "services/network/public/cpp/shared_url_loader_factory.h"
29 
30 namespace query_tiles {
31 namespace {
32 
33 // Issue 1076964: Currently the variation service can be only reached in full
34 // browser mode. Ensure the fetcher task launches OnFullBrowserLoaded.
35 // TODO(hesen): Work around store/get country code in reduce mode.
GetCountryCode()36 std::string GetCountryCode() {
37   std::string country_code;
38   base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
39   if (command_line->HasSwitch(query_tiles::switches::kQueryTilesCountryCode)) {
40     country_code = command_line->GetSwitchValueASCII(
41         query_tiles::switches::kQueryTilesCountryCode);
42     if (!country_code.empty())
43       return country_code;
44   }
45 
46   if (!g_browser_process)
47     return country_code;
48 
49   auto* variations_service = g_browser_process->variations_service();
50   if (variations_service) {
51     country_code = variations_service->GetStoredPermanentCountry();
52     if (!country_code.empty())
53       return country_code;
54     country_code = variations_service->GetLatestCountry();
55   }
56   return country_code;
57 }
58 
GetGoogleAPIKey()59 std::string GetGoogleAPIKey() {
60   bool is_stable_channel =
61       chrome::GetChannel() == version_info::Channel::STABLE;
62   return is_stable_channel ? google_apis::GetAPIKey()
63                            : google_apis::GetNonStableAPIKey();
64 }
65 
66 }  // namespace
67 
68 // static
GetInstance()69 TileServiceFactory* TileServiceFactory::GetInstance() {
70   return base::Singleton<TileServiceFactory>::get();
71 }
72 
73 // static
GetForKey(SimpleFactoryKey * key)74 TileService* TileServiceFactory::GetForKey(SimpleFactoryKey* key) {
75   return static_cast<TileService*>(
76       GetInstance()->GetServiceForKey(key, /*create=*/true));
77 }
78 
TileServiceFactory()79 TileServiceFactory::TileServiceFactory()
80     : SimpleKeyedServiceFactory("TileService",
81                                 SimpleDependencyManager::GetInstance()) {
82   DependsOn(ImageFetcherServiceFactory::GetInstance());
83   DependsOn(background_task::BackgroundTaskSchedulerFactory::GetInstance());
84 }
85 
~TileServiceFactory()86 TileServiceFactory::~TileServiceFactory() {}
87 
BuildServiceInstanceFor(SimpleFactoryKey * key) const88 std::unique_ptr<KeyedService> TileServiceFactory::BuildServiceInstanceFor(
89     SimpleFactoryKey* key) const {
90   auto* image_fetcher_service = ImageFetcherServiceFactory::GetForKey(key);
91   auto* db_provider =
92       ProfileKey::FromSimpleFactoryKey(key)->GetProtoDatabaseProvider();
93   // |storage_dir| is not actually used since we are using the shared leveldb.
94   base::FilePath storage_dir =
95       ProfileKey::FromSimpleFactoryKey(key)->GetPath().Append(
96           chrome::kQueryTileStorageDirname);
97 
98   auto* background_task_scheduler =
99       background_task::BackgroundTaskSchedulerFactory::GetForKey(key);
100 
101   std::string accept_languanges =
102       ProfileKey::FromSimpleFactoryKey(key)->GetPrefs()->GetString(
103           language::prefs::kAcceptLanguages);
104 
105   auto url_loader_factory =
106       SystemNetworkContextManager::GetInstance()->GetSharedURLLoaderFactory();
107 
108   base::Version version = version_info::GetVersion();
109   std::string channel_name = chrome::GetChannelName();
110   std::string client_version =
111       base::StringPrintf("%d.%d.%d.%s.chrome",
112                          version.components()[0],  // Major
113                          version.components()[2],  // Build
114                          version.components()[3],  // Patch
115                          channel_name.c_str());
116 
117   return CreateTileService(image_fetcher_service, db_provider, storage_dir,
118                            background_task_scheduler, accept_languanges,
119                            GetCountryCode(), GetGoogleAPIKey(), client_version,
120                            url_loader_factory,
121                            ProfileKey::FromSimpleFactoryKey(key)->GetPrefs());
122 }
123 
124 }  // namespace query_tiles
125