12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright 2012 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "components/webdata/common/web_data_request_manager.h"
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/bind.h"
89ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h"
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/stl_util.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// WebDataRequest implementation.
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)WebDataRequest::WebDataRequest(WebDataServiceConsumer* consumer,
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                               WebDataRequestManager* manager)
197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    : manager_(manager), cancelled_(false), consumer_(consumer) {
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  handle_ = manager_->GetNextRequestHandle();
21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  message_loop_ = base::MessageLoop::current();
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  manager_->RegisterRequest(this);
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)WebDataRequest::~WebDataRequest() {
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (manager_) {
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    manager_->CancelRequest(handle_);
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (result_.get()) {
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    result_->Destroy();
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)WebDataServiceBase::Handle WebDataRequest::GetHandle() const {
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return handle_;
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)WebDataServiceConsumer* WebDataRequest::GetConsumer() const {
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return consumer_;
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
42868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)base::MessageLoop* WebDataRequest::GetMessageLoop() const {
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return message_loop_;
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool WebDataRequest::IsCancelled() const {
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::AutoLock l(cancel_lock_);
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return cancelled_;
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void WebDataRequest::Cancel() {
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::AutoLock l(cancel_lock_);
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  cancelled_ = true;
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  consumer_ = NULL;
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  manager_ = NULL;
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void WebDataRequest::OnComplete() {
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  manager_= NULL;
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void WebDataRequest::SetResult(scoped_ptr<WDTypedResult> r) {
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  result_ = r.Pass();
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_ptr<WDTypedResult> WebDataRequest::GetResult(){
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return result_.Pass();
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// WebDataRequestManager implementation.
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)WebDataRequestManager::WebDataRequestManager()
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : next_request_handle_(1) {
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)WebDataRequestManager::~WebDataRequestManager() {
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::AutoLock l(pending_lock_);
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (RequestMap::iterator i = pending_requests_.begin();
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       i != pending_requests_.end(); ++i) {
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    i->second->Cancel();
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  pending_requests_.clear();
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void WebDataRequestManager::RegisterRequest(WebDataRequest* request) {
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::AutoLock l(pending_lock_);
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  pending_requests_[request->GetHandle()] = request;
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int WebDataRequestManager::GetNextRequestHandle() {
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::AutoLock l(pending_lock_);
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return ++next_request_handle_;
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void WebDataRequestManager::CancelRequest(WebDataServiceBase::Handle h) {
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::AutoLock l(pending_lock_);
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RequestMap::iterator i = pending_requests_.find(h);
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (i == pending_requests_.end()) {
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    NOTREACHED() << "Canceling a nonexistent web data service request";
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  i->second->Cancel();
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  pending_requests_.erase(i);
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void WebDataRequestManager::RequestCompleted(
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<WebDataRequest> request) {
112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::MessageLoop* loop = request->GetMessageLoop();
113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  loop->PostTask(FROM_HERE,
114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Bind(&WebDataRequestManager::RequestCompletedOnThread,
115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                            this,
116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                            base::Passed(&request)));
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void WebDataRequestManager::RequestCompletedOnThread(
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<WebDataRequest> request) {
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (request->IsCancelled())
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::AutoLock l(pending_lock_);
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    RequestMap::iterator i = pending_requests_.find(request->GetHandle());
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (i == pending_requests_.end()) {
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      NOTREACHED() << "Request completed called for an unknown request";
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return;
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Take ownership of the request object and remove it from the map.
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    pending_requests_.erase(i);
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Notify the consumer if needed.
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!request->IsCancelled()) {
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    WebDataServiceConsumer* consumer = request->GetConsumer();
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    request->OnComplete();
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (consumer) {
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      scoped_ptr<WDTypedResult> r = request->GetResult();
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      consumer->OnWebDataServiceRequestDone(request->GetHandle(), r.get());
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
146