OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2011 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/extensions/webstore_install_helper.h" |
| 6 |
| 7 #include <string> |
| 8 |
| 9 #include "base/task.h" |
| 10 #include "base/values.h" |
| 11 #include "chrome/common/chrome_utility_messages.h" |
| 12 #include "content/browser/browser_thread.h" |
| 13 #include "net/url_request/url_request_context_getter.h" |
| 14 #include "net/url_request/url_request_status.h" |
| 15 |
| 16 namespace { |
| 17 |
| 18 const char kImageDecodeError[] = "Image decode failed"; |
| 19 |
| 20 } // namespace |
| 21 |
| 22 WebstoreInstallHelper::WebstoreInstallHelper( |
| 23 Delegate* delegate, |
| 24 const std::string& manifest, |
| 25 const std::string& icon_data, |
| 26 const GURL& icon_url, |
| 27 net::URLRequestContextGetter* context_getter) |
| 28 : delegate_(delegate), |
| 29 manifest_(manifest), |
| 30 icon_base64_data_(icon_data), |
| 31 icon_url_(icon_url), |
| 32 context_getter_(context_getter), |
| 33 utility_host_(NULL), |
| 34 icon_decode_complete_(false), |
| 35 manifest_parse_complete_(false), |
| 36 parse_error_(Delegate::UNKNOWN_ERROR) {} |
| 37 |
| 38 WebstoreInstallHelper::~WebstoreInstallHelper() {} |
| 39 |
| 40 void WebstoreInstallHelper::Start() { |
| 41 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 42 CHECK(icon_base64_data_.empty() || icon_url_.is_empty()); |
| 43 |
| 44 if (icon_base64_data_.empty() && icon_url_.is_empty()) |
| 45 icon_decode_complete_ = true; |
| 46 |
| 47 BrowserThread::PostTask( |
| 48 BrowserThread::IO, |
| 49 FROM_HERE, |
| 50 NewRunnableMethod(this, |
| 51 &WebstoreInstallHelper::StartWorkOnIOThread)); |
| 52 |
| 53 if (!icon_url_.is_empty()) { |
| 54 CHECK(context_getter_); |
| 55 url_fetcher_.reset(new URLFetcher(icon_url_, URLFetcher::GET, this)); |
| 56 url_fetcher_->set_request_context(context_getter_); |
| 57 |
| 58 url_fetcher_->Start(); |
| 59 // We'll get called back in OnURLFetchComplete. |
| 60 } |
| 61 } |
| 62 |
| 63 void WebstoreInstallHelper::StartWorkOnIOThread() { |
| 64 CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 65 utility_host_ = new UtilityProcessHost(this, BrowserThread::IO); |
| 66 utility_host_->StartBatchMode(); |
| 67 |
| 68 if (!icon_base64_data_.empty()) |
| 69 utility_host_->Send( |
| 70 new ChromeUtilityMsg_DecodeImageBase64(icon_base64_data_)); |
| 71 |
| 72 utility_host_->Send(new ChromeUtilityMsg_ParseJSON(manifest_)); |
| 73 } |
| 74 |
| 75 void WebstoreInstallHelper::OnURLFetchComplete(const URLFetcher* source) { |
| 76 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 77 CHECK(source == url_fetcher_.get()); |
| 78 if (source->status().status() != net::URLRequestStatus::SUCCESS || |
| 79 source->response_code() != 200) { |
| 80 BrowserThread::PostTask( |
| 81 BrowserThread::IO, |
| 82 FROM_HERE, |
| 83 NewRunnableMethod(this, |
| 84 &WebstoreInstallHelper::OnDecodeImageFailed)); |
| 85 } else { |
| 86 std::string response_data; |
| 87 source->GetResponseAsString(&response_data); |
| 88 fetched_icon_data_.insert(fetched_icon_data_.begin(), |
| 89 response_data.begin(), |
| 90 response_data.end()); |
| 91 BrowserThread::PostTask( |
| 92 BrowserThread::IO, |
| 93 FROM_HERE, |
| 94 NewRunnableMethod(this, |
| 95 &WebstoreInstallHelper::StartFetchedImageDecode)); |
| 96 } |
| 97 url_fetcher_.reset(); |
| 98 } |
| 99 |
| 100 void WebstoreInstallHelper::StartFetchedImageDecode() { |
| 101 CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 102 CHECK(utility_host_); |
| 103 utility_host_->Send(new ChromeUtilityMsg_DecodeImage(fetched_icon_data_)); |
| 104 } |
| 105 |
| 106 |
| 107 bool WebstoreInstallHelper::OnMessageReceived(const IPC::Message& message) { |
| 108 bool handled = true; |
| 109 IPC_BEGIN_MESSAGE_MAP(WebstoreInstallHelper, message) |
| 110 IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_DecodeImage_Succeeded, |
| 111 OnDecodeImageSucceeded) |
| 112 IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_DecodeImage_Failed, |
| 113 OnDecodeImageFailed) |
| 114 IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_ParseJSON_Succeeded, |
| 115 OnJSONParseSucceeded) |
| 116 IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_ParseJSON_Failed, |
| 117 OnJSONParseFailed) |
| 118 IPC_MESSAGE_UNHANDLED(handled = false) |
| 119 IPC_END_MESSAGE_MAP() |
| 120 return handled; |
| 121 } |
| 122 |
| 123 |
| 124 void WebstoreInstallHelper::OnDecodeImageSucceeded( |
| 125 const SkBitmap& decoded_image) { |
| 126 CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 127 icon_ = decoded_image; |
| 128 icon_decode_complete_ = true; |
| 129 ReportResultsIfComplete(); |
| 130 } |
| 131 |
| 132 void WebstoreInstallHelper::OnDecodeImageFailed() { |
| 133 CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 134 icon_decode_complete_ = true; |
| 135 error_ = kImageDecodeError; |
| 136 parse_error_ = Delegate::ICON_ERROR; |
| 137 ReportResultsIfComplete(); |
| 138 } |
| 139 |
| 140 void WebstoreInstallHelper::OnJSONParseSucceeded(const ListValue& wrapper) { |
| 141 CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 142 manifest_parse_complete_ = true; |
| 143 Value* value = NULL; |
| 144 CHECK(wrapper.Get(0, &value)); |
| 145 if (value->IsType(Value::TYPE_DICTIONARY)) { |
| 146 parsed_manifest_.reset( |
| 147 static_cast<DictionaryValue*>(value)->DeepCopy()); |
| 148 } else { |
| 149 parse_error_ = Delegate::MANIFEST_ERROR; |
| 150 } |
| 151 ReportResultsIfComplete(); |
| 152 } |
| 153 |
| 154 void WebstoreInstallHelper::OnJSONParseFailed( |
| 155 const std::string& error_message) { |
| 156 CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 157 manifest_parse_complete_ = true; |
| 158 error_ = error_message; |
| 159 parse_error_ = Delegate::MANIFEST_ERROR; |
| 160 ReportResultsIfComplete(); |
| 161 } |
| 162 |
| 163 void WebstoreInstallHelper::ReportResultsIfComplete() { |
| 164 CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 165 |
| 166 if (!icon_decode_complete_ || !manifest_parse_complete_) |
| 167 return; |
| 168 |
| 169 // The utility_host_ will take care of deleting itself after this call. |
| 170 utility_host_->EndBatchMode(); |
| 171 utility_host_ = NULL; |
| 172 |
| 173 BrowserThread::PostTask( |
| 174 BrowserThread::UI, |
| 175 FROM_HERE, |
| 176 NewRunnableMethod(this, |
| 177 &WebstoreInstallHelper::ReportResultFromUIThread)); |
| 178 } |
| 179 |
| 180 void WebstoreInstallHelper::ReportResultFromUIThread() { |
| 181 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 182 if (error_.empty() && parsed_manifest_.get()) |
| 183 delegate_->OnWebstoreParseSuccess(icon_, parsed_manifest_.release()); |
| 184 else |
| 185 delegate_->OnWebstoreParseFailure(parse_error_, error_); |
| 186 } |
OLD | NEW |