1 // Copyright 2014 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/ui/webui/chromeos/image_source.h"
10 #include "base/files/file_util.h"
11 #include "base/location.h"
12 #include "base/memory/ref_counted_memory.h"
13 #include "base/sequenced_task_runner.h"
14 #include "base/single_thread_task_runner.h"
15 #include "base/thread_task_runner_handle.h"
16 #include "chrome/browser/chromeos/login/users/avatar/user_image_loader.h"
17 #include "chrome/common/url_constants.h"
18 #include "components/user_manager/user_image/user_image.h"
19 #include "content/public/browser/browser_thread.h"
20 #include "net/base/mime_util.h"
22 using content::BrowserThread
;
27 const char* kWhitelistedDirectories
[] = {
31 // Callback for user_manager::UserImageLoader.
33 const content::URLDataSource::GotDataCallback
& got_data_callback
,
34 const user_manager::UserImage
& user_image
) {
35 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
37 if (user_image
.has_raw_image())
38 got_data_callback
.Run(new base::RefCountedBytes(user_image
.raw_image()));
40 got_data_callback
.Run(NULL
);
43 // Looks for the image at |path| under the shared assets directory.
44 void StartOnBlockingPool(
45 const std::string
& path
,
46 scoped_refptr
<UserImageLoader
> image_loader
,
47 const content::URLDataSource::GotDataCallback
& got_data_callback
,
48 scoped_refptr
<base::SingleThreadTaskRunner
> thread_task_runner
) {
49 DCHECK(BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread());
51 const base::FilePath
asset_dir(FILE_PATH_LITERAL(chrome::kChromeOSAssetPath
));
52 const base::FilePath image_path
= asset_dir
.AppendASCII(path
);
53 if (base::PathExists(image_path
)) {
54 image_loader
->Start(image_path
.value(), 0,
55 base::Bind(&ImageLoaded
, got_data_callback
));
57 thread_task_runner
->PostTask(FROM_HERE
,
58 base::Bind(got_data_callback
, nullptr));
64 ImageSource::ImageSource() : weak_factory_(this) {
65 base::SequencedWorkerPool
* blocking_pool
=
66 BrowserThread::GetBlockingPool();
67 task_runner_
= blocking_pool
->GetSequencedTaskRunnerWithShutdownBehavior(
68 blocking_pool
->GetSequenceToken(),
69 base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN
);
72 ImageSource::~ImageSource() {
75 std::string
ImageSource::GetSource() const {
76 return chrome::kChromeOSAssetHost
;
79 void ImageSource::StartDataRequest(
80 const std::string
& path
,
81 int render_process_id
,
83 const content::URLDataSource::GotDataCallback
& got_data_callback
) {
84 if (!IsWhitelisted(path
)) {
85 got_data_callback
.Run(NULL
);
90 image_loader_
= new UserImageLoader(ImageDecoder::DEFAULT_CODEC
,
94 content::BrowserThread::GetBlockingPool()->PostTask(
96 base::Bind(&StartOnBlockingPool
,
100 base::ThreadTaskRunnerHandle::Get()));
103 std::string
ImageSource::GetMimeType(const std::string
& path
) const {
104 std::string mime_type
;
105 std::string ext
= base::FilePath(path
).Extension();
107 net::GetWellKnownMimeTypeFromExtension(ext
.substr(1), &mime_type
);
111 bool ImageSource::IsWhitelisted(const std::string
& path
) const {
112 base::FilePath
file_path(path
);
113 if (file_path
.ReferencesParent())
116 // Check if the path starts with a whitelisted directory.
117 std::vector
<std::string
> components
;
118 file_path
.GetComponents(&components
);
119 if (components
.empty())
122 for (size_t i
= 0; i
< arraysize(kWhitelistedDirectories
); i
++) {
123 if (components
[0] == kWhitelistedDirectories
[i
])
129 } // namespace chromeos