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

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

Issue 1153143002: Fix race condition in WebstoreInstallHelper (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 7 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
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_install_helper.h" 5 #include "chrome/browser/extensions/webstore_install_helper.h"
6 6
7 #include <string> 7 #include <string>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/thread_task_runner_handle.h" 10 #include "base/thread_task_runner_handle.h"
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
44 icon_decode_complete_(false), 44 icon_decode_complete_(false),
45 manifest_parse_complete_(false), 45 manifest_parse_complete_(false),
46 parse_error_(Delegate::UNKNOWN_ERROR) { 46 parse_error_(Delegate::UNKNOWN_ERROR) {
47 } 47 }
48 48
49 WebstoreInstallHelper::~WebstoreInstallHelper() {} 49 WebstoreInstallHelper::~WebstoreInstallHelper() {}
50 50
51 void WebstoreInstallHelper::Start() { 51 void WebstoreInstallHelper::Start() {
52 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 52 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
53 53
54 BrowserThread::PostTask(
55 BrowserThread::IO,
56 FROM_HERE,
57 base::Bind(&WebstoreInstallHelper::StartWorkOnIOThread, this));
58 }
59
60 void WebstoreInstallHelper::StartWorkOnIOThread() {
61 CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
62
54 if (icon_url_.is_empty()) { 63 if (icon_url_.is_empty()) {
55 icon_decode_complete_ = true; 64 icon_decode_complete_ = true;
56 } else { 65 } else {
57 // No existing |icon_fetcher_| to avoid unbalanced AddRef(). 66 // No existing |icon_fetcher_| to avoid unbalanced AddRef().
58 CHECK(!icon_fetcher_.get()); 67 CHECK(!icon_fetcher_.get());
59 AddRef(); // Balanced in OnFetchComplete(). 68 AddRef(); // Balanced in OnFetchComplete().
60 icon_fetcher_.reset(new chrome::BitmapFetcher(icon_url_, this)); 69 icon_fetcher_.reset(new chrome::BitmapFetcher(icon_url_, this));
61 icon_fetcher_->Start( 70 icon_fetcher_->Start(
62 context_getter_, std::string(), 71 context_getter_, std::string(),
asargent_no_longer_on_chrome 2015/05/27 16:49:23 There's a comment in the .h file for context_gette
Marc Treib 2015/05/28 10:03:49 Good catch! Looks like the URL fetching should rea
63 net::URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE, 72 net::URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE,
64 net::LOAD_DO_NOT_SAVE_COOKIES | net::LOAD_DO_NOT_SEND_COOKIES); 73 net::LOAD_DO_NOT_SAVE_COOKIES | net::LOAD_DO_NOT_SEND_COOKIES);
65 } 74 }
66 75
67 BrowserThread::PostTask(
68 BrowserThread::IO,
69 FROM_HERE,
70 base::Bind(&WebstoreInstallHelper::StartWorkOnIOThread, this));
71 }
72
73 void WebstoreInstallHelper::StartWorkOnIOThread() {
74 CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
75 utility_host_ = UtilityProcessHost::Create( 76 utility_host_ = UtilityProcessHost::Create(
76 this, base::ThreadTaskRunnerHandle::Get().get())->AsWeakPtr(); 77 this, base::ThreadTaskRunnerHandle::Get().get())->AsWeakPtr();
77 utility_host_->SetName(l10n_util::GetStringUTF16( 78 utility_host_->SetName(l10n_util::GetStringUTF16(
78 IDS_UTILITY_PROCESS_JSON_PARSER_NAME)); 79 IDS_UTILITY_PROCESS_JSON_PARSER_NAME));
79 utility_host_->StartBatchMode(); 80 utility_host_->StartBatchMode();
80 81
81 utility_host_->Send(new ChromeUtilityMsg_ParseJSON(manifest_)); 82 utility_host_->Send(new ChromeUtilityMsg_ParseJSON(manifest_));
82 } 83 }
83 84
84 bool WebstoreInstallHelper::OnMessageReceived(const IPC::Message& message) { 85 bool WebstoreInstallHelper::OnMessageReceived(const IPC::Message& message) {
85 bool handled = true; 86 bool handled = true;
86 IPC_BEGIN_MESSAGE_MAP(WebstoreInstallHelper, message) 87 IPC_BEGIN_MESSAGE_MAP(WebstoreInstallHelper, message)
87 IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_ParseJSON_Succeeded, 88 IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_ParseJSON_Succeeded,
88 OnJSONParseSucceeded) 89 OnJSONParseSucceeded)
89 IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_ParseJSON_Failed, 90 IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_ParseJSON_Failed,
90 OnJSONParseFailed) 91 OnJSONParseFailed)
91 IPC_MESSAGE_UNHANDLED(handled = false) 92 IPC_MESSAGE_UNHANDLED(handled = false)
92 IPC_END_MESSAGE_MAP() 93 IPC_END_MESSAGE_MAP()
93 return handled; 94 return handled;
94 } 95 }
95 96
96 void WebstoreInstallHelper::OnFetchComplete(const GURL& url, 97 void WebstoreInstallHelper::OnFetchComplete(const GURL& url,
97 const SkBitmap* image) { 98 const SkBitmap* image) {
98 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 99 CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
99 // OnFetchComplete should only be called as icon_fetcher_ delegate to avoid 100 // OnFetchComplete should only be called as icon_fetcher_ delegate to avoid
100 // unbalanced Release(). 101 // unbalanced Release().
101 CHECK(icon_fetcher_.get()); 102 CHECK(icon_fetcher_.get());
102 103
103 if (image) 104 if (image)
104 icon_ = *image; 105 icon_ = *image;
105 icon_decode_complete_ = true; 106 icon_decode_complete_ = true;
106 if (icon_.empty()) { 107 if (icon_.empty()) {
107 error_ = kImageDecodeError; 108 error_ = kImageDecodeError;
108 parse_error_ = Delegate::ICON_ERROR; 109 parse_error_ = Delegate::ICON_ERROR;
109 } 110 }
110 icon_fetcher_.reset(); 111 icon_fetcher_.reset();
111 BrowserThread::PostTask( 112 Release(); // Balanced in StartWorkOnIOThread().
112 BrowserThread::IO, 113 ReportResultsIfComplete();
113 FROM_HERE,
114 base::Bind(&WebstoreInstallHelper::ReportResultsIfComplete, this));
115 Release(); // Balanced in Start().
116 } 114 }
117 115
118 void WebstoreInstallHelper::OnJSONParseSucceeded( 116 void WebstoreInstallHelper::OnJSONParseSucceeded(
119 const base::ListValue& wrapper) { 117 const base::ListValue& wrapper) {
120 CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 118 CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
121 manifest_parse_complete_ = true; 119 manifest_parse_complete_ = true;
122 const base::Value* value = NULL; 120 const base::Value* value = NULL;
123 CHECK(wrapper.Get(0, &value)); 121 CHECK(wrapper.Get(0, &value));
124 if (value->IsType(base::Value::TYPE_DICTIONARY)) { 122 if (value->IsType(base::Value::TYPE_DICTIONARY)) {
125 parsed_manifest_.reset( 123 parsed_manifest_.reset(
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
159 157
160 void WebstoreInstallHelper::ReportResultFromUIThread() { 158 void WebstoreInstallHelper::ReportResultFromUIThread() {
161 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 159 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
162 if (error_.empty() && parsed_manifest_) 160 if (error_.empty() && parsed_manifest_)
163 delegate_->OnWebstoreParseSuccess(id_, icon_, parsed_manifest_.release()); 161 delegate_->OnWebstoreParseSuccess(id_, icon_, parsed_manifest_.release());
164 else 162 else
165 delegate_->OnWebstoreParseFailure(id_, parse_error_, error_); 163 delegate_->OnWebstoreParseFailure(id_, parse_error_, error_);
166 } 164 }
167 165
168 } // namespace extensions 166 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698