OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 // Implements the Chrome Extensions Cookies API. | 5 // Implements the Chrome Extensions Cookies API. |
6 | 6 |
7 #include "chrome/browser/extensions/extension_cookies_api.h" | 7 #include "chrome/browser/extensions/extension_cookies_api.h" |
8 | 8 |
9 #include "base/json/json_writer.h" | 9 #include "base/json/json_writer.h" |
10 #include "base/task.h" | |
11 #include "chrome/browser/browser_list.h" | 10 #include "chrome/browser/browser_list.h" |
12 #include "chrome/browser/chrome_thread.h" | |
13 #include "chrome/browser/extensions/extension_cookies_api_constants.h" | 11 #include "chrome/browser/extensions/extension_cookies_api_constants.h" |
14 #include "chrome/browser/extensions/extension_cookies_helpers.h" | 12 #include "chrome/browser/extensions/extension_cookies_helpers.h" |
15 #include "chrome/browser/extensions/extension_message_service.h" | 13 #include "chrome/browser/extensions/extension_message_service.h" |
16 #include "chrome/browser/profile.h" | 14 #include "chrome/browser/profile.h" |
17 #include "chrome/common/extensions/extension_error_utils.h" | 15 #include "chrome/common/extensions/extension_error_utils.h" |
18 #include "chrome/common/net/url_request_context_getter.h" | 16 #include "chrome/common/net/url_request_context_getter.h" |
19 #include "chrome/common/notification_type.h" | 17 #include "chrome/common/notification_type.h" |
20 #include "chrome/common/notification_service.h" | 18 #include "chrome/common/notification_service.h" |
21 #include "net/base/cookie_monster.h" | 19 #include "net/base/cookie_monster.h" |
22 | 20 |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
94 // Check against host permissions if needed. | 92 // Check against host permissions if needed. |
95 if (check_host_permissions && | 93 if (check_host_permissions && |
96 !GetExtension()->HasHostPermission(*url)) { | 94 !GetExtension()->HasHostPermission(*url)) { |
97 error_ = ExtensionErrorUtils::FormatErrorMessage( | 95 error_ = ExtensionErrorUtils::FormatErrorMessage( |
98 keys::kNoHostPermissionsError, url->spec()); | 96 keys::kNoHostPermissionsError, url->spec()); |
99 return false; | 97 return false; |
100 } | 98 } |
101 return true; | 99 return true; |
102 } | 100 } |
103 | 101 |
104 bool CookiesFunction::ParseStoreContext(const DictionaryValue* details, | 102 bool CookiesFunction::ParseCookieStore(const DictionaryValue* details, |
105 URLRequestContextGetter** context, | 103 net::CookieStore** store, |
106 std::string* store_id) { | 104 std::string* store_id) { |
107 DCHECK(details && (context || store_id)); | 105 DCHECK(details && (store || store_id)); |
108 Profile* store_profile = NULL; | 106 Profile* store_profile = NULL; |
109 if (details->HasKey(keys::kStoreIdKey)) { | 107 if (details->HasKey(keys::kStoreIdKey)) { |
110 // The store ID was explicitly specified in the details dictionary. | 108 // The store ID was explicitly specified in the details dictionary. |
111 // Retrieve its corresponding cookie store. | 109 // Retrieve its corresponding cookie store. |
112 std::string store_id_value; | 110 std::string store_id_value; |
113 // Get the store ID string or return false. | 111 // Get the store ID string or return false. |
114 EXTENSION_FUNCTION_VALIDATE( | 112 EXTENSION_FUNCTION_VALIDATE( |
115 details->GetString(keys::kStoreIdKey, &store_id_value)); | 113 details->GetString(keys::kStoreIdKey, &store_id_value)); |
116 store_profile = extension_cookies_helpers::ChooseProfileFromStoreId( | 114 store_profile = extension_cookies_helpers::ChooseProfileFromStoreId( |
117 store_id_value, profile(), include_incognito()); | 115 store_id_value, profile(), include_incognito()); |
118 if (!store_profile) { | 116 if (!store_profile) { |
119 error_ = ExtensionErrorUtils::FormatErrorMessage( | 117 error_ = ExtensionErrorUtils::FormatErrorMessage( |
120 keys::kInvalidStoreIdError, store_id_value); | 118 keys::kInvalidStoreIdError, store_id_value); |
121 return false; | 119 return false; |
122 } | 120 } |
123 } else { | 121 } else { |
124 // The store ID was not specified; use the current execution context's | 122 // The store ID was not specified; use the current execution context's |
125 // cookie store by default. | 123 // cookie store by default. |
126 // GetCurrentBrowser() already takes into account incognito settings. | 124 // GetCurrentBrowser() already takes into account incognito settings. |
127 Browser* current_browser = GetCurrentBrowser(); | 125 Browser* current_browser = GetCurrentBrowser(); |
128 if (!current_browser) { | 126 if (!current_browser) { |
129 error_ = keys::kNoCookieStoreFoundError; | 127 error_ = keys::kNoCookieStoreFoundError; |
130 return false; | 128 return false; |
131 } | 129 } |
132 store_profile = current_browser->profile(); | 130 store_profile = current_browser->profile(); |
133 } | 131 } |
134 DCHECK(store_profile); | 132 DCHECK(store_profile); |
135 | 133 if (store) |
136 if (context) | 134 *store = store_profile->GetRequestContext()->GetCookieStore(); |
137 *context = store_profile->GetRequestContext(); | |
138 if (store_id) | 135 if (store_id) |
139 *store_id = extension_cookies_helpers::GetStoreIdFromProfile(store_profile); | 136 *store_id = |
140 | 137 extension_cookies_helpers::GetStoreIdFromProfile(store_profile); |
141 return true; | 138 return true; |
142 } | 139 } |
143 | 140 |
144 GetCookieFunction::GetCookieFunction() {} | |
145 | |
146 bool GetCookieFunction::RunImpl() { | 141 bool GetCookieFunction::RunImpl() { |
147 // Return false if the arguments are malformed. | 142 // Return false if the arguments are malformed. |
148 DictionaryValue* details; | 143 DictionaryValue* details; |
149 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &details)); | 144 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &details)); |
150 DCHECK(details); | 145 DCHECK(details); |
151 | 146 |
152 // Read/validate input parameters. | 147 // Read/validate input parameters. |
153 if (!ParseUrl(details, &url_, true)) | 148 GURL url; |
| 149 if (!ParseUrl(details, &url, true)) |
154 return false; | 150 return false; |
155 | 151 |
| 152 std::string name; |
156 // Get the cookie name string or return false. | 153 // Get the cookie name string or return false. |
157 EXTENSION_FUNCTION_VALIDATE(details->GetString(keys::kNameKey, &name_)); | 154 EXTENSION_FUNCTION_VALIDATE(details->GetString(keys::kNameKey, &name)); |
158 | 155 |
159 URLRequestContextGetter* store_context = NULL; | 156 net::CookieStore* cookie_store; |
160 if (!ParseStoreContext(details, &store_context, &store_id_)) | 157 std::string store_id; |
| 158 if (!ParseCookieStore(details, &cookie_store, &store_id)) |
161 return false; | 159 return false; |
| 160 DCHECK(cookie_store && !store_id.empty()); |
162 | 161 |
163 DCHECK(store_context && !store_id_.empty()); | 162 net::CookieMonster::CookieList cookie_list = |
164 store_context_ = store_context; | 163 extension_cookies_helpers::GetCookieListFromStore(cookie_store, url); |
165 | 164 net::CookieMonster::CookieList::iterator it; |
166 bool rv = ChromeThread::PostTask( | 165 for (it = cookie_list.begin(); it != cookie_list.end(); ++it) { |
167 ChromeThread::IO, FROM_HERE, | 166 // Return the first matching cookie. Relies on the fact that the |
168 NewRunnableMethod(this, &GetCookieFunction::GetCookieOnIOThread)); | 167 // CookieMonster retrieves them in reverse domain-length order. |
169 DCHECK(rv); | 168 const net::CookieMonster::CanonicalCookie& cookie = it->second; |
170 | 169 if (cookie.Name() == name) { |
171 // Will finish asynchronously. | 170 result_.reset( |
| 171 extension_cookies_helpers::CreateCookieValue(*it, store_id)); |
| 172 return true; |
| 173 } |
| 174 } |
| 175 // The cookie doesn't exist; return null. |
| 176 result_.reset(Value::CreateNullValue()); |
172 return true; | 177 return true; |
173 } | 178 } |
174 | 179 |
175 void GetCookieFunction::GetCookieOnIOThread() { | |
176 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO)); | |
177 net::CookieStore* cookie_store = store_context_->GetCookieStore(); | |
178 cookie_list_ = | |
179 extension_cookies_helpers::GetCookieListFromStore(cookie_store, url_); | |
180 | |
181 bool rv = ChromeThread::PostTask( | |
182 ChromeThread::UI, FROM_HERE, | |
183 NewRunnableMethod(this, &GetCookieFunction::RespondOnUIThread)); | |
184 DCHECK(rv); | |
185 } | |
186 | |
187 void GetCookieFunction::RespondOnUIThread() { | |
188 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); | |
189 | |
190 net::CookieMonster::CookieList::iterator it; | |
191 for (it = cookie_list_.begin(); it != cookie_list_.end(); ++it) { | |
192 // Return the first matching cookie. Relies on the fact that the | |
193 // CookieMonster retrieves them in reverse domain-length order. | |
194 const net::CookieMonster::CanonicalCookie& cookie = it->second; | |
195 if (cookie.Name() == name_) { | |
196 result_.reset( | |
197 extension_cookies_helpers::CreateCookieValue(*it, store_id_)); | |
198 break; | |
199 } | |
200 } | |
201 | |
202 // The cookie doesn't exist; return null. | |
203 if (it == cookie_list_.end()) | |
204 result_.reset(Value::CreateNullValue()); | |
205 | |
206 SendResponse(true); | |
207 } | |
208 | |
209 GetAllCookiesFunction::GetAllCookiesFunction() {} | |
210 | |
211 bool GetAllCookiesFunction::RunImpl() { | 180 bool GetAllCookiesFunction::RunImpl() { |
212 // Return false if the arguments are malformed. | 181 // Return false if the arguments are malformed. |
213 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &details_)); | 182 DictionaryValue* details; |
214 DCHECK(details_); | 183 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &details)); |
| 184 DCHECK(details); |
215 | 185 |
216 // Read/validate input parameters. | 186 // Read/validate input parameters. |
217 if (details_->HasKey(keys::kUrlKey) && !ParseUrl(details_, &url_, false)) | 187 GURL url; |
| 188 if (details->HasKey(keys::kUrlKey) && !ParseUrl(details, &url, false)) |
218 return false; | 189 return false; |
219 | 190 |
220 URLRequestContextGetter* store_context = NULL; | 191 net::CookieStore* cookie_store; |
221 if (!ParseStoreContext(details_, &store_context, &store_id_)) | 192 std::string store_id; |
| 193 if (!ParseCookieStore(details, &cookie_store, &store_id)) |
222 return false; | 194 return false; |
223 DCHECK(store_context); | 195 DCHECK(cookie_store); |
224 store_context_ = store_context; | |
225 | 196 |
226 bool rv = ChromeThread::PostTask( | 197 ListValue* matching_list = new ListValue(); |
227 ChromeThread::IO, FROM_HERE, | 198 extension_cookies_helpers::AppendMatchingCookiesToList( |
228 NewRunnableMethod(this, &GetAllCookiesFunction::GetAllCookiesOnIOThread)); | 199 cookie_store, store_id, url, details, GetExtension(), matching_list); |
229 DCHECK(rv); | 200 result_.reset(matching_list); |
230 | |
231 // Will finish asynchronously. | |
232 return true; | 201 return true; |
233 } | 202 } |
234 | 203 |
235 void GetAllCookiesFunction::GetAllCookiesOnIOThread() { | |
236 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO)); | |
237 net::CookieStore* cookie_store = store_context_->GetCookieStore(); | |
238 cookie_list_ = | |
239 extension_cookies_helpers::GetCookieListFromStore(cookie_store, url_); | |
240 | |
241 bool rv = ChromeThread::PostTask( | |
242 ChromeThread::UI, FROM_HERE, | |
243 NewRunnableMethod(this, &GetAllCookiesFunction::RespondOnUIThread)); | |
244 DCHECK(rv); | |
245 } | |
246 | |
247 void GetAllCookiesFunction::RespondOnUIThread() { | |
248 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); | |
249 | |
250 const Extension* extension = GetExtension(); | |
251 if (extension) { | |
252 ListValue* matching_list = new ListValue(); | |
253 extension_cookies_helpers::AppendMatchingCookiesToList( | |
254 cookie_list_, store_id_, url_, details_, GetExtension(), matching_list); | |
255 result_.reset(matching_list); | |
256 } | |
257 SendResponse(true); | |
258 } | |
259 | |
260 SetCookieFunction::SetCookieFunction() : secure_(false), http_only_(false) {} | |
261 | |
262 bool SetCookieFunction::RunImpl() { | 204 bool SetCookieFunction::RunImpl() { |
263 // Return false if the arguments are malformed. | 205 // Return false if the arguments are malformed. |
264 DictionaryValue* details; | 206 DictionaryValue* details; |
265 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &details)); | 207 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &details)); |
266 DCHECK(details); | 208 DCHECK(details); |
267 | 209 |
268 // Read/validate input parameters. | 210 // Read/validate input parameters. |
269 if (!ParseUrl(details, &url_, true)) | 211 GURL url; |
| 212 if (!ParseUrl(details, &url, true)) |
270 return false; | 213 return false; |
271 // The macros below return false if argument types are not as expected. | 214 // The macros below return false if argument types are not as expected. |
272 if (details->HasKey(keys::kNameKey)) | 215 std::string name; |
273 EXTENSION_FUNCTION_VALIDATE(details->GetString(keys::kNameKey, &name_)); | 216 if (details->HasKey(keys::kNameKey)) { |
274 if (details->HasKey(keys::kValueKey)) | 217 EXTENSION_FUNCTION_VALIDATE(details->GetString(keys::kNameKey, &name)); |
275 EXTENSION_FUNCTION_VALIDATE(details->GetString(keys::kValueKey, &value_)); | 218 } |
276 if (details->HasKey(keys::kDomainKey)) | 219 std::string value; |
277 EXTENSION_FUNCTION_VALIDATE(details->GetString(keys::kDomainKey, &domain_)); | 220 if (details->HasKey(keys::kValueKey)) { |
278 if (details->HasKey(keys::kPathKey)) | 221 EXTENSION_FUNCTION_VALIDATE(details->GetString(keys::kValueKey, &value)); |
279 EXTENSION_FUNCTION_VALIDATE(details->GetString(keys::kPathKey, &path_)); | 222 } |
280 | 223 std::string domain; |
| 224 if (details->HasKey(keys::kDomainKey)) { |
| 225 EXTENSION_FUNCTION_VALIDATE(details->GetString(keys::kDomainKey, &domain)); |
| 226 } |
| 227 std::string path; |
| 228 if (details->HasKey(keys::kPathKey)) { |
| 229 EXTENSION_FUNCTION_VALIDATE(details->GetString(keys::kPathKey, &path)); |
| 230 } |
| 231 bool secure = false; |
281 if (details->HasKey(keys::kSecureKey)) { | 232 if (details->HasKey(keys::kSecureKey)) { |
282 EXTENSION_FUNCTION_VALIDATE( | 233 EXTENSION_FUNCTION_VALIDATE(details->GetBoolean(keys::kSecureKey, &secure)); |
283 details->GetBoolean(keys::kSecureKey, &secure_)); | |
284 } | 234 } |
| 235 bool http_only = false; |
285 if (details->HasKey(keys::kHttpOnlyKey)) { | 236 if (details->HasKey(keys::kHttpOnlyKey)) { |
286 EXTENSION_FUNCTION_VALIDATE( | 237 EXTENSION_FUNCTION_VALIDATE( |
287 details->GetBoolean(keys::kHttpOnlyKey, &http_only_)); | 238 details->GetBoolean(keys::kHttpOnlyKey, &http_only)); |
288 } | 239 } |
| 240 base::Time expiration_time; |
289 if (details->HasKey(keys::kExpirationDateKey)) { | 241 if (details->HasKey(keys::kExpirationDateKey)) { |
290 Value* expiration_date_value; | 242 Value* expiration_date_value; |
291 EXTENSION_FUNCTION_VALIDATE(details->Get(keys::kExpirationDateKey, | 243 EXTENSION_FUNCTION_VALIDATE(details->Get(keys::kExpirationDateKey, |
292 &expiration_date_value)); | 244 &expiration_date_value)); |
293 double expiration_date; | 245 double expiration_date; |
294 if (expiration_date_value->IsType(Value::TYPE_INTEGER)) { | 246 if (expiration_date_value->IsType(Value::TYPE_INTEGER)) { |
295 int expiration_date_int; | 247 int expiration_date_int; |
296 EXTENSION_FUNCTION_VALIDATE( | 248 EXTENSION_FUNCTION_VALIDATE( |
297 expiration_date_value->GetAsInteger(&expiration_date_int)); | 249 expiration_date_value->GetAsInteger(&expiration_date_int)); |
298 expiration_date = static_cast<double>(expiration_date_int); | 250 expiration_date = static_cast<double>(expiration_date_int); |
299 } else { | 251 } else { |
300 EXTENSION_FUNCTION_VALIDATE( | 252 EXTENSION_FUNCTION_VALIDATE( |
301 expiration_date_value->GetAsReal(&expiration_date)); | 253 expiration_date_value->GetAsReal(&expiration_date)); |
302 } | 254 } |
303 expiration_time_ = base::Time::FromDoubleT(expiration_date); | 255 expiration_time = base::Time::FromDoubleT(expiration_date); |
304 } | 256 } |
305 | 257 |
306 URLRequestContextGetter* store_context = NULL; | 258 net::CookieStore* cookie_store; |
307 if (!ParseStoreContext(details, &store_context, NULL)) | 259 if (!ParseCookieStore(details, &cookie_store, NULL)) |
308 return false; | 260 return false; |
309 DCHECK(store_context); | 261 DCHECK(cookie_store); |
310 store_context_ = store_context; | |
311 | 262 |
312 bool rv = ChromeThread::PostTask( | 263 if (!cookie_store->GetCookieMonster()->SetCookieWithDetails( |
313 ChromeThread::IO, FROM_HERE, | 264 url, name, value, domain, path, expiration_time, secure, |
314 NewRunnableMethod(this, &SetCookieFunction::SetCookieOnIOThread)); | 265 http_only)) { |
315 DCHECK(rv); | 266 error_ = ExtensionErrorUtils::FormatErrorMessage( |
316 | 267 keys::kCookieSetFailedError, name); |
317 // Will finish asynchronously. | 268 return false; |
| 269 } |
318 return true; | 270 return true; |
319 } | 271 } |
320 | 272 |
321 void SetCookieFunction::SetCookieOnIOThread() { | |
322 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO)); | |
323 net::CookieMonster* cookie_monster = | |
324 store_context_->GetCookieStore()->GetCookieMonster(); | |
325 success_ = cookie_monster->SetCookieWithDetails( | |
326 url_, name_, value_, domain_, path_, expiration_time_, | |
327 secure_, http_only_); | |
328 | |
329 bool rv = ChromeThread::PostTask( | |
330 ChromeThread::UI, FROM_HERE, | |
331 NewRunnableMethod(this, &SetCookieFunction::RespondOnUIThread)); | |
332 DCHECK(rv); | |
333 } | |
334 | |
335 void SetCookieFunction::RespondOnUIThread() { | |
336 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); | |
337 if (!success_) { | |
338 error_ = ExtensionErrorUtils::FormatErrorMessage( | |
339 keys::kCookieSetFailedError, name_); | |
340 } | |
341 SendResponse(success_); | |
342 } | |
343 | |
344 namespace { | |
345 | |
346 class RemoveCookieTask : public Task { | |
347 public: | |
348 RemoveCookieTask(const GURL& url, | |
349 const std::string& name, | |
350 const scoped_refptr<URLRequestContextGetter>& context_getter) | |
351 : url_(url), | |
352 name_(name), | |
353 context_getter_(context_getter) {} | |
354 | |
355 virtual void Run() { | |
356 net::CookieStore* cookie_store = context_getter_->GetCookieStore(); | |
357 cookie_store->DeleteCookie(url_, name_); | |
358 } | |
359 | |
360 private: | |
361 const GURL url_; | |
362 const std::string name_; | |
363 const scoped_refptr<URLRequestContextGetter> context_getter_; | |
364 | |
365 DISALLOW_COPY_AND_ASSIGN(RemoveCookieTask); | |
366 }; | |
367 | |
368 } // namespace | |
369 | |
370 bool RemoveCookieFunction::RunImpl() { | 273 bool RemoveCookieFunction::RunImpl() { |
371 // Return false if the arguments are malformed. | 274 // Return false if the arguments are malformed. |
372 DictionaryValue* details; | 275 DictionaryValue* details; |
373 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &details)); | 276 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &details)); |
374 DCHECK(details); | 277 DCHECK(details); |
375 | 278 |
376 // Read/validate input parameters. | 279 // Read/validate input parameters. |
377 GURL url; | 280 GURL url; |
378 if (!ParseUrl(details, &url, true)) | 281 if (!ParseUrl(details, &url, true)) |
379 return false; | 282 return false; |
380 | 283 |
381 std::string name; | 284 std::string name; |
382 // Get the cookie name string or return false. | 285 // Get the cookie name string or return false. |
383 EXTENSION_FUNCTION_VALIDATE(details->GetString(keys::kNameKey, &name)); | 286 EXTENSION_FUNCTION_VALIDATE(details->GetString(keys::kNameKey, &name)); |
384 | 287 |
385 URLRequestContextGetter* store_context = NULL; | 288 net::CookieStore* cookie_store; |
386 if (!ParseStoreContext(details, &store_context, NULL)) | 289 if (!ParseCookieStore(details, &cookie_store, NULL)) |
387 return false; | 290 return false; |
388 DCHECK(store_context); | 291 DCHECK(cookie_store); |
389 | 292 |
390 // We don't bother to synchronously wait for the result here, because | 293 cookie_store->DeleteCookie(url, name); |
391 // CookieMonster is only ever accessed on the IO thread, so any other accesses | |
392 // should happen after this. | |
393 bool rv = ChromeThread::PostTask( | |
394 ChromeThread::IO, FROM_HERE, | |
395 new RemoveCookieTask(url, name, store_context)); | |
396 DCHECK(rv); | |
397 | |
398 return true; | 294 return true; |
399 } | 295 } |
400 | 296 |
401 bool GetAllCookieStoresFunction::RunImpl() { | 297 bool GetAllCookieStoresFunction::RunImpl() { |
402 Profile* original_profile = profile()->GetOriginalProfile(); | 298 Profile* original_profile = profile()->GetOriginalProfile(); |
403 DCHECK(original_profile); | 299 DCHECK(original_profile); |
404 scoped_ptr<ListValue> original_tab_ids(new ListValue()); | 300 scoped_ptr<ListValue> original_tab_ids(new ListValue()); |
405 Profile* incognito_profile = NULL; | 301 Profile* incognito_profile = NULL; |
406 scoped_ptr<ListValue> incognito_tab_ids; | 302 scoped_ptr<ListValue> incognito_tab_ids; |
407 if (include_incognito()) { | 303 if (include_incognito()) { |
(...skipping 24 matching lines...) Expand all Loading... |
432 original_profile, original_tab_ids.release())); | 328 original_profile, original_tab_ids.release())); |
433 } | 329 } |
434 if (incognito_tab_ids.get() && incognito_tab_ids->GetSize() > 0) { | 330 if (incognito_tab_ids.get() && incognito_tab_ids->GetSize() > 0) { |
435 cookie_store_list->Append( | 331 cookie_store_list->Append( |
436 extension_cookies_helpers::CreateCookieStoreValue( | 332 extension_cookies_helpers::CreateCookieStoreValue( |
437 incognito_profile, incognito_tab_ids.release())); | 333 incognito_profile, incognito_tab_ids.release())); |
438 } | 334 } |
439 result_.reset(cookie_store_list); | 335 result_.reset(cookie_store_list); |
440 return true; | 336 return true; |
441 } | 337 } |
OLD | NEW |