Add more checks to investigate SupervisedUserPrefStore crash at startup.
[chromium-blink-merge.git] / chrome / browser / android / logo_service.cc
blobddcb626361050d372542a332ab237ab94479e4ed
1 // Copyright 2014 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/android/logo_service.h"
7 #include "base/memory/weak_ptr.h"
8 #include "chrome/browser/image_decoder.h"
9 #include "chrome/browser/profiles/profile.h"
10 #include "chrome/browser/search_engines/template_url_service_factory.h"
11 #include "chrome/browser/search_engines/ui_thread_search_terms_data.h"
12 #include "components/keyed_service/content/browser_context_dependency_manager.h"
13 #include "components/search_engines/template_url_service.h"
14 #include "components/search_provider_logos/google_logo_api.h"
15 #include "content/public/browser/browser_thread.h"
16 #include "net/url_request/url_request_context_getter.h"
18 using content::BrowserThread;
19 using search_provider_logos::Logo;
20 using search_provider_logos::LogoDelegate;
21 using search_provider_logos::LogoTracker;
23 namespace {
25 const char kCachedLogoDirectory[] = "Search Logo";
26 const int kDecodeLogoTimeoutSeconds = 30;
28 // Returns the URL where the doodle can be downloaded, e.g.
29 // https://www.google.com/async/newtab_mobile. This depends on the user's
30 // Google domain.
31 GURL GetGoogleDoodleURL(Profile* profile) {
32 GURL google_base_url(UIThreadSearchTermsData(profile).GoogleBaseURLValue());
33 const char kGoogleDoodleURLPath[] = "async/newtab_mobile";
34 GURL::Replacements replacements;
35 replacements.SetPathStr(kGoogleDoodleURLPath);
36 return google_base_url.ReplaceComponents(replacements);
39 class LogoDecoderDelegate : public ImageDecoder::Delegate {
40 public:
41 LogoDecoderDelegate(
42 const scoped_refptr<ImageDecoder>& image_decoder,
43 const base::Callback<void(const SkBitmap&)>& image_decoded_callback)
44 : image_decoder_(image_decoder),
45 image_decoded_callback_(image_decoded_callback),
46 weak_ptr_factory_(this) {
47 // If the ImageDecoder crashes or otherwise never completes, call
48 // OnImageDecodeTimedOut() eventually to ensure that image_decoded_callback_
49 // is run.
50 base::MessageLoopProxy::current()->PostDelayedTask(
51 FROM_HERE,
52 base::Bind(&LogoDecoderDelegate::OnDecodeImageFailed,
53 weak_ptr_factory_.GetWeakPtr(),
54 (const ImageDecoder*) NULL),
55 base::TimeDelta::FromSeconds(kDecodeLogoTimeoutSeconds));
58 ~LogoDecoderDelegate() override { image_decoder_->set_delegate(NULL); }
60 // ImageDecoder::Delegate:
61 void OnImageDecoded(const ImageDecoder* decoder,
62 const SkBitmap& decoded_image) override {
63 image_decoded_callback_.Run(decoded_image);
64 delete this;
67 void OnDecodeImageFailed(const ImageDecoder* decoder) override {
68 image_decoded_callback_.Run(SkBitmap());
69 delete this;
72 private:
73 scoped_refptr<ImageDecoder> image_decoder_;
74 base::Callback<void(const SkBitmap&)> image_decoded_callback_;
75 base::WeakPtrFactory<LogoDecoderDelegate> weak_ptr_factory_;
77 DISALLOW_COPY_AND_ASSIGN(LogoDecoderDelegate);
80 class ChromeLogoDelegate : public search_provider_logos::LogoDelegate {
81 public:
82 ChromeLogoDelegate() {}
83 ~ChromeLogoDelegate() override {}
85 // search_provider_logos::LogoDelegate:
86 void DecodeUntrustedImage(
87 const scoped_refptr<base::RefCountedString>& encoded_image,
88 base::Callback<void(const SkBitmap&)> image_decoded_callback) override {
89 scoped_refptr<ImageDecoder> image_decoder = new ImageDecoder(
90 NULL,
91 encoded_image->data(),
92 ImageDecoder::DEFAULT_CODEC);
93 LogoDecoderDelegate* delegate =
94 new LogoDecoderDelegate(image_decoder, image_decoded_callback);
95 image_decoder->set_delegate(delegate);
96 image_decoder->Start(base::MessageLoopProxy::current());
99 private:
100 DISALLOW_COPY_AND_ASSIGN(ChromeLogoDelegate);
103 } // namespace
105 // LogoService ----------------------------------------------------------------
107 LogoService::LogoService(Profile* profile) : profile_(profile) {
110 LogoService::~LogoService() {
113 void LogoService::GetLogo(search_provider_logos::LogoObserver* observer) {
114 TemplateURLService* template_url_service =
115 TemplateURLServiceFactory::GetForProfile(profile_);
116 if (!template_url_service)
117 return;
119 TemplateURL* template_url = template_url_service->GetDefaultSearchProvider();
120 if (!template_url || !template_url->url_ref().HasGoogleBaseURLs(
121 template_url_service->search_terms_data()))
122 return;
124 if (!logo_tracker_) {
125 logo_tracker_.reset(new LogoTracker(
126 profile_->GetPath().Append(kCachedLogoDirectory),
127 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE),
128 BrowserThread::GetBlockingPool(),
129 profile_->GetRequestContext(),
130 scoped_ptr<search_provider_logos::LogoDelegate>(
131 new ChromeLogoDelegate())));
134 logo_tracker_->SetServerAPI(
135 GetGoogleDoodleURL(profile_),
136 base::Bind(&search_provider_logos::GoogleParseLogoResponse),
137 base::Bind(&search_provider_logos::GoogleAppendFingerprintToLogoURL));
138 logo_tracker_->GetLogo(observer);
141 // LogoServiceFactory ---------------------------------------------------------
143 // static
144 LogoService* LogoServiceFactory::GetForProfile(Profile* profile) {
145 return static_cast<LogoService*>(
146 GetInstance()->GetServiceForBrowserContext(profile, true));
149 // static
150 LogoServiceFactory* LogoServiceFactory::GetInstance() {
151 return Singleton<LogoServiceFactory>::get();
154 LogoServiceFactory::LogoServiceFactory()
155 : BrowserContextKeyedServiceFactory(
156 "LogoService",
157 BrowserContextDependencyManager::GetInstance()) {
160 LogoServiceFactory::~LogoServiceFactory() {}
162 KeyedService* LogoServiceFactory::BuildServiceInstanceFor(
163 content::BrowserContext* context) const {
164 Profile* profile = static_cast<Profile*>(context);
165 DCHECK(!profile->IsOffTheRecord());
166 return new LogoService(profile);