Index: chrome/browser/extensions/webstore_data_fetcher.cc |
diff --git a/chrome/browser/extensions/webstore_data_fetcher.cc b/chrome/browser/extensions/webstore_data_fetcher.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..31065bda6eb83bd7470061f64b05f0e6ccf7ca27 |
--- /dev/null |
+++ b/chrome/browser/extensions/webstore_data_fetcher.cc |
@@ -0,0 +1,179 @@ |
+// Copyright 2013 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "chrome/browser/extensions/webstore_data_fetcher.h" |
+ |
+#include "base/values.h" |
+#include "chrome/browser/extensions/webstore_data_fetcher_delegate.h" |
+#include "chrome/common/chrome_utility_messages.h" |
+#include "chrome/common/extensions/extension_constants.h" |
+#include "content/public/browser/browser_thread.h" |
+#include "content/public/browser/utility_process_host.h" |
+#include "content/public/browser/utility_process_host_client.h" |
+#include "net/base/load_flags.h" |
+#include "net/url_request/url_fetcher.h" |
+#include "net/url_request/url_request_status.h" |
+ |
+using content::BrowserThread; |
+using content::UtilityProcessHost; |
+using content::UtilityProcessHostClient; |
+ |
+namespace { |
+ |
+const char kInvalidWebstoreResponseError[] = "Invalid Chrome Web Store reponse"; |
+ |
+} // namespace |
+ |
+namespace extensions { |
+ |
+//////////////////////////////////////////////////////////////////////////////// |
+// WebstoreDataFetcher::SafeWebstoreResponseParser |
asargent_no_longer_on_chrome
2013/02/12 18:40:10
nit: Is this comment needed/helpful? There's only
xiyuan
2013/02/12 18:49:03
Removed.
|
+ |
+class WebstoreDataFetcher::SafeWebstoreResponseParser |
+ : public UtilityProcessHostClient { |
+ public: |
+ SafeWebstoreResponseParser(const base::WeakPtr<WebstoreDataFetcher>& client, |
+ const std::string& webstore_data) |
+ : client_(client), |
+ webstore_data_(webstore_data) {} |
+ |
+ void Start() { |
+ CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
+ BrowserThread::PostTask( |
+ BrowserThread::IO, |
+ FROM_HERE, |
+ base::Bind(&SafeWebstoreResponseParser::StartWorkOnIOThread, this)); |
+ } |
+ |
+ void StartWorkOnIOThread() { |
+ CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
+ UtilityProcessHost* host = |
+ UtilityProcessHost::Create( |
+ this, base::MessageLoopProxy::current()); |
+ host->EnableZygote(); |
+ host->Send(new ChromeUtilityMsg_ParseJSON(webstore_data_)); |
+ } |
+ |
+ // Implementing pieces of the UtilityProcessHostClient interface. |
+ virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE { |
+ bool handled = true; |
+ IPC_BEGIN_MESSAGE_MAP(SafeWebstoreResponseParser, message) |
+ IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_ParseJSON_Succeeded, |
+ OnJSONParseSucceeded) |
+ IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_ParseJSON_Failed, |
+ OnJSONParseFailed) |
+ IPC_MESSAGE_UNHANDLED(handled = false) |
+ IPC_END_MESSAGE_MAP() |
+ return handled; |
+ } |
+ |
+ void OnJSONParseSucceeded(const base::ListValue& wrapper) { |
+ CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
+ const Value* value = NULL; |
+ CHECK(wrapper.Get(0, &value)); |
+ if (value->IsType(Value::TYPE_DICTIONARY)) { |
+ parsed_webstore_data_.reset( |
+ static_cast<const DictionaryValue*>(value)->DeepCopy()); |
+ } else { |
+ error_ = kInvalidWebstoreResponseError; |
+ } |
+ |
+ ReportResults(); |
+ } |
+ |
+ virtual void OnJSONParseFailed(const std::string& error_message) { |
+ CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
+ error_ = error_message; |
+ ReportResults(); |
+ } |
+ |
+ void ReportResults() { |
+ CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
+ |
+ BrowserThread::PostTask( |
+ BrowserThread::UI, |
+ FROM_HERE, |
+ base::Bind(&SafeWebstoreResponseParser::ReportResultOnUIThread, this)); |
+ } |
+ |
+ void ReportResultOnUIThread() { |
+ CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
+ if (!client_) |
+ return; |
+ |
+ if (error_.empty() && parsed_webstore_data_.get()) { |
+ client_->OnWebstoreResponseParseSuccess(parsed_webstore_data_.release()); |
+ } else { |
+ client_->OnWebstoreResponseParseFailure(error_); |
+ } |
+ } |
+ |
+ private: |
+ virtual ~SafeWebstoreResponseParser() {} |
+ |
+ base::WeakPtr<WebstoreDataFetcher> client_; |
+ |
+ std::string webstore_data_; |
+ std::string error_; |
+ scoped_ptr<DictionaryValue> parsed_webstore_data_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(SafeWebstoreResponseParser); |
+}; |
+ |
+WebstoreDataFetcher::WebstoreDataFetcher( |
+ WebstoreDataFetcherDelegate* delegate, |
+ net::URLRequestContextGetter* request_context, |
+ const GURL& referrer_url, |
+ const std::string webstore_item_id) |
+ : delegate_(delegate), |
+ request_context_(request_context), |
+ referrer_url_(referrer_url), |
+ id_(webstore_item_id) { |
+} |
+ |
+WebstoreDataFetcher::~WebstoreDataFetcher() {} |
+ |
+void WebstoreDataFetcher::Start() { |
+ GURL webstore_data_url(extension_urls::GetWebstoreItemJsonDataURL(id_)); |
+ |
+ webstore_data_url_fetcher_.reset(net::URLFetcher::Create( |
+ webstore_data_url, net::URLFetcher::GET, this)); |
+ webstore_data_url_fetcher_->SetRequestContext(request_context_); |
+ webstore_data_url_fetcher_->SetReferrer(referrer_url_.spec()); |
+ webstore_data_url_fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SAVE_COOKIES | |
+ net::LOAD_DISABLE_CACHE); |
+ webstore_data_url_fetcher_->Start(); |
+} |
+ |
+void WebstoreDataFetcher::OnWebstoreResponseParseSuccess( |
+ base::DictionaryValue* webstore_data) { |
+ delegate_->OnWebstoreResponseParseSuccess(webstore_data); |
+} |
+ |
+void WebstoreDataFetcher::OnWebstoreResponseParseFailure( |
+ const std::string& error) { |
+ delegate_->OnWebstoreResponseParseFailure(error); |
+} |
+ |
+void WebstoreDataFetcher::OnURLFetchComplete(const net::URLFetcher* source) { |
+ CHECK_EQ(webstore_data_url_fetcher_.get(), source); |
+ |
+ if (!webstore_data_url_fetcher_->GetStatus().is_success() || |
+ webstore_data_url_fetcher_->GetResponseCode() != 200) { |
+ delegate_->OnWebstoreRequestFailure(); |
+ return; |
+ } |
+ |
+ std::string webstore_json_data; |
+ webstore_data_url_fetcher_->GetResponseAsString(&webstore_json_data); |
+ webstore_data_url_fetcher_.reset(); |
+ |
+ scoped_refptr<SafeWebstoreResponseParser> parser = |
+ new SafeWebstoreResponseParser(AsWeakPtr(), webstore_json_data); |
+ // The parser will call us back via OnWebstoreResponseParseSucces or |
+ // OnWebstoreResponseParseFailure. |
+ parser->Start(); |
+} |
+ |
+} // namespace extensions |