Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(529)

Side by Side Diff: chrome/browser/chromeos/login/ownership_service.cc

Issue 10824112: Move Chrome OS device settings stuff to chrome/browser/chromeos/settings. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase. Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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/login/ownership_service.h"
6
7 #include "base/command_line.h"
8 #include "base/bind.h"
9 #include "base/bind_helpers.h"
10 #include "base/file_path.h"
11 #include "base/file_util.h"
12 #include "base/lazy_instance.h"
13 #include "base/synchronization/lock.h"
14 #include "base/task_runner_util.h"
15 #include "chrome/browser/browser_process.h"
16 #include "chrome/common/chrome_notification_types.h"
17 #include "chrome/common/chrome_switches.h"
18 #include "content/public/browser/browser_thread.h"
19 #include "content/public/browser/notification_service.h"
20
21 using content::BrowserThread;
22
23 namespace chromeos {
24
25 namespace {
26
27 typedef std::pair<OwnershipService::Status, bool> OwnershipStatusReturnType;
28
29 // Makes the check for ownership on the FILE thread and stores the result in the
30 // provided pointers.
31 OwnershipStatusReturnType CheckStatusOnFileThread() {
32 bool current_user_is_owner;
33 OwnershipService::Status status;
34 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
35 status = OwnershipService::GetSharedInstance()->IsAlreadyOwned() ?
36 OwnershipService::OWNERSHIP_TAKEN : OwnershipService::OWNERSHIP_NONE;
37 current_user_is_owner =
38 OwnershipService::GetSharedInstance()->IsCurrentUserOwner();
39 return OwnershipStatusReturnType(status, current_user_is_owner);
40 }
41
42 } // namespace
43
44 static base::LazyInstance<OwnershipService> g_ownership_service =
45 LAZY_INSTANCE_INITIALIZER;
46
47 // static
48 OwnershipService* OwnershipService::GetSharedInstance() {
49 return g_ownership_service.Pointer();
50 }
51
52 OwnershipService::OwnershipService()
53 : manager_(new OwnerManager),
54 utils_(OwnerKeyUtils::Create()),
55 ownership_status_(OWNERSHIP_UNKNOWN),
56 force_ownership_(CommandLine::ForCurrentProcess()->HasSwitch(
57 switches::kStubCrosSettings)) {
58 notification_registrar_.Add(
59 this,
60 chrome::NOTIFICATION_OWNER_KEY_FETCH_ATTEMPT_SUCCEEDED,
61 content::NotificationService::AllSources());
62 }
63
64 OwnershipService::~OwnershipService() {}
65
66 void OwnershipService::Prewarm() {
67 // Note that we cannot prewarm in constructor because in current codebase
68 // object is created before spawning threads.
69 if (g_ownership_service == this) {
70 // Start getting ownership status.
71 BrowserThread::PostTask(
72 BrowserThread::FILE, FROM_HERE,
73 base::Bind(&OwnershipService::FetchStatus, base::Unretained(this)));
74 } else {
75 // This can happen only for particular test: OwnershipServiceTest. It uses
76 // mocks and for that uses OwnershipService not as a regular singleton but
77 // as a resurrecting object. This behaviour conflicts with
78 // base::Unretained(). So avoid posting task in those circumstances
79 // in order to avoid accessing already deleted object.
80 }
81 }
82
83 bool OwnershipService::IsAlreadyOwned() {
84 return file_util::PathExists(utils_->GetOwnerKeyFilePath());
85 }
86
87 OwnershipService::Status OwnershipService::GetStatus(bool blocking) {
88 if (force_ownership_)
89 return OWNERSHIP_TAKEN;
90 Status status = OWNERSHIP_UNKNOWN;
91 bool is_owned = false;
92 if (BrowserThread::CurrentlyOn(BrowserThread::UI)) {
93 ownership_status_lock_.Acquire();
94 status = ownership_status_;
95 ownership_status_lock_.Release();
96 if (status != OWNERSHIP_UNKNOWN || !blocking)
97 return status;
98 // Under common usage there is very short lapse of time when ownership
99 // status is still unknown after constructing OwnershipService.
100 LOG(ERROR) << "Blocking on UI thread in OwnershipService::GetStatus";
101 base::ThreadRestrictions::ScopedAllowIO allow_io;
102 is_owned = IsAlreadyOwned();
103 } else {
104 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
105 is_owned = IsAlreadyOwned();
106 }
107 status = is_owned ? OWNERSHIP_TAKEN : OWNERSHIP_NONE;
108 SetStatus(status);
109 return status;
110 }
111
112 void OwnershipService::StartLoadOwnerKeyAttempt() {
113 BrowserThread::PostTask(
114 BrowserThread::FILE, FROM_HERE,
115 base::Bind(&TryLoadOwnerKeyAttempt, base::Unretained(this)));
116 }
117
118 void OwnershipService::StartUpdateOwnerKey(const std::vector<uint8>& new_key,
119 OwnerManager::KeyUpdateDelegate* d) {
120 BrowserThread::ID thread_id;
121 if (!BrowserThread::GetCurrentThreadIdentifier(&thread_id))
122 thread_id = BrowserThread::UI;
123 BrowserThread::PostTask(
124 BrowserThread::FILE, FROM_HERE,
125 base::Bind(&OwnershipService::UpdateOwnerKey, base::Unretained(this),
126 thread_id, new_key, d));
127 return;
128 }
129
130 void OwnershipService::StartSigningAttempt(const std::string& data,
131 OwnerManager::Delegate* d) {
132 BrowserThread::ID thread_id;
133 if (!BrowserThread::GetCurrentThreadIdentifier(&thread_id))
134 thread_id = BrowserThread::UI;
135 BrowserThread::PostTask(
136 BrowserThread::FILE, FROM_HERE,
137 base::Bind(&OwnershipService::TrySigningAttempt, base::Unretained(this),
138 thread_id, data, d));
139 return;
140 }
141
142 void OwnershipService::StartVerifyAttempt(const std::string& data,
143 const std::vector<uint8>& signature,
144 OwnerManager::Delegate* d) {
145 BrowserThread::ID thread_id;
146 if (!BrowserThread::GetCurrentThreadIdentifier(&thread_id))
147 thread_id = BrowserThread::UI;
148 BrowserThread::PostTask(
149 BrowserThread::FILE, FROM_HERE,
150 base::Bind(&OwnershipService::TryVerifyAttempt, base::Unretained(this),
151 thread_id, data, signature, d));
152 return;
153 }
154
155 void OwnershipService::Observe(int type,
156 const content::NotificationSource& source,
157 const content::NotificationDetails& details) {
158 if (type == chrome::NOTIFICATION_OWNER_KEY_FETCH_ATTEMPT_SUCCEEDED) {
159 SetStatus(OWNERSHIP_TAKEN);
160 notification_registrar_.RemoveAll();
161 } else {
162 NOTREACHED();
163 }
164 }
165
166 bool OwnershipService::IsCurrentUserOwner() {
167 if (force_ownership_)
168 return true;
169 // If this user has the private key associated with the owner's
170 // public key, this user is the owner.
171 return IsAlreadyOwned() && manager_->EnsurePrivateKey();
172 }
173
174 void OwnershipService::GetStatusAsync(const Callback& callback) {
175 PostTaskAndReplyWithResult(
176 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE),
177 FROM_HERE,
178 base::Bind(&CheckStatusOnFileThread),
179 base::Bind(&OwnershipService::ReturnStatus,
180 callback));
181 }
182
183
184 // static
185 void OwnershipService::UpdateOwnerKey(OwnershipService* service,
186 const BrowserThread::ID thread_id,
187 const std::vector<uint8>& new_key,
188 OwnerManager::KeyUpdateDelegate* d) {
189 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
190 service->manager()->UpdateOwnerKey(thread_id, new_key, d);
191 }
192
193 // static
194 void OwnershipService::TryLoadOwnerKeyAttempt(OwnershipService* service) {
195 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
196 if (!service->IsAlreadyOwned()) {
197 VLOG(1) << "Device not yet owned";
198 return;
199 }
200 service->manager()->LoadOwnerKey();
201 }
202
203 // static
204 void OwnershipService::TrySigningAttempt(OwnershipService* service,
205 const BrowserThread::ID thread_id,
206 const std::string& data,
207 OwnerManager::Delegate* d) {
208 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
209 if (!service->IsAlreadyOwned()) {
210 LOG(ERROR) << "Device not yet owned";
211 BrowserThread::PostTask(
212 thread_id, FROM_HERE,
213 base::Bind(&OwnershipService::FailAttempt, d));
214 return;
215 }
216 service->manager()->Sign(thread_id, data, d);
217 }
218
219 // static
220 void OwnershipService::TryVerifyAttempt(OwnershipService* service,
221 const BrowserThread::ID thread_id,
222 const std::string& data,
223 const std::vector<uint8>& signature,
224 OwnerManager::Delegate* d) {
225 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
226 if (!service->IsAlreadyOwned()) {
227 LOG(ERROR) << "Device not yet owned";
228 BrowserThread::PostTask(
229 thread_id, FROM_HERE,
230 base::Bind(&OwnershipService::FailAttempt, d));
231 return;
232 }
233 service->manager()->Verify(thread_id, data, signature, d);
234 }
235
236 // static
237 void OwnershipService::FailAttempt(OwnerManager::Delegate* d) {
238 d->OnKeyOpComplete(OwnerManager::KEY_UNAVAILABLE, std::vector<uint8>());
239 }
240
241 void OwnershipService::FetchStatus() {
242 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
243 Status status = IsAlreadyOwned() ? OWNERSHIP_TAKEN : OWNERSHIP_NONE;
244 SetStatus(status);
245 }
246
247 void OwnershipService::SetStatus(Status new_status) {
248 DCHECK(new_status == OWNERSHIP_TAKEN || new_status == OWNERSHIP_NONE);
249 base::AutoLock lk(ownership_status_lock_);
250 ownership_status_ = new_status;
251 }
252
253 // static
254 void OwnershipService::ReturnStatus(const Callback& callback,
255 OwnershipStatusReturnType status) {
256 callback.Run(status.first, status.second);
257 }
258
259 } // namespace chromeos
OLDNEW
« no previous file with comments | « chrome/browser/chromeos/login/ownership_service.h ('k') | chrome/browser/chromeos/login/ownership_service_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698