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

Side by Side Diff: chrome/browser/chrome_to_mobile_service.cc

Issue 10834203: Integrate invalidation API into ChromeToMobileService. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Sync and merge; consume ipc::invalidation::ObjectSource::CHROME_COMPONENTS. 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
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/chrome_to_mobile_service.h" 5 #include "chrome/browser/chrome_to_mobile_service.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/command_line.h" 8 #include "base/command_line.h"
9 #include "base/file_util.h" 9 #include "base/file_util.h"
10 #include "base/guid.h" 10 #include "base/guid.h"
11 #include "base/json/json_reader.h" 11 #include "base/json/json_reader.h"
12 #include "base/json/json_writer.h" 12 #include "base/json/json_writer.h"
13 #include "base/metrics/histogram.h" 13 #include "base/metrics/histogram.h"
14 #include "base/stringprintf.h" 14 #include "base/stringprintf.h"
15 #include "base/utf_string_conversions.h" 15 #include "base/utf_string_conversions.h"
16 #include "chrome/app/chrome_command_ids.h" 16 #include "chrome/app/chrome_command_ids.h"
17 #include "chrome/browser/content_settings/cookie_settings.h" 17 #include "chrome/browser/content_settings/cookie_settings.h"
18 #include "chrome/browser/prefs/pref_service.h" 18 #include "chrome/browser/prefs/pref_service.h"
19 #include "chrome/browser/printing/cloud_print/cloud_print_url.h" 19 #include "chrome/browser/printing/cloud_print/cloud_print_url.h"
20 #include "chrome/browser/profiles/profile.h" 20 #include "chrome/browser/profiles/profile.h"
21 #include "chrome/browser/signin/token_service.h" 21 #include "chrome/browser/signin/token_service.h"
22 #include "chrome/browser/signin/token_service_factory.h" 22 #include "chrome/browser/signin/token_service_factory.h"
23 #include "chrome/browser/sync/profile_sync_service.h"
24 #include "chrome/browser/sync/profile_sync_service_factory.h"
23 #include "chrome/browser/ui/browser.h" 25 #include "chrome/browser/ui/browser.h"
24 #include "chrome/browser/ui/browser_command_controller.h" 26 #include "chrome/browser/ui/browser_command_controller.h"
25 #include "chrome/browser/ui/browser_finder.h" 27 #include "chrome/browser/ui/browser_finder.h"
26 #include "chrome/browser/ui/browser_list.h" 28 #include "chrome/browser/ui/browser_list.h"
27 #include "chrome/browser/ui/browser_navigator.h" 29 #include "chrome/browser/ui/browser_navigator.h"
28 #include "chrome/browser/ui/browser_tabstrip.h" 30 #include "chrome/browser/ui/browser_tabstrip.h"
29 #include "chrome/common/chrome_notification_types.h" 31 #include "chrome/common/chrome_notification_types.h"
30 #include "chrome/common/chrome_switches.h" 32 #include "chrome/common/chrome_switches.h"
31 #include "chrome/common/cloud_print/cloud_print_helpers.h" 33 #include "chrome/common/cloud_print/cloud_print_helpers.h"
32 #include "chrome/common/net/gaia/gaia_constants.h" 34 #include "chrome/common/net/gaia/gaia_constants.h"
33 #include "chrome/common/net/gaia/gaia_urls.h" 35 #include "chrome/common/net/gaia/gaia_urls.h"
34 #include "chrome/common/net/gaia/oauth2_access_token_fetcher.h" 36 #include "chrome/common/net/gaia/oauth2_access_token_fetcher.h"
35 #include "chrome/common/pref_names.h" 37 #include "chrome/common/pref_names.h"
36 #include "chrome/common/url_constants.h" 38 #include "chrome/common/url_constants.h"
37 #include "content/public/browser/browser_thread.h" 39 #include "content/public/browser/browser_thread.h"
38 #include "content/public/browser/notification_details.h" 40 #include "content/public/browser/notification_details.h"
39 #include "content/public/browser/notification_source.h" 41 #include "content/public/browser/notification_source.h"
40 #include "content/public/browser/web_contents.h" 42 #include "content/public/browser/web_contents.h"
43 #include "google/cacheinvalidation/include/types.h"
44 #include "google/cacheinvalidation/types.pb.h"
41 #include "net/base/escape.h" 45 #include "net/base/escape.h"
42 #include "net/base/load_flags.h" 46 #include "net/base/load_flags.h"
43 #include "net/url_request/url_fetcher.h" 47 #include "net/url_request/url_fetcher.h"
44 #include "net/url_request/url_request_context_getter.h" 48 #include "net/url_request/url_request_context_getter.h"
45 49
46 namespace { 50 namespace {
47 51
48 // The default enabled/disabled state of the Chrome To Mobile feature. 52 // The default enabled/disabled state of the Chrome To Mobile feature.
49 const bool kChromeToMobileEnabled = false; 53 const bool kChromeToMobileEnabled = false;
50 54
51 // The maximum number of retries for the URLFetcher requests. 55 // The maximum number of retries for the URLFetcher requests.
52 const size_t kMaxRetries = 1; 56 const size_t kMaxRetries = 1;
53 57
54 // The number of hours to delay before retrying authentication on failure. 58 // The number of hours to delay before retrying authentication on failure.
55 const size_t kAuthRetryDelayHours = 6; 59 const size_t kAuthRetryDelayHours = 6;
56 60
57 // The number of hours before subsequent search requests are allowed. 61 // The number of hours before subsequent search requests are allowed.
58 // This value is used to throttle expensive cloud print search requests. 62 // This value is used to throttle expensive cloud print search requests.
59 // Note that this limitation does not hold across application restarts. 63 // Note that this limitation does not hold across application restarts.
60 const int kSearchRequestDelayHours = 24; 64 const int kSearchRequestDelayHours = 24;
61 65
66 // TODO(msw): Push back for enum values, instead of these string contstants?
67 // The invalidation object ID for the User space, Chrome to Mobile, Mobile LiST.
68 // ("U" == "User", "CM" == "Chrome to Mobile", "MLST" == "Mobile LiST").
69 const char kMobileListObjectId[] = "UCMMLST";
akalin 2012/08/08 23:06:27 i think object id names have to be strings
msw 2012/08/10 22:05:05 I've voiced my dissent, but will go along :) "It w
akalin 2012/08/10 23:03:22 I understand you don't like strings, but I don't k
nyquist 2012/08/10 23:46:39 The object ID name must match whatever the source
70
62 // The cloud print OAuth2 scope and 'printer' type of compatible mobile devices. 71 // The cloud print OAuth2 scope and 'printer' type of compatible mobile devices.
63 const char kCloudPrintAuth[] = "https://www.googleapis.com/auth/cloudprint"; 72 const char kCloudPrintAuth[] = "https://www.googleapis.com/auth/cloudprint";
64 const char kTypeAndroid[] = "ANDROID_CHROME_SNAPSHOT"; 73 const char kTypeAndroid[] = "ANDROID_CHROME_SNAPSHOT";
65 const char kTypeIOS[] = "IOS_CHROME_SNAPSHOT"; 74 const char kTypeIOS[] = "IOS_CHROME_SNAPSHOT";
66 75
67 // The account info URL pattern and strings to check for cloud print access. 76 // The account info URL pattern and strings to check for cloud print access.
68 // The 'key=' query parameter is used for caching; supply a random number. 77 // The 'key=' query parameter is used for caching; supply a random number.
69 // The 'rv=2' query parameter requests a JSON response; use 'rv=1' for XML. 78 // The 'rv=2' query parameter requests a JSON response; use 'rv=1' for XML.
70 const char kAccountInfoURL[] = 79 const char kAccountInfoURL[] =
71 "https://clients1.google.com/tbproxy/getaccountinfo?key=%s&rv=2&%s"; 80 "https://clients1.google.com/tbproxy/getaccountinfo?key=%s&rv=2&%s";
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
171 if (command_line->HasSwitch(switches::kEnableChromeToMobile)) 180 if (command_line->HasSwitch(switches::kEnableChromeToMobile))
172 return true; 181 return true;
173 182
174 return kChromeToMobileEnabled; 183 return kChromeToMobileEnabled;
175 } 184 }
176 185
177 // static 186 // static
178 void ChromeToMobileService::RegisterUserPrefs(PrefService* prefs) { 187 void ChromeToMobileService::RegisterUserPrefs(PrefService* prefs) {
179 prefs->RegisterListPref(prefs::kChromeToMobileDeviceList, 188 prefs->RegisterListPref(prefs::kChromeToMobileDeviceList,
180 PrefService::UNSYNCABLE_PREF); 189 PrefService::UNSYNCABLE_PREF);
181 prefs->RegisterInt64Pref(prefs::kChromeToMobileTimestamp, 0, 190 // TODO(msw): Okay to change a pref from Int64 to string?
182 PrefService::UNSYNCABLE_PREF); 191 // TODO(msw): Consider renaming timestamp to version? Which is it?
192 prefs->RegisterStringPref(prefs::kChromeToMobileTimestamp, "",
akalin 2012/08/08 23:06:27 just to be clear, this is different from the inval
msw 2012/08/10 22:05:05 Removed. I was changing it to match the last recei
193 PrefService::UNSYNCABLE_PREF);
183 } 194 }
184 195
185 ChromeToMobileService::ChromeToMobileService(Profile* profile) 196 ChromeToMobileService::ChromeToMobileService(Profile* profile)
186 : ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)), 197 : ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)),
187 profile_(profile), 198 profile_(profile),
199 mobile_list_id_(ipc::invalidation::ObjectSource::CHROME_COMPONENTS,
200 kMobileListObjectId),
201 sync_invalidation_enabled_(false),
188 cloud_print_url_(new CloudPrintURL(profile)), 202 cloud_print_url_(new CloudPrintURL(profile)),
189 cloud_print_accessible_(false) { 203 cloud_print_accessible_(false) {
190 // Skip initialization if constructed without a profile. 204 // Skip initialization if constructed without a profile.
191 if (profile_) { 205 if (profile_) {
dcheng 2012/08/08 23:11:10 Why do you need to check profile_ here and not oth
msw 2012/08/10 22:05:05 It's for the GMock unit tests, which provide a NUL
192 // Get an access token as soon as the Gaia login refresh token is available. 206 // Get an access token as soon as the Gaia login refresh token is available.
193 TokenService* service = TokenServiceFactory::GetForProfile(profile_); 207 TokenService* token_service = TokenServiceFactory::GetForProfile(profile_);
194 registrar_.Add(this, chrome::NOTIFICATION_TOKEN_AVAILABLE, 208 registrar_.Add(this, chrome::NOTIFICATION_TOKEN_AVAILABLE,
195 content::Source<TokenService>(service)); 209 content::Source<TokenService>(token_service));
196 if (service->HasOAuthLoginToken()) 210 if (token_service->HasOAuthLoginToken())
197 RefreshAccessToken(); 211 RefreshAccessToken();
212
213 ProfileSyncService* profile_sync_service =
214 ProfileSyncServiceFactory::GetForProfile(profile_);
215 // TODO(msw): Update with https://chromiumcodereview.appspot.com/10824161/
216 //profile_sync_service->AddHandler(this);
217 sync_objects_.insert(mobile_list_id_);
218 profile_sync_service->UpdateRegisteredInvalidationIds(this, sync_objects_);
219 // TODO(msw): Check if sync_invalidation_enabled_ directly here?
akalin 2012/08/08 23:06:27 Hmm, I guess you need some way to check if notific
msw 2012/08/10 22:05:05 How about profile_sync_service->IsSyncEnabled()? N
220 // TODO(msw): Or are we always pinged via OnNotificationsEnabled?
198 } 221 }
199 } 222 }
200 223
201 ChromeToMobileService::~ChromeToMobileService() { 224 ChromeToMobileService::~ChromeToMobileService() {
202 while (!snapshots_.empty()) 225 while (!snapshots_.empty())
203 DeleteSnapshot(*snapshots_.begin()); 226 DeleteSnapshot(*snapshots_.begin());
227 if (profile_) {
228 // TODO(msw): Update with https://chromiumcodereview.appspot.com/10824161/
229 //ProfileSyncService* profile_sync_service =
230 // ProfileSyncServiceFactory::GetForProfile(profile_);
231 //profile_sync_service->RemoveHandler(this);
232 }
204 } 233 }
205 234
206 bool ChromeToMobileService::HasMobiles() { 235 bool ChromeToMobileService::HasMobiles() {
207 return !GetMobiles()->empty(); 236 const base::ListValue* mobiles = GetMobiles();
237 return mobiles && !mobiles->empty();
208 } 238 }
209 239
210 const base::ListValue* ChromeToMobileService::GetMobiles() const { 240 const base::ListValue* ChromeToMobileService::GetMobiles() const {
241 if (!sync_invalidation_enabled_)
242 return NULL;
243
211 return profile_->GetPrefs()->GetList(prefs::kChromeToMobileDeviceList); 244 return profile_->GetPrefs()->GetList(prefs::kChromeToMobileDeviceList);
212 } 245 }
213 246
214 void ChromeToMobileService::RequestMobileListUpdate() { 247 void ChromeToMobileService::RequestMobileListUpdate() {
215 if (access_token_.empty()) 248 if (access_token_.empty())
216 RefreshAccessToken(); 249 RefreshAccessToken();
217 else if (cloud_print_accessible_) 250 else if (sync_invalidation_enabled_ && cloud_print_accessible_)
218 RequestSearch(); 251 RequestSearch();
219 } 252 }
220 253
221 void ChromeToMobileService::GenerateSnapshot(Browser* browser, 254 void ChromeToMobileService::GenerateSnapshot(Browser* browser,
222 base::WeakPtr<Observer> observer) { 255 base::WeakPtr<Observer> observer) {
223 // Callback SnapshotFileCreated from CreateSnapshotFile to continue. 256 // Callback SnapshotFileCreated from CreateSnapshotFile to continue.
224 CreateSnapshotFileCallback callback = 257 CreateSnapshotFileCallback callback =
225 base::Bind(&ChromeToMobileService::SnapshotFileCreated, 258 base::Bind(&ChromeToMobileService::SnapshotFileCreated,
226 weak_ptr_factory_.GetWeakPtr(), observer, 259 weak_ptr_factory_.GetWeakPtr(), observer,
227 browser->session_id().id()); 260 browser->session_id().id());
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
325 358
326 void ChromeToMobileService::OnGetTokenFailure( 359 void ChromeToMobileService::OnGetTokenFailure(
327 const GoogleServiceAuthError& error) { 360 const GoogleServiceAuthError& error) {
328 access_token_fetcher_.reset(); 361 access_token_fetcher_.reset();
329 auth_retry_timer_.Stop(); 362 auth_retry_timer_.Stop();
330 auth_retry_timer_.Start( 363 auth_retry_timer_.Start(
331 FROM_HERE, base::TimeDelta::FromHours(kAuthRetryDelayHours), 364 FROM_HERE, base::TimeDelta::FromHours(kAuthRetryDelayHours),
332 this, &ChromeToMobileService::RefreshAccessToken); 365 this, &ChromeToMobileService::RefreshAccessToken);
333 } 366 }
334 367
368 void ChromeToMobileService::OnNotificationsEnabled() {
369 // Only enable Chrome To Mobile if Sync Invalidation Notification are enabled.
370 // Otherwise, the device list may be out of date and result in send failures.
371 // TODO(msw): Load the cached mobile list now (instead of sync_invalidation_en abled_)?
372 sync_invalidation_enabled_ = true;
373 }
374
375 void ChromeToMobileService::OnNotificationsDisabled(
376 syncer::NotificationsDisabledReason reason) {
377 // Only enable Chrome To Mobile if Sync Invalidation Notification are enabled.
378 // Otherwise, the device list may be out of date and result in send failures.
379 // TODO(msw): Clear the cached mobile list now (instead of sync_invalidation_e nabled_)?
380 sync_invalidation_enabled_ = false;
381 }
382
383 void ChromeToMobileService::OnIncomingNotification(
384 const syncer::ObjectIdPayloadMap& id_payloads,
385 syncer::IncomingNotificationSource source) {
386 DCHECK(sync_invalidation_enabled_);
387 DCHECK_EQ(id_payloads.size(), 1U);
388 DCHECK_EQ(id_payloads.count(mobile_list_id_), 1U);
389 std::string new_timestamp = id_payloads.find(mobile_list_id_)->second;
390
391 PrefService* prefs = profile_->GetPrefs();
392 std::string timestamp = prefs->GetString(prefs::kChromeToMobileTimestamp);
393 // TODO(msw): Check if the timestamp is newer? Or just different?
394 if (!new_timestamp.empty() && timestamp.compare(new_timestamp) != 0) {
395 // TODO(msw): Update the cached timestamp now, or only on successful update?
396 prefs->SetString(prefs::kChromeToMobileTimestamp, new_timestamp);
397 RequestMobileListUpdate();
398 }
399 }
400
335 void ChromeToMobileService::SnapshotFileCreated( 401 void ChromeToMobileService::SnapshotFileCreated(
336 base::WeakPtr<Observer> observer, 402 base::WeakPtr<Observer> observer,
337 SessionID::id_type browser_id, 403 SessionID::id_type browser_id,
338 const FilePath& path, 404 const FilePath& path,
339 bool success) { 405 bool success) {
340 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 406 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
341 // Track the set of temporary files to be deleted later. 407 // Track the set of temporary files to be deleted later.
342 snapshots_.insert(path); 408 snapshots_.insert(path);
343 409
344 Browser* browser = browser::FindBrowserWithID(browser_id); 410 Browser* browser = browser::FindBrowserWithID(browser_id);
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
438 std::string url_string = StringPrintf(kAccountInfoURL, 504 std::string url_string = StringPrintf(kAccountInfoURL,
439 base::GenerateGUID().c_str(), kChromeToMobileRequestor); 505 base::GenerateGUID().c_str(), kChromeToMobileRequestor);
440 GURL url(url_string); 506 GURL url(url_string);
441 507
442 // Account information is read from the profile's cookie. If cookies are 508 // Account information is read from the profile's cookie. If cookies are
443 // blocked, access cloud print directly to list any potential devices. 509 // blocked, access cloud print directly to list any potential devices.
444 scoped_refptr<CookieSettings> cookie_settings = 510 scoped_refptr<CookieSettings> cookie_settings =
445 CookieSettings::Factory::GetForProfile(profile_); 511 CookieSettings::Factory::GetForProfile(profile_);
446 if (cookie_settings && !cookie_settings->IsReadingCookieAllowed(url, url)) { 512 if (cookie_settings && !cookie_settings->IsReadingCookieAllowed(url, url)) {
447 cloud_print_accessible_ = true; 513 cloud_print_accessible_ = true;
448 RequestMobileListUpdate(); 514 // TODO(msw): Don't poll now... RequestMobileListUpdate();
449 return; 515 return;
450 } 516 }
451 517
452 account_info_request_.reset( 518 account_info_request_.reset(
453 net::URLFetcher::Create(url, net::URLFetcher::GET, this)); 519 net::URLFetcher::Create(url, net::URLFetcher::GET, this));
454 account_info_request_->SetRequestContext(profile_->GetRequestContext()); 520 account_info_request_->SetRequestContext(profile_->GetRequestContext());
455 account_info_request_->SetMaxRetries(kMaxRetries); 521 account_info_request_->SetMaxRetries(kMaxRetries);
456 // This request sends the user's cookie to check the cloud print service flag. 522 // This request sends the user's cookie to check the cloud print service flag.
457 account_info_request_->SetLoadFlags(net::LOAD_DO_NOT_SAVE_COOKIES); 523 account_info_request_->SetLoadFlags(net::LOAD_DO_NOT_SAVE_COOKIES);
458 account_info_request_->Start(); 524 account_info_request_->Start();
459 } 525 }
460 526
461 void ChromeToMobileService::RequestSearch() { 527 void ChromeToMobileService::RequestSearch() {
462 DCHECK(!access_token_.empty()); 528 DCHECK(!access_token_.empty());
529 DCHECK(sync_invalidation_enabled_);
463 530
464 // Deny requests if cloud print is inaccessible, and deny concurrent requests. 531 // Deny requests if cloud print is inaccessible, and deny concurrent requests.
465 if (!cloud_print_accessible_ || search_request_.get()) 532 if (!cloud_print_accessible_ || search_request_.get())
466 return; 533 return;
467 534
468 PrefService* prefs = profile_->GetPrefs();
469 base::TimeTicks previous_search_time = base::TimeTicks::FromInternalValue(
470 prefs->GetInt64(prefs::kChromeToMobileTimestamp));
471
472 // Deny requests before the delay period has passed since the last request.
473 base::TimeDelta elapsed_time = base::TimeTicks::Now() - previous_search_time;
474 if (!previous_search_time.is_null() &&
475 elapsed_time.InHours() < kSearchRequestDelayHours)
476 return;
477
478 LogMetric(DEVICES_REQUESTED); 535 LogMetric(DEVICES_REQUESTED);
479 536
480 const GURL service_url(cloud_print_url_->GetCloudPrintServiceURL()); 537 const GURL service_url(cloud_print_url_->GetCloudPrintServiceURL());
481 search_request_.reset(net::URLFetcher::Create(GetSearchURL(service_url), 538 search_request_.reset(net::URLFetcher::Create(GetSearchURL(service_url),
482 net::URLFetcher::GET, this)); 539 net::URLFetcher::GET, this));
483 InitRequest(search_request_.get()); 540 InitRequest(search_request_.get());
484 search_request_->Start(); 541 search_request_->Start();
485 } 542 }
486 543
487 void ChromeToMobileService::HandleAccountInfoResponse() { 544 void ChromeToMobileService::HandleAccountInfoResponse() {
488 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 545 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
489 546
490 std::string data; 547 std::string data;
491 account_info_request_->GetResponseAsString(&data); 548 account_info_request_->GetResponseAsString(&data);
492 account_info_request_.reset(); 549 account_info_request_.reset();
493 550
494 ListValue* services = NULL; 551 ListValue* services = NULL;
495 DictionaryValue* dictionary = NULL; 552 DictionaryValue* dictionary = NULL;
496 scoped_ptr<Value> json(base::JSONReader::Read(data)); 553 scoped_ptr<Value> json(base::JSONReader::Read(data));
497 StringValue cloud_print_service(kCloudPrintSerivceValue); 554 StringValue cloud_print_service(kCloudPrintSerivceValue);
498 if (json.get() && json->GetAsDictionary(&dictionary) && dictionary && 555 if (json.get() && json->GetAsDictionary(&dictionary) && dictionary &&
499 dictionary->GetList(kAccountServicesKey, &services) && services && 556 dictionary->GetList(kAccountServicesKey, &services) && services &&
500 services->Find(cloud_print_service) != services->end()) { 557 services->Find(cloud_print_service) != services->end()) {
501 cloud_print_accessible_ = true; 558 cloud_print_accessible_ = true;
502 RequestMobileListUpdate(); 559 // TODO(msw): Don't poll now... RequestMobileListUpdate();
503 } 560 }
504 } 561 }
505 562
506 void ChromeToMobileService::HandleSearchResponse() { 563 void ChromeToMobileService::HandleSearchResponse() {
507 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 564 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
508 565
509 std::string data; 566 std::string data;
510 search_request_->GetResponseAsString(&data); 567 search_request_->GetResponseAsString(&data);
511 search_request_.reset(); 568 search_request_.reset();
512 569
(...skipping 17 matching lines...) Expand all
530 mobile->SetString("type", type); 587 mobile->SetString("type", type);
531 mobile->SetString("name", name); 588 mobile->SetString("name", name);
532 mobile->SetString("id", id); 589 mobile->SetString("id", id);
533 mobiles.Append(mobile); 590 mobiles.Append(mobile);
534 } else { 591 } else {
535 NOTREACHED(); 592 NOTREACHED();
536 } 593 }
537 } 594 }
538 } 595 }
539 596
540 // Update the mobile list and timestamp in prefs. 597 // Update the mobile list in prefs.
541 PrefService* prefs = profile_->GetPrefs(); 598 // TODO(msw): Update the timestamp now (only on successful list updates?)
542 prefs->Set(prefs::kChromeToMobileDeviceList, mobiles); 599 profile_->GetPrefs()->Set(prefs::kChromeToMobileDeviceList, mobiles);
543 prefs->SetInt64(prefs::kChromeToMobileTimestamp,
544 base::TimeTicks::Now().ToInternalValue());
545 600
546 const bool has_mobiles = HasMobiles(); 601 const bool has_mobiles = HasMobiles();
547 if (has_mobiles) 602 if (has_mobiles)
548 LogMetric(DEVICES_AVAILABLE); 603 LogMetric(DEVICES_AVAILABLE);
549 604
550 for (BrowserList::const_iterator i = BrowserList::begin(); 605 for (BrowserList::const_iterator i = BrowserList::begin();
551 i != BrowserList::end(); ++i) { 606 i != BrowserList::end(); ++i) {
552 Browser* browser = *i; 607 Browser* browser = *i;
553 if (browser->profile() == profile_) 608 if (browser->profile() == profile_)
554 browser->command_controller()->SendToMobileStateChanged(has_mobiles); 609 browser->command_controller()->SendToMobileStateChanged(has_mobiles);
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
586 641
587 // Ensure a second response is not sent after reporting failure below. 642 // Ensure a second response is not sent after reporting failure below.
588 request_observer_map_.erase(other); 643 request_observer_map_.erase(other);
589 break; 644 break;
590 } 645 }
591 } 646 }
592 647
593 LogMetric(success ? SEND_SUCCESS : SEND_ERROR); 648 LogMetric(success ? SEND_SUCCESS : SEND_ERROR);
594 observer->OnSendComplete(success); 649 observer->OnSendComplete(success);
595 } 650 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698