1 // Copyright 2017 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/search/one_google_bar/one_google_bar_service.h"
6 
7 #include <utility>
8 
9 #include "base/bind.h"
10 #include "base/callback.h"
11 #include "chrome/browser/search/one_google_bar/one_google_bar_loader.h"
12 #include "components/signin/public/identity_manager/identity_manager.h"
13 
14 class OneGoogleBarService::SigninObserver
15     : public signin::IdentityManager::Observer {
16  public:
17   using SigninStatusChangedCallback = base::RepeatingClosure;
18 
SigninObserver(signin::IdentityManager * identity_manager,const SigninStatusChangedCallback & callback)19   SigninObserver(signin::IdentityManager* identity_manager,
20                  const SigninStatusChangedCallback& callback)
21       : identity_manager_(identity_manager), callback_(callback) {
22     identity_manager_->AddObserver(this);
23   }
24 
~SigninObserver()25   ~SigninObserver() override { identity_manager_->RemoveObserver(this); }
26 
27  private:
28   // IdentityManager::Observer implementation.
OnAccountsInCookieUpdated(const signin::AccountsInCookieJarInfo & accounts_in_cookie_jar_info,const GoogleServiceAuthError & error)29   void OnAccountsInCookieUpdated(
30       const signin::AccountsInCookieJarInfo& accounts_in_cookie_jar_info,
31       const GoogleServiceAuthError& error) override {
32     callback_.Run();
33   }
34 
35   signin::IdentityManager* const identity_manager_;
36   SigninStatusChangedCallback callback_;
37 };
38 
OneGoogleBarService(signin::IdentityManager * identity_manager,std::unique_ptr<OneGoogleBarLoader> loader)39 OneGoogleBarService::OneGoogleBarService(
40     signin::IdentityManager* identity_manager,
41     std::unique_ptr<OneGoogleBarLoader> loader)
42     : loader_(std::move(loader)),
43       signin_observer_(std::make_unique<SigninObserver>(
44           identity_manager,
45           base::BindRepeating(&OneGoogleBarService::SigninStatusChanged,
46                               base::Unretained(this)))) {}
47 
48 OneGoogleBarService::~OneGoogleBarService() = default;
49 
Shutdown()50 void OneGoogleBarService::Shutdown() {
51   for (auto& observer : observers_) {
52     observer.OnOneGoogleBarServiceShuttingDown();
53   }
54 
55   signin_observer_.reset();
56   DCHECK(!observers_.might_have_observers());
57 }
58 
Refresh()59 void OneGoogleBarService::Refresh() {
60   loader_->Load(base::BindOnce(&OneGoogleBarService::OneGoogleBarDataLoaded,
61                                base::Unretained(this)));
62 }
63 
AddObserver(OneGoogleBarServiceObserver * observer)64 void OneGoogleBarService::AddObserver(OneGoogleBarServiceObserver* observer) {
65   observers_.AddObserver(observer);
66 }
67 
RemoveObserver(OneGoogleBarServiceObserver * observer)68 void OneGoogleBarService::RemoveObserver(
69     OneGoogleBarServiceObserver* observer) {
70   observers_.RemoveObserver(observer);
71 }
72 
SetLanguageCodeForTesting(const std::string & language_code)73 void OneGoogleBarService::SetLanguageCodeForTesting(
74     const std::string& language_code) {
75   language_code_ = language_code;
76 }
77 
SetAdditionalQueryParams(const std::string & value)78 bool OneGoogleBarService::SetAdditionalQueryParams(const std::string& value) {
79   return loader_->SetAdditionalQueryParams(value);
80 }
81 
SigninStatusChanged()82 void OneGoogleBarService::SigninStatusChanged() {
83   // If we have cached data, clear it and notify observers.
84   if (one_google_bar_data_.has_value()) {
85     one_google_bar_data_ = base::nullopt;
86     NotifyObservers();
87   }
88 }
89 
OneGoogleBarDataLoaded(OneGoogleBarLoader::Status status,const base::Optional<OneGoogleBarData> & data)90 void OneGoogleBarService::OneGoogleBarDataLoaded(
91     OneGoogleBarLoader::Status status,
92     const base::Optional<OneGoogleBarData>& data) {
93   // In case of transient errors, keep our cached data (if any), but still
94   // notify observers of the finished load (attempt).
95   if (status != OneGoogleBarLoader::Status::TRANSIENT_ERROR) {
96     one_google_bar_data_ = data;
97     language_code_ = data.has_value() ? data->language_code : std::string();
98   }
99   NotifyObservers();
100 }
101 
NotifyObservers()102 void OneGoogleBarService::NotifyObservers() {
103   for (auto& observer : observers_) {
104     observer.OnOneGoogleBarDataUpdated();
105   }
106 }
107