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

Side by Side Diff: chrome/browser/chromeos/gdata/gdata_operations.cc

Issue 10749015: gdrive: Get JSON feeds parsing off the UI thread (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: review fix Created 8 years, 5 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/chromeos/gdata/gdata_operations.h" 5 #include "chrome/browser/chromeos/gdata/gdata_operations.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/json/json_reader.h" 8 #include "base/json/json_reader.h"
9 #include "base/metrics/histogram.h" 9 #include "base/metrics/histogram.h"
10 #include "base/string_number_conversions.h" 10 #include "base/string_number_conversions.h"
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
153 // URL for fetching documents in a particular directory. 153 // URL for fetching documents in a particular directory.
154 GURL FormatDocumentListURL(const std::string& directory_resource_id) { 154 GURL FormatDocumentListURL(const std::string& directory_resource_id) {
155 if (directory_resource_id.empty()) 155 if (directory_resource_id.empty())
156 return GURL(kGetDocumentListURLForAllDocuments); 156 return GURL(kGetDocumentListURLForAllDocuments);
157 157
158 return GURL(base::StringPrintf(kGetDocumentListURLForDirectoryFormat, 158 return GURL(base::StringPrintf(kGetDocumentListURLForDirectoryFormat,
159 net::EscapePath( 159 net::EscapePath(
160 directory_resource_id).c_str())); 160 directory_resource_id).c_str()));
161 } 161 }
162 162
163 // Parse JSON string to base::Value object.
164 void ParseJsonOnBlockingPool(const std::string& data,
165 scoped_ptr<base::Value>* value) {
166 DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::UI));
167
168 int error_code = -1;
169 std::string error_message;
170 value->reset(base::JSONReader::ReadAndReturnError(data,
171 base::JSON_PARSE_RFC,
172 &error_code,
173 &error_message));
174
175 if (!value->get()) {
176 LOG(ERROR) << "Error while parsing entry response: "
177 << error_message
178 << ", code: "
179 << error_code
180 << ", data:\n"
181 << data;
182 }
183 }
184
163 } // namespace 185 } // namespace
164 186
165 namespace gdata { 187 namespace gdata {
166 188
167 //================================ AuthOperation =============================== 189 //================================ AuthOperation ===============================
168 190
169 AuthOperation::AuthOperation(GDataOperationRegistry* registry, 191 AuthOperation::AuthOperation(GDataOperationRegistry* registry,
170 Profile* profile, 192 Profile* profile,
171 const AuthStatusCallback& callback, 193 const AuthStatusCallback& callback,
172 const std::string& refresh_token) 194 const std::string& refresh_token)
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after
441 void EntryActionOperation::RunCallbackOnPrematureFailure(GDataErrorCode code) { 463 void EntryActionOperation::RunCallbackOnPrematureFailure(GDataErrorCode code) {
442 if (!callback_.is_null()) 464 if (!callback_.is_null())
443 callback_.Run(code, document_url_); 465 callback_.Run(code, document_url_);
444 } 466 }
445 467
446 //============================== GetDataOperation ============================== 468 //============================== GetDataOperation ==============================
447 469
448 GetDataOperation::GetDataOperation(GDataOperationRegistry* registry, 470 GetDataOperation::GetDataOperation(GDataOperationRegistry* registry,
449 Profile* profile, 471 Profile* profile,
450 const GetDataCallback& callback) 472 const GetDataCallback& callback)
451 : UrlFetchOperationBase(registry, profile), callback_(callback) { 473 : UrlFetchOperationBase(registry, profile),
474 callback_(callback),
475 weak_ptr_factory_(this) {
452 } 476 }
453 477
454 GetDataOperation::~GetDataOperation() {} 478 GetDataOperation::~GetDataOperation() {}
455 479
456 bool GetDataOperation::ProcessURLFetchResults(const net::URLFetcher* source) { 480 bool GetDataOperation::ProcessURLFetchResults(const net::URLFetcher* source) {
457 std::string data; 481 std::string data;
458 source->GetResponseAsString(&data); 482 source->GetResponseAsString(&data);
459 scoped_ptr<base::Value> root_value; 483 GDataErrorCode fetch_error_code = GetErrorCode(source);
460 GDataErrorCode code = GetErrorCode(source); 484 bool ret = false;
461 485
462 switch (code) { 486 switch (fetch_error_code) {
463 case HTTP_SUCCESS: 487 case HTTP_SUCCESS:
464 case HTTP_CREATED: { 488 case HTTP_CREATED:
465 root_value.reset(ParseResponse(data)); 489 ret = ParseResponse(fetch_error_code, data);
466 if (!root_value.get())
467 code = GDATA_PARSE_ERROR;
468
469 break; 490 break;
470 }
471 default: 491 default:
492 RunCallback(fetch_error_code, scoped_ptr<base::Value>());
472 break; 493 break;
473 } 494 }
474 495
475 if (!callback_.is_null()) 496 return ret;
476 callback_.Run(code, root_value.Pass());
477 return root_value.get() != NULL;
hashimoto 2012/07/11 03:32:08 Look like this code had a bug where the return val
478 } 497 }
479 498
480 void GetDataOperation::RunCallbackOnPrematureFailure(GDataErrorCode code) { 499 void GetDataOperation::RunCallbackOnPrematureFailure(
500 GDataErrorCode fetch_error_code) {
481 if (!callback_.is_null()) { 501 if (!callback_.is_null()) {
482 scoped_ptr<base::Value> root_value; 502 scoped_ptr<base::Value> root_value;
483 callback_.Run(code, root_value.Pass()); 503 callback_.Run(fetch_error_code, root_value.Pass());
484 } 504 }
485 } 505 }
486 506
487 base::Value* GetDataOperation::ParseResponse(const std::string& data) { 507 bool GetDataOperation::ParseResponse(GDataErrorCode fetch_error_code,
488 int error_code = -1; 508 const std::string& data) {
489 std::string error_message; 509 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
490 scoped_ptr<base::Value> root_value(base::JSONReader::ReadAndReturnError( 510
491 data, base::JSON_PARSE_RFC, &error_code, &error_message)); 511 // Uses this hack to avoid deep-copy of json object because json might be so
492 if (!root_value.get()) { 512 // big.
493 LOG(ERROR) << "Error while parsing entry response: " 513 // This pointer of scped_ptr is to ensure a deletion of the parsed json value
494 << error_message 514 // object, even when OnDataParsed() is not called.
495 << ", code: " 515 scoped_ptr<base::Value>* parsed_value = new scoped_ptr<base::Value>();
496 << error_code 516
497 << ", data:\n" 517 return BrowserThread::PostBlockingPoolTaskAndReply(
498 << data; 518 FROM_HERE,
499 return NULL; 519 base::Bind(&ParseJsonOnBlockingPool,
500 } 520 data,
501 return root_value.release(); 521 parsed_value),
522 base::Bind(&GetDataOperation::OnDataParsed,
523 weak_ptr_factory_.GetWeakPtr(),
524 fetch_error_code,
525 base::Owned(parsed_value)));
526 }
527
528 void GetDataOperation::RunCallback(GDataErrorCode fetch_error_code,
529 scoped_ptr<base::Value> value) {
530 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
531 if (!callback_.is_null())
532 callback_.Run(fetch_error_code, value.Pass());
533 }
534
535 void GetDataOperation::OnDataParsed(GDataErrorCode fetch_error_code,
536 scoped_ptr<base::Value>* value) {
537 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
538 if (!value->get())
539 fetch_error_code = GDATA_PARSE_ERROR;
540
541 // The ownership of the parsed json object is transfered to RunCallBack(),
542 // keeping the ownership of the |value| here.
543 RunCallback(fetch_error_code, value->Pass());
544 DCHECK(!value->get());
545
546 // |value| will be deleted after return beause it is base::Owned()'d.
502 } 547 }
503 548
504 //============================ GetDocumentsOperation =========================== 549 //============================ GetDocumentsOperation ===========================
505 550
506 GetDocumentsOperation::GetDocumentsOperation( 551 GetDocumentsOperation::GetDocumentsOperation(
507 GDataOperationRegistry* registry, 552 GDataOperationRegistry* registry,
508 Profile* profile, 553 Profile* profile,
509 int start_changestamp, 554 int start_changestamp,
510 const std::string& search_string, 555 const std::string& search_string,
511 const std::string& directory_resource_id, 556 const std::string& directory_resource_id,
(...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after
852 xml_writer.WriteElement("docs:authorizedApp", app_id_); 897 xml_writer.WriteElement("docs:authorizedApp", app_id_);
853 898
854 xml_writer.EndElement(); // Ends "entry" element. 899 xml_writer.EndElement(); // Ends "entry" element.
855 xml_writer.StopWriting(); 900 xml_writer.StopWriting();
856 upload_content->assign(xml_writer.GetWrittenString()); 901 upload_content->assign(xml_writer.GetWrittenString());
857 DVLOG(1) << "AuthorizeAppOperation data: " << *upload_content_type << ", [" 902 DVLOG(1) << "AuthorizeAppOperation data: " << *upload_content_type << ", ["
858 << *upload_content << "]"; 903 << *upload_content << "]";
859 return true; 904 return true;
860 } 905 }
861 906
862 base::Value* AuthorizeAppsOperation::ParseResponse(const std::string& data) { 907 bool AuthorizeAppsOperation::ParseResponse(GDataErrorCode code,
908 const std::string& data) {
863 // Parse entry XML. 909 // Parse entry XML.
864 XmlReader xml_reader; 910 XmlReader xml_reader;
865 scoped_ptr<DocumentEntry> entry; 911 scoped_ptr<DocumentEntry> entry;
866 if (xml_reader.Load(data)) { 912 if (xml_reader.Load(data)) {
867 while (xml_reader.Read()) { 913 while (xml_reader.Read()) {
868 if (xml_reader.NodeName() == DocumentEntry::GetEntryNodeName()) { 914 if (xml_reader.NodeName() == DocumentEntry::GetEntryNodeName()) {
869 entry.reset(DocumentEntry::CreateFromXml(&xml_reader)); 915 entry.reset(DocumentEntry::CreateFromXml(&xml_reader));
870 break; 916 break;
871 } 917 }
872 } 918 }
873 } 919 }
874 920
875 // From the response, we create a list of the links returned, since those 921 // From the response, we create a list of the links returned, since those
876 // are the only things we are interested in. 922 // are the only things we are interested in.
877 scoped_ptr<base::ListValue> link_list(new ListValue); 923 scoped_ptr<base::ListValue> link_list(new ListValue);
878 const ScopedVector<Link>& feed_links = entry->links(); 924 const ScopedVector<Link>& feed_links = entry->links();
879 for (ScopedVector<Link>::const_iterator iter = feed_links.begin(); 925 for (ScopedVector<Link>::const_iterator iter = feed_links.begin();
880 iter != feed_links.end(); ++iter) { 926 iter != feed_links.end(); ++iter) {
881 if ((*iter)->type() == Link::OPEN_WITH) { 927 if ((*iter)->type() == Link::OPEN_WITH) {
882 base::DictionaryValue* link = new DictionaryValue; 928 base::DictionaryValue* link = new DictionaryValue;
883 link->SetString(std::string("href"), (*iter)->href().spec()); 929 link->SetString(std::string("href"), (*iter)->href().spec());
884 link->SetString(std::string("mime_type"), (*iter)->mime_type()); 930 link->SetString(std::string("mime_type"), (*iter)->mime_type());
885 link->SetString(std::string("title"), (*iter)->title()); 931 link->SetString(std::string("title"), (*iter)->title());
886 link->SetString(std::string("app_id"), (*iter)->app_id()); 932 link->SetString(std::string("app_id"), (*iter)->app_id());
887 link_list->Append(link); 933 link_list->Append(link);
888 } 934 }
889 } 935 }
890 936
891 return link_list.release(); 937 RunCallback(code, link_list.PassAs<base::Value>());
938
939 return true;
892 } 940 }
893 941
894 GURL AuthorizeAppsOperation::GetURL() const { 942 GURL AuthorizeAppsOperation::GetURL() const {
895 return document_url_; 943 return document_url_;
896 } 944 }
897 945
898 //======================= AddResourceToDirectoryOperation ====================== 946 //======================= AddResourceToDirectoryOperation ======================
899 947
900 AddResourceToDirectoryOperation::AddResourceToDirectoryOperation( 948 AddResourceToDirectoryOperation::AddResourceToDirectoryOperation(
901 GDataOperationRegistry* registry, 949 GDataOperationRegistry* registry,
(...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after
1226 return true; 1274 return true;
1227 } 1275 }
1228 1276
1229 void ResumeUploadOperation::OnURLFetchUploadProgress( 1277 void ResumeUploadOperation::OnURLFetchUploadProgress(
1230 const net::URLFetcher* source, int64 current, int64 total) { 1278 const net::URLFetcher* source, int64 current, int64 total) {
1231 // Adjust the progress values according to the range currently uploaded. 1279 // Adjust the progress values according to the range currently uploaded.
1232 NotifyProgress(params_.start_range + current, params_.content_length); 1280 NotifyProgress(params_.start_range + current, params_.content_length);
1233 } 1281 }
1234 1282
1235 } // namespace gdata 1283 } // namespace gdata
OLDNEW
« no previous file with comments | « chrome/browser/chromeos/gdata/gdata_operations.h ('k') | chrome/browser/chromeos/gdata/gdata_operations_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698