1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/android/popular_sites.h"
8 #include "base/files/file_path.h"
9 #include "base/files/file_util.h"
10 #include "base/json/json_reader.h"
11 #include "base/path_service.h"
12 #include "base/strings/stringprintf.h"
13 #include "base/task_runner_util.h"
14 #include "base/values.h"
15 #include "chrome/browser/net/file_downloader.h"
16 #include "chrome/common/chrome_paths.h"
17 #include "content/public/browser/browser_thread.h"
19 using content::BrowserThread
;
23 const char kPopularSitesURLFormat
[] = "https://www.gstatic.com/chrome/ntp/%s";
24 const char kPopularSitesDefaultFilename
[] = "suggested_sites_IN_1.json";
26 std::string
GetPopularSitesFilename(const std::string
& filename
) {
27 return filename
.empty() ? kPopularSitesDefaultFilename
: filename
.c_str();
30 base::FilePath
GetPopularSitesPath(const std::string
& filename
) {
32 PathService::Get(chrome::DIR_USER_DATA
, &dir
);
33 return dir
.AppendASCII(GetPopularSitesFilename(filename
));
36 GURL
GetPopularSitesURL(const std::string
& filename
) {
37 return GURL(base::StringPrintf(kPopularSitesURLFormat
,
38 GetPopularSitesFilename(filename
).c_str()));
41 scoped_ptr
<std::vector
<PopularSites::Site
>> ReadAndParseJsonFile(
42 const base::FilePath
& path
) {
44 if (!base::ReadFileToString(path
, &json
)) {
45 DLOG(WARNING
) << "Failed reading file";
49 scoped_ptr
<base::Value
> value
=
50 base::JSONReader::Read(json
, base::JSON_ALLOW_TRAILING_COMMAS
);
51 base::ListValue
* list
;
52 if (!value
|| !value
->GetAsList(&list
)) {
53 DLOG(WARNING
) << "Failed parsing json";
57 scoped_ptr
<std::vector
<PopularSites::Site
>> sites(
58 new std::vector
<PopularSites::Site
>);
59 for (size_t i
= 0; i
< list
->GetSize(); i
++) {
60 base::DictionaryValue
* item
;
61 if (!list
->GetDictionary(i
, &item
))
65 if (!item
->GetString("title", &title
) || !item
->GetString("url", &url
))
67 std::string favicon_url
;
68 item
->GetString("favicon_url", &favicon_url
);
69 sites
->push_back(PopularSites::Site(title
, GURL(url
), GURL(favicon_url
)));
77 PopularSites::Site::Site(const base::string16
& title
,
79 const GURL
& favicon_url
)
80 : title(title
), url(url
), favicon_url(favicon_url
) {}
82 PopularSites::PopularSites(const std::string
& filename
,
83 net::URLRequestContextGetter
* request_context
,
84 const FinishedCallback
& callback
)
85 : callback_(callback
), weak_ptr_factory_(this) {
86 base::FilePath path
= GetPopularSitesPath(filename
);
87 downloader_
.reset(new FileDownloader(
88 GetPopularSitesURL(filename
), path
, request_context
,
89 base::Bind(&PopularSites::OnDownloadDone
, base::Unretained(this), path
)));
92 PopularSites::~PopularSites() {}
94 void PopularSites::OnDownloadDone(const base::FilePath
& path
, bool success
) {
96 base::PostTaskAndReplyWithResult(
97 BrowserThread::GetBlockingPool()->GetTaskRunnerWithShutdownBehavior(
98 base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN
).get(),
100 base::Bind(&ReadAndParseJsonFile
, path
),
101 base::Bind(&PopularSites::OnJsonParsed
,
102 weak_ptr_factory_
.GetWeakPtr()));
104 DLOG(WARNING
) << "Download failed";
105 callback_
.Run(false);
111 void PopularSites::OnJsonParsed(scoped_ptr
<std::vector
<Site
>> sites
) {
116 callback_
.Run(!!sites
);