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

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

Issue 2294983002: [Download Home] Add image thumbnail support (Closed)
Patch Set: Changed how the image is resized 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
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 ImageThumbnailRequest(int icon_size,
31 const std::string& file_path,
32 base::WeakPtr<ThumbnailProvider> weak_provider)
33 : icon_size_(icon_size),
34 file_path_(file_path),
35 weak_provider_(weak_provider) {
36 }
37
38 void Start() {
39 if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE)) {
Ted C 2016/08/31 00:34:35 let's pull this out to a separate function and mak
gone 2016/08/31 01:35:04 Turns out you can force all of this to be on the F
40 content::BrowserThread::PostTask(
41 content::BrowserThread::FILE,
42 FROM_HERE,
43 base::Bind(&ImageThumbnailRequest::Start, base::Unretained(this)));
44 return;
45 }
46
47 // Re-check the file's size because it may have changed.
Ted C 2016/08/31 00:34:34 I think "// Ensure the file does not exceed our ma
gone 2016/08/31 01:35:04 Did some variant of this sentence.
48 int64_t file_size;
49 base::FilePath path = base::FilePath::FromUTF8Unsafe(file_path_);
50 if (!base::GetFileSize(path, &file_size) ||
51 file_size > kMaxImageSize) {
52 LOG(ERROR) << "Unexpected file size: " << file_path_ << ", " << file_size;
53 FinishRequest(SkBitmap());
54 }
55
56 // Make sure the file isn't empty.
57 std::string data;
58 bool success = base::ReadFileToString(path, &data);
59 if (!success || data.empty()) {
60 LOG(ERROR) << "Failed to read file: " << file_path_;
61 FinishRequest(SkBitmap());
62 }
63
64 ImageDecoder::Start(this, data);
65 }
66
67 void OnImageDecoded(const SkBitmap& decoded_image) override {
68 SkBitmap thumbnail = decoded_image;
69 if (!decoded_image.drawsNothing()) {
70 // Shrink the image down so that its smallest dimension is within range.
71 int min_dimension = std::min(decoded_image.width(),
72 decoded_image.height());
73
74 if (min_dimension > icon_size_) {
75 uint64_t width = static_cast<uint64_t>(decoded_image.width());
76 uint64_t height = static_cast<uint64_t>(decoded_image.height());
77 thumbnail = skia::ImageOperations::Resize(
Ted C 2016/08/31 00:34:35 it'd be nice to not do this on the UI thread...don
gone 2016/08/31 01:35:04 Done.
78 decoded_image,
Ted C 2016/08/31 00:34:34 this looks wonky to me. I think it should be 4 fr
gone 2016/08/31 01:35:04 Actually ran git cl format this time.
79 skia::ImageOperations::RESIZE_BEST,
80 width * icon_size_ / min_dimension,
81 height * icon_size_ / min_dimension);
82 }
83 }
84
85 FinishRequest(thumbnail);
86 }
87
88 void OnDecodeImageFailed() override {
89 LOG(ERROR) << "Failed to decode image: " << file_path_;
90 FinishRequest(SkBitmap());
91 }
92
93 private:
94 void FinishRequest(const SkBitmap& thumbnail) {
95 if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)) {
96 content::BrowserThread::PostTask(
Ted C 2016/08/31 00:34:35 ideally the same comment as above and have anyone
gone 2016/08/31 01:35:04 Done.
97 content::BrowserThread::UI,
98 FROM_HERE,
99 base::Bind(&ImageThumbnailRequest::FinishRequest,
100 base::Unretained(this), thumbnail));
101 return;
102 }
103
104 if (weak_provider_)
105 weak_provider_->OnThumbnailRetrieved(file_path_, thumbnail);
106 task_runner()->DeleteSoon(FROM_HERE, this);
107 }
108
109 const int icon_size_;
110 std::string file_path_;
111 base::WeakPtr<ThumbnailProvider> weak_provider_;
112
113 DISALLOW_IMPLICIT_CONSTRUCTORS(ImageThumbnailRequest);
114 };
115
116 } // namespace
117
118 ThumbnailProvider::ThumbnailProvider(const JavaParamRef<jobject>& jobj,
119 int icon_size)
120 : java_delegate_(jobj),
121 weak_factory_(this) {
122 }
123
124 ThumbnailProvider::~ThumbnailProvider() {
125 java_delegate_.Reset();
126 weak_factory_.InvalidateWeakPtrs();
Ted C 2016/08/31 00:34:35 This happens as a result of destructing the WeakPt
gone 2016/08/31 01:35:04 Done.
127 }
128
129 void ThumbnailProvider::Destroy(JNIEnv* env,
130 const JavaParamRef<jobject>& jobj) {
131 delete this;
132 }
133
134 void ThumbnailProvider::OnThumbnailRetrieved(const std::string& file_path,
135 const SkBitmap& thumbnail) {
136 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
137
138 if (java_delegate_.is_null())
139 return;
140
141 // Send the bitmap back to Java-land.
142 JNIEnv* env = base::android::AttachCurrentThread();
143 Java_ThumbnailProviderImpl_onThumbnailRetrieved(
144 env,
145 java_delegate_,
146 base::android::ConvertUTF8ToJavaString(env, file_path),
147 gfx::ConvertToJavaBitmap(&thumbnail));
148 }
149
150 void ThumbnailProvider::RetrieveThumbnail(JNIEnv* env,
151 const JavaParamRef<jobject>& jobj,
152 jstring file_path,
153 jint icon_size) {
154 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
155
156 // The ImageThumbnailRequest deletes itself on completion.
157 std::string path = base::android::ConvertJavaStringToUTF8(env, file_path);
158 ImageThumbnailRequest* request = new ImageThumbnailRequest(
159 icon_size, path, weak_factory_.GetWeakPtr());
160 request->Start();
161 }
162
163 // static
164 bool ThumbnailProvider::RegisterJNI(JNIEnv* env) {
165 return RegisterNativesImpl(env);
166 }
167
168 // static
169 static jlong Init(JNIEnv* env,
170 const JavaParamRef<jobject>& jobj,
171 int icon_size) {
172 return reinterpret_cast<intptr_t>(new ThumbnailProvider(jobj, icon_size));
173 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698