190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// found in the LICENSE file. 490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 5424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "chrome/browser/ui/app_list/search/common/json_response_fetcher.h" 690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/bind.h" 890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/values.h" 990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/safe_json_parser.h" 1090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "net/base/load_flags.h" 1190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "net/url_request/url_fetcher.h" 1290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "net/url_request/url_request_status.h" 13424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "url/gurl.h" 1490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 1590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)namespace app_list { 1690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 17424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)const char kBadResponse[] = "Bad Web Service search response"; 1890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 19424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)JSONResponseFetcher::JSONResponseFetcher( 2090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const Callback& callback, 2190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) net::URLRequestContextGetter* context_getter) 2290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) : callback_(callback), 2390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) context_getter_(context_getter), 2490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) weak_factory_(this) { 2590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(!callback_.is_null()); 2690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 2790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 28424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)JSONResponseFetcher::~JSONResponseFetcher() {} 2990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 30424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void JSONResponseFetcher::Start(const GURL& query_url) { 3190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) Stop(); 3290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 3390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) fetcher_.reset(net::URLFetcher::Create( 34424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) query_url, 3590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) net::URLFetcher::GET, 3690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) this)); 3790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) fetcher_->SetRequestContext(context_getter_); 3890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SAVE_COOKIES | 3990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) net::LOAD_DISABLE_CACHE); 4090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) fetcher_->Start(); 4190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 4290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 43424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void JSONResponseFetcher::Stop() { 4490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) fetcher_.reset(); 4590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) weak_factory_.InvalidateWeakPtrs(); 4690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 4790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 48424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void JSONResponseFetcher::OnJsonParseSuccess( 4990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<base::Value> parsed_json) { 5090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!parsed_json->IsType(base::Value::TYPE_DICTIONARY)) { 5190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) OnJsonParseError(kBadResponse); 5290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return; 5390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 5490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 5590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) callback_.Run(make_scoped_ptr( 5690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) static_cast<base::DictionaryValue*>(parsed_json.release()))); 5790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 5890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 59424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void JSONResponseFetcher::OnJsonParseError(const std::string& error) { 6090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) callback_.Run(scoped_ptr<base::DictionaryValue>()); 6190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 6290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 63424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void JSONResponseFetcher::OnURLFetchComplete( 64424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const net::URLFetcher* source) { 6590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CHECK_EQ(fetcher_.get(), source); 6690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 6790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<net::URLFetcher> fetcher(fetcher_.Pass()); 6890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 6990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!fetcher->GetStatus().is_success() || 7090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) fetcher->GetResponseCode() != 200) { 7190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) OnJsonParseError(kBadResponse); 7290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return; 7390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 7490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 7558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) std::string json_data; 7658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) fetcher->GetResponseAsString(&json_data); 7790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 7890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_refptr<SafeJsonParser> parser = 7958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) new SafeJsonParser(json_data, 80424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) base::Bind( 81424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) &JSONResponseFetcher::OnJsonParseSuccess, 82424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) weak_factory_.GetWeakPtr()), 83424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) base::Bind( 84424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) &JSONResponseFetcher::OnJsonParseError, 85424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) weak_factory_.GetWeakPtr())); 8690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // The parser will call us back via one of the callbacks. 8790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) parser->Start(); 8890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 8990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 9090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} // namespace app_list 91