OLD | NEW |
---|---|
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/chromeos/gdata/operations_base.h" | 5 #include "chrome/browser/chromeos/gdata/operations_base.h" |
6 | 6 |
7 #include "base/debug/stack_trace.h" | |
hashimoto
2012/07/19 03:57:57
nit: Remove this.
yoshiki
2012/07/19 04:58:45
Done.
| |
8 | |
7 #include "base/json/json_reader.h" | 9 #include "base/json/json_reader.h" |
8 #include "base/metrics/histogram.h" | 10 #include "base/metrics/histogram.h" |
9 #include "base/string_number_conversions.h" | 11 #include "base/string_number_conversions.h" |
10 #include "base/stringprintf.h" | 12 #include "base/stringprintf.h" |
11 #include "base/values.h" | 13 #include "base/values.h" |
12 #include "chrome/browser/browser_process.h" | 14 #include "chrome/browser/browser_process.h" |
13 #include "chrome/common/net/gaia/gaia_urls.h" | 15 #include "chrome/common/net/gaia/gaia_urls.h" |
14 #include "chrome/common/net/gaia/google_service_auth_error.h" | 16 #include "chrome/common/net/gaia/google_service_auth_error.h" |
15 #include "chrome/common/net/gaia/oauth2_access_token_fetcher.h" | 17 #include "chrome/common/net/gaia/oauth2_access_token_fetcher.h" |
16 #include "chrome/common/net/url_util.h" | 18 #include "chrome/common/net/url_util.h" |
(...skipping 21 matching lines...) Expand all Loading... | |
38 const char kGDataVersionHeader[] = "GData-Version: 3.0"; | 40 const char kGDataVersionHeader[] = "GData-Version: 3.0"; |
39 | 41 |
40 // Maximum number of attempts for re-authentication per operation. | 42 // Maximum number of attempts for re-authentication per operation. |
41 const int kMaxReAuthenticateAttemptsPerOperation = 1; | 43 const int kMaxReAuthenticateAttemptsPerOperation = 1; |
42 | 44 |
43 // OAuth scope for the documents API. | 45 // OAuth scope for the documents API. |
44 const char kDocsListScope[] = "https://docs.google.com/feeds/"; | 46 const char kDocsListScope[] = "https://docs.google.com/feeds/"; |
45 const char kSpreadsheetsScope[] = "https://spreadsheets.google.com/feeds/"; | 47 const char kSpreadsheetsScope[] = "https://spreadsheets.google.com/feeds/"; |
46 const char kUserContentScope[] = "https://docs.googleusercontent.com/"; | 48 const char kUserContentScope[] = "https://docs.googleusercontent.com/"; |
47 | 49 |
50 // Parse JSON string to base::Value object. | |
51 void ParseJsonOnBlockingPool(const std::string& data, | |
52 scoped_ptr<base::Value>* value) { | |
53 DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
54 | |
55 int error_code = -1; | |
56 std::string error_message; | |
57 value->reset(base::JSONReader::ReadAndReturnError(data, | |
58 base::JSON_PARSE_RFC, | |
59 &error_code, | |
60 &error_message)); | |
61 | |
62 if (!value->get()) { | |
63 LOG(ERROR) << "Error while parsing entry response: " | |
64 << error_message | |
65 << ", code: " | |
66 << error_code | |
67 << ", data:\n" | |
68 << data; | |
69 } | |
70 } | |
71 | |
48 } // namespace | 72 } // namespace |
49 | 73 |
50 namespace gdata { | 74 namespace gdata { |
51 | 75 |
52 //================================ AuthOperation =============================== | 76 //================================ AuthOperation =============================== |
53 | 77 |
54 AuthOperation::AuthOperation(GDataOperationRegistry* registry, | 78 AuthOperation::AuthOperation(GDataOperationRegistry* registry, |
55 Profile* profile, | 79 Profile* profile, |
56 const AuthStatusCallback& callback, | 80 const AuthStatusCallback& callback, |
57 const std::string& refresh_token) | 81 const std::string& refresh_token) |
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
321 void EntryActionOperation::RunCallbackOnPrematureFailure(GDataErrorCode code) { | 345 void EntryActionOperation::RunCallbackOnPrematureFailure(GDataErrorCode code) { |
322 if (!callback_.is_null()) | 346 if (!callback_.is_null()) |
323 callback_.Run(code, document_url_); | 347 callback_.Run(code, document_url_); |
324 } | 348 } |
325 | 349 |
326 //============================== GetDataOperation ============================== | 350 //============================== GetDataOperation ============================== |
327 | 351 |
328 GetDataOperation::GetDataOperation(GDataOperationRegistry* registry, | 352 GetDataOperation::GetDataOperation(GDataOperationRegistry* registry, |
329 Profile* profile, | 353 Profile* profile, |
330 const GetDataCallback& callback) | 354 const GetDataCallback& callback) |
331 : UrlFetchOperationBase(registry, profile), callback_(callback) { | 355 : UrlFetchOperationBase(registry, profile), |
356 callback_(callback), | |
357 weak_ptr_factory_(this) { | |
332 } | 358 } |
333 | 359 |
334 GetDataOperation::~GetDataOperation() {} | 360 GetDataOperation::~GetDataOperation() {} |
335 | 361 |
336 bool GetDataOperation::ProcessURLFetchResults(const URLFetcher* source) { | 362 bool GetDataOperation::ProcessURLFetchResults(const URLFetcher* source) { |
337 std::string data; | 363 std::string data; |
338 source->GetResponseAsString(&data); | 364 source->GetResponseAsString(&data); |
339 scoped_ptr<base::Value> root_value; | 365 scoped_ptr<base::Value> root_value; |
340 GDataErrorCode code = GetErrorCode(source); | 366 GDataErrorCode fetch_error_code = GetErrorCode(source); |
367 bool ret = false; | |
341 | 368 |
342 switch (code) { | 369 switch (fetch_error_code) { |
343 case HTTP_SUCCESS: | 370 case HTTP_SUCCESS: |
344 case HTTP_CREATED: { | 371 case HTTP_CREATED: |
345 root_value.reset(ParseResponse(data)); | 372 ret = ParseResponse(fetch_error_code, data); |
346 if (!root_value.get()) | |
347 code = GDATA_PARSE_ERROR; | |
348 | |
349 break; | 373 break; |
350 } | |
351 default: | 374 default: |
375 RunCallback(fetch_error_code, scoped_ptr<base::Value>()); | |
352 break; | 376 break; |
353 } | 377 } |
354 | 378 |
355 if (!callback_.is_null()) | 379 return ret; |
356 callback_.Run(code, root_value.Pass()); | |
357 return root_value.get() != NULL; | |
358 } | 380 } |
359 | 381 |
360 void GetDataOperation::RunCallbackOnPrematureFailure(GDataErrorCode code) { | 382 void GetDataOperation::RunCallbackOnPrematureFailure( |
383 GDataErrorCode fetch_error_code) { | |
361 if (!callback_.is_null()) { | 384 if (!callback_.is_null()) { |
362 scoped_ptr<base::Value> root_value; | 385 scoped_ptr<base::Value> root_value; |
363 callback_.Run(code, root_value.Pass()); | 386 callback_.Run(fetch_error_code, root_value.Pass()); |
364 } | 387 } |
365 } | 388 } |
366 | 389 |
367 base::Value* GetDataOperation::ParseResponse(const std::string& data) { | 390 bool GetDataOperation::ParseResponse(GDataErrorCode fetch_error_code, |
368 int error_code = -1; | 391 const std::string& data) { |
369 std::string error_message; | 392 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
370 scoped_ptr<base::Value> root_value(base::JSONReader::ReadAndReturnError( | 393 base::debug::StackTrace().PrintBacktrace(); |
371 data, base::JSON_PARSE_RFC, &error_code, &error_message)); | 394 |
372 if (!root_value.get()) { | 395 // Uses this hack to avoid deep-copy of json object because json might be so |
373 LOG(ERROR) << "Error while parsing entry response: " | 396 // big. |
374 << error_message | 397 // This pointer of scped_ptr is to ensure a deletion of the parsed json value |
375 << ", code: " | 398 // object, even when OnDataParsed() is not called. |
376 << error_code | 399 scoped_ptr<base::Value>* parsed_value = new scoped_ptr<base::Value>(); |
377 << ", data:\n" | 400 |
378 << data; | 401 ParseJsonOnBlockingPool(data, parsed_value); |
hashimoto
2012/07/19 03:57:57
The comment-outed block below should be used inste
yoshiki
2012/07/19 04:58:45
Oops, I forgot to remove debugging code. sorry.
O
| |
379 return NULL; | 402 OnDataParsed(fetch_error_code, parsed_value); |
380 } | 403 delete parsed_value; |
381 return root_value.release(); | 404 return true; |
405 | |
406 /* | |
407 return BrowserThread::PostBlockingPoolTaskAndReply( | |
408 FROM_HERE, | |
409 base::Bind(&ParseJsonOnBlockingPool, | |
410 data, | |
411 parsed_value), | |
412 base::Bind(&GetDataOperation::OnDataParsed, | |
413 weak_ptr_factory_.GetWeakPtr(), | |
414 fetch_error_code, | |
415 base::Owned(parsed_value))); | |
416 */ | |
417 } | |
418 | |
419 void GetDataOperation::RunCallback(GDataErrorCode fetch_error_code, | |
420 scoped_ptr<base::Value> value) { | |
421 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
422 if (!callback_.is_null()) | |
423 callback_.Run(fetch_error_code, value.Pass()); | |
424 } | |
425 | |
426 void GetDataOperation::OnDataParsed(GDataErrorCode fetch_error_code, | |
427 scoped_ptr<base::Value>* value) { | |
428 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
429 if (!value->get()) | |
430 fetch_error_code = GDATA_PARSE_ERROR; | |
431 | |
432 // The ownership of the parsed json object is transfered to RunCallBack(), | |
433 // keeping the ownership of the |value| here. | |
434 RunCallback(fetch_error_code, value->Pass()); | |
435 DCHECK(!value->get()); | |
436 | |
437 // |value| will be deleted after return beause it is base::Owned()'d. | |
382 } | 438 } |
383 | 439 |
384 } // namespace gdata | 440 } // namespace gdata |
OLD | NEW |