Chromium Code Reviews
[email protected] (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(308)

Side by Side Diff: chrome/browser/android/download/ui/thumbnail_provider.cc

Issue 2294983002: [Download Home] Add image thumbnail support (Closed)
Patch Set: Missed the CC files in the GN system Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « chrome/browser/android/download/ui/thumbnail_provider.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2016 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.
4
5 #include "chrome/browser/android/download/ui/thumbnail_provider.h"
6
7 #include "base/android/jni_string.h"
8 #include "base/files/file_path.h"
9 #include "base/files/file_util.h"
10 #include "base/memory/weak_ptr.h"
11 #include "chrome/browser/image_decoder.h"
12 #include "content/public/browser/browser_thread.h"
13 #include "jni/ThumbnailProviderImpl_jni.h"
14 #include "skia/ext/image_operations.h"
15 #include "third_party/skia/include/core/SkBitmap.h"
16 #include "ui/gfx/android/java_bitmap.h"
17 #include "ui/gfx/skbitmap_operations.h"
18
19 class SkBitmap;
20
21 using base::android::JavaParamRef;
22
23 namespace {
24
25 // Ignore image files that are too large to avoid long delays.
26 const int64_t kMaxImageSize = 10 * 1024 * 1024; // 10 MB
27
28 class ImageThumbnailRequest : public ImageDecoder::ImageRequest {
29 public:
30 static void Create(int icon_size,
31 const std::string& file_path,
32 base::WeakPtr<ThumbnailProvider> weak_provider) {
33 DCHECK_CURRENTLY_ON(content::BrowserThread::FILE);
34 ImageThumbnailRequest* request =
35 new ImageThumbnailRequest(icon_size, file_path, weak_provider);
36 request->Start();
37 }
38
39 protected:
40 void OnImageDecoded(const SkBitmap& decoded_image) override {
41 DCHECK_CURRENTLY_ON(content::BrowserThread::FILE);
42
43 SkBitmap thumbnail = decoded_image;
44 if (!decoded_image.drawsNothing()) {
45 // Shrink the image down so that its smallest dimension is equal to or
46 // smaller than the requested size.
47 int min_dimension =
48 std::min(decoded_image.width(), decoded_image.height());
49
50 if (min_dimension > icon_size_) {
51 uint64_t width = static_cast<uint64_t>(decoded_image.width());
52 uint64_t height = static_cast<uint64_t>(decoded_image.height());
53 thumbnail = skia::ImageOperations::Resize(
54 decoded_image, skia::ImageOperations::RESIZE_BEST,
55 width * icon_size_ / min_dimension,
56 height * icon_size_ / min_dimension);
57 }
58 }
59
60 FinishRequest(thumbnail);
61 }
62
63 void OnDecodeImageFailed() override {
64 LOG(ERROR) << "Failed to decode image: " << file_path_;
65 FinishRequest(SkBitmap());
66 }
67
68 private:
69 ImageThumbnailRequest(int icon_size,
70 const std::string& file_path,
71 base::WeakPtr<ThumbnailProvider> weak_provider)
72 : icon_size_(icon_size),
73 file_path_(file_path),
74 weak_provider_(weak_provider) {}
75
76 void Start() {
77 DCHECK_CURRENTLY_ON(content::BrowserThread::FILE);
78
79 // Confirm that the file's size is within our threshold.
80 int64_t file_size;
81 base::FilePath path = base::FilePath::FromUTF8Unsafe(file_path_);
82 if (!base::GetFileSize(path, &file_size) || file_size > kMaxImageSize) {
83 LOG(ERROR) << "Unexpected file size: " << file_path_ << ", " << file_size;
84 FinishRequest(SkBitmap());
85 }
86
87 // Make sure the file isn't empty.
88 std::string data;
89 bool success = base::ReadFileToString(path, &data);
90 if (!success || data.empty()) {
91 LOG(ERROR) << "Failed to read file: " << file_path_;
92 FinishRequest(SkBitmap());
93 }
94
95 ImageDecoder::Start(this, data);
96 }
97
98 void FinishRequest(const SkBitmap& thumbnail) {
99 DCHECK_CURRENTLY_ON(content::BrowserThread::FILE);
100
101 content::BrowserThread::PostTask(
102 content::BrowserThread::UI, FROM_HERE,
103 base::Bind(&ThumbnailProvider::OnThumbnailRetrieved,
104 weak_provider_, file_path_, thumbnail));
105 task_runner()->DeleteSoon(FROM_HERE, this);
106 }
107
108 const int icon_size_;
109 std::string file_path_;
110 base::WeakPtr<ThumbnailProvider> weak_provider_;
111
112 DISALLOW_IMPLICIT_CONSTRUCTORS(ImageThumbnailRequest);
113 };
114
115 } // namespace
116
117 ThumbnailProvider::ThumbnailProvider(const JavaParamRef<jobject>& jobj)
118 : java_delegate_(jobj), weak_factory_(this) {}
119
120 ThumbnailProvider::~ThumbnailProvider() {
121 java_delegate_.Reset();
122 }
123
124 void ThumbnailProvider::Destroy(JNIEnv* env,
125 const JavaParamRef<jobject>& jobj) {
126 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
127 delete this;
128 }
129
130 void ThumbnailProvider::OnThumbnailRetrieved(const std::string& file_path,
131 const SkBitmap& thumbnail) {
132 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
133
134 if (java_delegate_.is_null())
135 return;
136
137 // Send the bitmap back to Java-land.
138 JNIEnv* env = base::android::AttachCurrentThread();
139 Java_ThumbnailProviderImpl_onThumbnailRetrieved(
140 env, java_delegate_,
141 base::android::ConvertUTF8ToJavaString(env, file_path),
142 gfx::ConvertToJavaBitmap(&thumbnail));
143 }
144
145 void ThumbnailProvider::RetrieveThumbnail(JNIEnv* env,
146 const JavaParamRef<jobject>& jobj,
147 jstring jfile_path,
148 jint icon_size) {
149 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
150
151 // The ImageThumbnailRequest deletes itself on completion. Don't track it
152 // because we don't (currently) cancel it.
153 std::string path = base::android::ConvertJavaStringToUTF8(env, jfile_path);
154 content::BrowserThread::PostTask(
155 content::BrowserThread::FILE, FROM_HERE,
156 base::Bind(&ImageThumbnailRequest::Create, icon_size, path,
157 weak_factory_.GetWeakPtr()));
158 }
159
160 // static
161 bool ThumbnailProvider::RegisterThumbnailProvider(JNIEnv* env) {
162 return RegisterNativesImpl(env);
163 }
164
165 // static
166 static jlong Init(JNIEnv* env, const JavaParamRef<jobject>& jobj) {
167 return reinterpret_cast<intptr_t>(new ThumbnailProvider(jobj));
168 }
OLDNEW
« no previous file with comments | « chrome/browser/android/download/ui/thumbnail_provider.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698