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

Side by Side Diff: chrome/browser/extensions/webstore_standalone_installer.cc

Issue 12212076: Move web store data fetching and parsing out of WebstoreStandaloneInstaller. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 7 years, 10 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/extensions/webstore_standalone_installer.h" 5 #include "chrome/browser/extensions/webstore_standalone_installer.h"
6 6
7 #include <vector> 7 #include <vector>
8 8
9 #include "base/bind.h" 9 #include "base/stringprintf.h"
10 #include "base/string_util.h"
11 #include "base/values.h" 10 #include "base/values.h"
12 #include "chrome/browser/browser_process.h"
13 #include "chrome/browser/extensions/crx_installer.h" 11 #include "chrome/browser/extensions/crx_installer.h"
14 #include "chrome/browser/extensions/extension_install_ui.h" 12 #include "chrome/browser/extensions/extension_install_ui.h"
15 #include "chrome/browser/extensions/extension_service.h" 13 #include "chrome/browser/extensions/extension_service.h"
14 #include "chrome/browser/extensions/webstore_data_fetcher.h"
16 #include "chrome/browser/profiles/profile.h" 15 #include "chrome/browser/profiles/profile.h"
17 #include "chrome/common/chrome_utility_messages.h"
18 #include "chrome/common/extensions/extension.h" 16 #include "chrome/common/extensions/extension.h"
19 #include "chrome/common/extensions/extension_constants.h"
20 #include "chrome/common/url_constants.h"
21 #include "content/public/browser/utility_process_host.h"
22 #include "content/public/browser/utility_process_host_client.h"
23 #include "content/public/browser/web_contents.h" 17 #include "content/public/browser/web_contents.h"
24 #include "content/public/browser/web_contents_view.h" 18 #include "content/public/browser/web_contents_view.h"
25 #include "extensions/common/url_pattern.h"
26 #include "net/base/escape.h"
27 #include "net/base/load_flags.h"
28 #include "net/url_request/url_fetcher.h"
29 #include "net/url_request/url_request_status.h"
30 19
31 using content::BrowserThread; 20 using content::BrowserThread;
32 using content::OpenURLParams; 21 using content::OpenURLParams;
33 using content::UtilityProcessHost;
34 using content::UtilityProcessHostClient;
35 using content::WebContents; 22 using content::WebContents;
36 23
37 namespace extensions { 24 namespace extensions {
38 25
39 const char kManifestKey[] = "manifest"; 26 const char kManifestKey[] = "manifest";
40 const char kIconUrlKey[] = "icon_url"; 27 const char kIconUrlKey[] = "icon_url";
41 const char kLocalizedNameKey[] = "localized_name"; 28 const char kLocalizedNameKey[] = "localized_name";
42 const char kLocalizedDescriptionKey[] = "localized_description"; 29 const char kLocalizedDescriptionKey[] = "localized_description";
43 const char kUsersKey[] = "users"; 30 const char kUsersKey[] = "users";
44 const char kAverageRatingKey[] = "average_rating"; 31 const char kAverageRatingKey[] = "average_rating";
(...skipping 11 matching lines...) Expand all
56 const char kNoVerifiedSiteError[] = 43 const char kNoVerifiedSiteError[] =
57 "Inline installs can only be initiated for Chrome Web Store items that " 44 "Inline installs can only be initiated for Chrome Web Store items that "
58 "have a verified site"; 45 "have a verified site";
59 const char kNotFromVerifiedSiteError[] = 46 const char kNotFromVerifiedSiteError[] =
60 "Installs can only be initiated by the Chrome Web Store item's verified " 47 "Installs can only be initiated by the Chrome Web Store item's verified "
61 "site"; 48 "site";
62 const char kInlineInstallSupportedError[] = 49 const char kInlineInstallSupportedError[] =
63 "Inline installation is not supported for this item. The user will be " 50 "Inline installation is not supported for this item. The user will be "
64 "redirected to the Chrome Web Store."; 51 "redirected to the Chrome Web Store.";
65 52
66 class SafeWebstoreResponseParser : public UtilityProcessHostClient {
67 public:
68 SafeWebstoreResponseParser(WebstoreStandaloneInstaller *client,
69 const std::string& webstore_data)
70 : client_(client),
71 webstore_data_(webstore_data) {}
72
73 void Start() {
74 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
75 BrowserThread::PostTask(
76 BrowserThread::IO,
77 FROM_HERE,
78 base::Bind(&SafeWebstoreResponseParser::StartWorkOnIOThread, this));
79 }
80
81 void StartWorkOnIOThread() {
82 CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
83 UtilityProcessHost* host =
84 UtilityProcessHost::Create(
85 this, base::MessageLoopProxy::current());
86 host->EnableZygote();
87 host->Send(new ChromeUtilityMsg_ParseJSON(webstore_data_));
88 }
89
90 // Implementing pieces of the UtilityProcessHostClient interface.
91 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE {
92 bool handled = true;
93 IPC_BEGIN_MESSAGE_MAP(SafeWebstoreResponseParser, message)
94 IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_ParseJSON_Succeeded,
95 OnJSONParseSucceeded)
96 IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_ParseJSON_Failed,
97 OnJSONParseFailed)
98 IPC_MESSAGE_UNHANDLED(handled = false)
99 IPC_END_MESSAGE_MAP()
100 return handled;
101 }
102
103 void OnJSONParseSucceeded(const ListValue& wrapper) {
104 CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
105 const Value* value = NULL;
106 CHECK(wrapper.Get(0, &value));
107 if (value->IsType(Value::TYPE_DICTIONARY)) {
108 parsed_webstore_data_.reset(
109 static_cast<const DictionaryValue*>(value)->DeepCopy());
110 } else {
111 error_ = kInvalidWebstoreResponseError;
112 }
113
114 ReportResults();
115 }
116
117 virtual void OnJSONParseFailed(const std::string& error_message) {
118 CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
119 error_ = error_message;
120 ReportResults();
121 }
122
123 void ReportResults() {
124 CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
125
126 BrowserThread::PostTask(
127 BrowserThread::UI,
128 FROM_HERE,
129 base::Bind(&SafeWebstoreResponseParser::ReportResultOnUIThread, this));
130 }
131
132 void ReportResultOnUIThread() {
133 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
134 if (error_.empty() && parsed_webstore_data_.get()) {
135 client_->OnWebstoreResponseParseSuccess(parsed_webstore_data_.release());
136 } else {
137 client_->OnWebstoreResponseParseFailure(error_);
138 }
139 }
140
141 private:
142 virtual ~SafeWebstoreResponseParser() {}
143
144 WebstoreStandaloneInstaller* client_;
145
146 std::string webstore_data_;
147 std::string error_;
148 scoped_ptr<DictionaryValue> parsed_webstore_data_;
149 };
150
151 WebstoreStandaloneInstaller::WebstoreStandaloneInstaller( 53 WebstoreStandaloneInstaller::WebstoreStandaloneInstaller(
152 WebContents* web_contents, 54 WebContents* web_contents,
153 std::string webstore_item_id, 55 std::string webstore_item_id,
154 VerifiedSiteRequired require_verified_site, 56 VerifiedSiteRequired require_verified_site,
155 PromptType prompt_type, 57 PromptType prompt_type,
156 GURL requestor_url, 58 GURL requestor_url,
157 Callback callback) 59 Callback callback)
158 : content::WebContentsObserver(web_contents), 60 : content::WebContentsObserver(web_contents),
159 id_(webstore_item_id), 61 id_(webstore_item_id),
160 require_verified_site_(require_verified_site == REQUIRE_VERIFIED_SITE), 62 require_verified_site_(require_verified_site == REQUIRE_VERIFIED_SITE),
161 prompt_type_(prompt_type), 63 prompt_type_(prompt_type),
162 requestor_url_(requestor_url), 64 requestor_url_(requestor_url),
163 callback_(callback), 65 callback_(callback),
164 skip_post_install_ui_(false), 66 skip_post_install_ui_(false),
165 average_rating_(0.0), 67 average_rating_(0.0),
166 rating_count_(0) { 68 rating_count_(0) {
167 CHECK(!callback.is_null()); 69 CHECK(!callback.is_null());
168 } 70 }
169 71
170 void WebstoreStandaloneInstaller::BeginInstall() { 72 void WebstoreStandaloneInstaller::BeginInstall() {
171 AddRef(); // Balanced in CompleteInstall or WebContentsDestroyed. 73 AddRef(); // Balanced in CompleteInstall or WebContentsDestroyed.
172 74
173 if (!Extension::IdIsValid(id_)) { 75 if (!Extension::IdIsValid(id_)) {
174 CompleteInstall(kInvalidWebstoreItemId); 76 CompleteInstall(kInvalidWebstoreItemId);
175 return; 77 return;
176 } 78 }
177 79
178 GURL webstore_data_url(extension_urls::GetWebstoreItemJsonDataURL(id_));
179
180 webstore_data_url_fetcher_.reset(net::URLFetcher::Create(
181 webstore_data_url, net::URLFetcher::GET, this));
182 Profile* profile = Profile::FromBrowserContext( 80 Profile* profile = Profile::FromBrowserContext(
183 web_contents()->GetBrowserContext()); 81 web_contents()->GetBrowserContext());
184 webstore_data_url_fetcher_->SetRequestContext(
185 profile->GetRequestContext());
186 // Use the requesting page as the referrer both since that is more correct 82 // Use the requesting page as the referrer both since that is more correct
187 // (it is the page that caused this request to happen) and so that we can 83 // (it is the page that caused this request to happen) and so that we can
188 // track top sites that trigger inline install requests. 84 // track top sites that trigger inline install requests.
189 webstore_data_url_fetcher_->SetReferrer(requestor_url_.spec()); 85 webstore_data_fetcher_.reset(new WebstoreDataFetcher(
190 webstore_data_url_fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SAVE_COOKIES | 86 this,
191 net::LOAD_DISABLE_CACHE); 87 profile->GetRequestContext(),
192 webstore_data_url_fetcher_->Start(); 88 requestor_url_,
89 id_));
90 webstore_data_fetcher_->Start();
193 } 91 }
194 92
195 WebstoreStandaloneInstaller::~WebstoreStandaloneInstaller() {} 93 WebstoreStandaloneInstaller::~WebstoreStandaloneInstaller() {}
196 94
197 void WebstoreStandaloneInstaller::OnURLFetchComplete( 95 void WebstoreStandaloneInstaller::OnWebstoreRequestFailure() {
198 const net::URLFetcher* source) { 96 CompleteInstall(kWebstoreRequestError);
199 CHECK_EQ(webstore_data_url_fetcher_.get(), source);
200 // We shouldn't be getting UrlFetcher callbacks if the WebContents has gone
201 // away; we stop any in in-progress fetches in WebContentsDestroyed.
202 CHECK(web_contents());
203
204 if (!webstore_data_url_fetcher_->GetStatus().is_success() ||
205 webstore_data_url_fetcher_->GetResponseCode() != 200) {
206 CompleteInstall(kWebstoreRequestError);
207 return;
208 }
209
210 std::string webstore_json_data;
211 webstore_data_url_fetcher_->GetResponseAsString(&webstore_json_data);
212 webstore_data_url_fetcher_.reset();
213
214 scoped_refptr<SafeWebstoreResponseParser> parser =
215 new SafeWebstoreResponseParser(this, webstore_json_data);
216 // The parser will call us back via OnWebstoreResponseParseSucces or
217 // OnWebstoreResponseParseFailure.
218 parser->Start();
219 } 97 }
220 98
221 void WebstoreStandaloneInstaller::OnWebstoreResponseParseSuccess( 99 void WebstoreStandaloneInstaller::OnWebstoreResponseParseSuccess(
222 DictionaryValue* webstore_data) { 100 DictionaryValue* webstore_data) {
223 // Check if the tab has gone away in the meantime. 101 // Check if the tab has gone away in the meantime.
224 if (!web_contents()) { 102 if (!web_contents()) {
225 CompleteInstall(""); 103 CompleteInstall("");
226 return; 104 return;
227 } 105 }
228 106
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
418 } 296 }
419 297
420 void WebstoreStandaloneInstaller::InstallUIAbort(bool user_initiated) { 298 void WebstoreStandaloneInstaller::InstallUIAbort(bool user_initiated) {
421 CompleteInstall(kUserCancelledError); 299 CompleteInstall(kUserCancelledError);
422 } 300 }
423 301
424 void WebstoreStandaloneInstaller::WebContentsDestroyed( 302 void WebstoreStandaloneInstaller::WebContentsDestroyed(
425 WebContents* web_contents) { 303 WebContents* web_contents) {
426 callback_.Reset(); 304 callback_.Reset();
427 // Abort any in-progress fetches. 305 // Abort any in-progress fetches.
428 if (webstore_data_url_fetcher_.get()) { 306 if (webstore_data_fetcher_.get()) {
429 webstore_data_url_fetcher_.reset(); 307 webstore_data_fetcher_.reset();
430 Release(); // Matches the AddRef in BeginInstall. 308 Release(); // Matches the AddRef in BeginInstall.
431 } 309 }
432 } 310 }
433 311
434 void WebstoreStandaloneInstaller::OnExtensionInstallSuccess( 312 void WebstoreStandaloneInstaller::OnExtensionInstallSuccess(
435 const std::string& id) { 313 const std::string& id) {
436 CHECK_EQ(id_, id); 314 CHECK_EQ(id_, id);
437 CompleteInstall(""); 315 CompleteInstall("");
438 } 316 }
439 317
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
471 DLOG(WARNING) << "Could not parse " << verified_site_url << 349 DLOG(WARNING) << "Could not parse " << verified_site_url <<
472 " as URL pattern " << parse_result; 350 " as URL pattern " << parse_result;
473 return false; 351 return false;
474 } 352 }
475 verified_site_pattern.SetScheme("*"); 353 verified_site_pattern.SetScheme("*");
476 354
477 return verified_site_pattern.MatchesURL(requestor_url); 355 return verified_site_pattern.MatchesURL(requestor_url);
478 } 356 }
479 357
480 } // namespace extensions 358 } // namespace extensions
OLDNEW
« no previous file with comments | « chrome/browser/extensions/webstore_standalone_installer.h ('k') | chrome/chrome_browser_extensions.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698