- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / browser / chromeos / settings / device_oauth2_token_service_factory.cc
1 // Copyright (c) 2012 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/chromeos/settings/device_oauth2_token_service_factory.h"
6
7 #include "base/bind.h"
8 #include "base/callback.h"
9 #include "base/message_loop/message_loop.h"
10 #include "base/tracked_objects.h"
11 #include "chrome/browser/browser_process.h"
12 #include "chrome/browser/chromeos/settings/device_oauth2_token_service.h"
13 #include "chrome/browser/chromeos/settings/token_encryptor.h"
14 #include "chromeos/cryptohome/system_salt_getter.h"
15 #include "content/public/browser/browser_thread.h"
16
17 namespace chromeos {
18 namespace {
19
20 DeviceOAuth2TokenServiceFactory* g_factory = NULL;
21
22 }  // namespace
23
24 DeviceOAuth2TokenServiceFactory::DeviceOAuth2TokenServiceFactory()
25     : initialized_(false),
26       token_service_(NULL),
27       weak_ptr_factory_(this) {
28 }
29
30 DeviceOAuth2TokenServiceFactory::~DeviceOAuth2TokenServiceFactory() {
31   delete token_service_;
32 }
33
34 // static
35 void DeviceOAuth2TokenServiceFactory::Get(const GetCallback& callback) {
36   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
37
38   if (!g_factory) {
39     base::MessageLoop::current()->PostTask(
40         FROM_HERE,
41         base::Bind(callback,
42                    static_cast<DeviceOAuth2TokenService*>(NULL)));
43     return;
44   }
45
46   g_factory->RunAsync(callback);
47 }
48
49 // static
50 void DeviceOAuth2TokenServiceFactory::Initialize() {
51   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
52
53   DCHECK(!g_factory);
54   g_factory = new DeviceOAuth2TokenServiceFactory;
55   g_factory->CreateTokenService();
56 }
57
58 // static
59 void DeviceOAuth2TokenServiceFactory::Shutdown() {
60   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
61
62   if (g_factory) {
63     delete g_factory;
64     g_factory = NULL;
65   }
66 }
67
68 void DeviceOAuth2TokenServiceFactory::CreateTokenService() {
69   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
70
71   SystemSaltGetter::Get()->GetSystemSalt(
72       base::Bind(&DeviceOAuth2TokenServiceFactory::DidGetSystemSalt,
73                  weak_ptr_factory_.GetWeakPtr()));
74 }
75
76 void DeviceOAuth2TokenServiceFactory::DidGetSystemSalt(
77     const std::string& system_salt) {
78   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
79   DCHECK(!token_service_);
80
81   if (system_salt.empty()) {
82     LOG(ERROR) << "Failed to get the system salt";
83   } else {
84     token_service_= new DeviceOAuth2TokenService(
85         g_browser_process->system_request_context(),
86         g_browser_process->local_state(),
87         new CryptohomeTokenEncryptor(system_salt));
88   }
89   // Mark that the factory is initialized.
90   initialized_ = true;
91
92   // Run callbacks regardless of whether token_service_ is created or not,
93   // but don't run callbacks immediately. Each callback would cause an
94   // interesting action, hence running them consecutively could be
95   // potentially expensive and dangerous.
96   while (!pending_callbacks_.empty()) {
97     base::MessageLoop::current()->PostTask(
98         FROM_HERE,
99         base::Bind(pending_callbacks_.front(), token_service_));
100     pending_callbacks_.pop();
101   }
102 }
103
104 void DeviceOAuth2TokenServiceFactory::RunAsync(const GetCallback& callback) {
105   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
106
107   if (initialized_) {
108     base::MessageLoop::current()->PostTask(
109         FROM_HERE,
110         base::Bind(callback, token_service_));
111     return;
112   }
113
114   pending_callbacks_.push(callback);
115 }
116
117 }  // namespace chromeos