Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(292)

Side by Side Diff: chrome/browser/extensions/clipboard_extension_helper.cc

Issue 2379573008: Add SetImageData api to chrome.clipboard. (Closed)
Patch Set: Address code review comments and add test cases. Created 4 years 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/extensions/clipboard_extension_helper.h"
6
7 #include "base/macros.h"
8 #include "base/metrics/histogram_macros.h"
9 #include "base/synchronization/cancellation_flag.h"
10 #include "chrome/browser/image_decoder.h"
11 #include "extensions/browser/api/clipboard/clipboard_api.h"
12 #include "ui/base/clipboard/scoped_clipboard_writer.h"
13
14 using content::BrowserThread;
15
16 namespace extensions {
17
18 class ClipboardExtensionHelper::ClipboardImageDataDecoder
19 : public ImageDecoder::ImageRequest {
20 public:
21 explicit ClipboardImageDataDecoder(
22 const base::WeakPtr<ClipboardExtensionHelper>& owner)
23 : owner_(owner) {}
24
25 void Start(const std::vector<char>& image_data, clipboard::ImageType type) {
26 DCHECK_CURRENTLY_ON(BrowserThread::UI);
27 std::string image_data_str(image_data.begin(), image_data.end());
28
29 ImageDecoder::ImageCodec codec = ImageDecoder::DEFAULT_CODEC;
30 #if defined(OS_CHROMEOS)
Devlin 2016/12/09 15:23:43 Is this API only supported on CrOS? If so, can't
jennyz 2016/12/14 01:15:36 Yes, this API is Cros-only, I made a couple of cha
31 if (type == clipboard::IMAGE_TYPE_PNG) {
Devlin 2016/12/09 15:23:43 prefer a switch
jennyz 2016/12/14 01:15:35 Done.
32 codec = ImageDecoder::ROBUST_PNG_CODEC;
33 } else if (type == clipboard::IMAGE_TYPE_JPEG) {
34 codec = ImageDecoder::ROBUST_JPEG_CODEC;
35 } else {
36 OnDecodeImageFailed();
37 return;
38 }
39 #endif
40
41 ImageDecoder::StartWithOptions(this, image_data_str, codec, true);
42 }
43
44 void Cancel() {
Devlin 2016/12/09 15:23:48 Shouldn't we also call ImageDecoder::Cancel()?
jennyz 2016/12/14 01:15:35 Yes, good suggestion. Now I changed to call ImageD
45 cancel_flag_.Set();
46 if (owner_)
47 owner_->OnImageDecodeCancel();
48 }
49
50 void OnImageDecoded(const SkBitmap& decoded_image) override {
51 if (!cancel_flag_.IsSet() && owner_)
Devlin 2016/12/09 15:23:45 If we *do* want this approach, instead of doing th
jennyz 2016/12/14 01:15:35 Changed to use unique_ptr to manage the life cycle
52 owner_->OnImageDecoded(decoded_image);
53 delete this;
54 }
55
56 void OnDecodeImageFailed() override {
57 if (!cancel_flag_.IsSet() && owner_)
58 owner_->OnImageDecodeFailure();
59 delete this;
60 }
61
62 private:
63 ~ClipboardImageDataDecoder() override {}
64 base::WeakPtr<ClipboardExtensionHelper> owner_;
Devlin 2016/12/09 15:23:48 What was wrong with dcheng's suggestion to have th
jennyz 2016/12/14 01:15:36 Yes, changed to use unique_ptr to manage the lifet
65 base::CancellationFlag cancel_flag_;
66
67 DISALLOW_COPY_AND_ASSIGN(ClipboardImageDataDecoder);
68 };
69
70 ClipboardExtensionHelper::ClipboardImageDataDecoder*
71 ClipboardExtensionHelper::clipboard_image_data_decoder_;
72
73 ClipboardExtensionHelper::ClipboardExtensionHelper()
74 : clipboard_writer_(
75 new ui::ScopedClipboardWriter(ui::CLIPBOARD_TYPE_COPY_PASTE)),
76 weak_factory_(this) {}
77
78 ClipboardExtensionHelper::~ClipboardExtensionHelper() {}
79
80 void ClipboardExtensionHelper::DecodeAndSaveImageData(
81 const std::vector<char>& data,
82 api::clipboard::ImageType type,
83 const base::Closure& success_callback,
84 const base::Closure& error_callback) {
85 DCHECK_CURRENTLY_ON(BrowserThread::UI);
86
87 // If there is a previous image decoding request still running, cancel it
88 // first. We only need the most recent image save request be completed.
89 if (clipboard_image_data_decoder_)
90 clipboard_image_data_decoder_->Cancel();
Devlin 2016/12/09 15:23:47 So only one item can be using the decode api at an
jennyz 2016/12/14 01:15:35 The clipboard can only save one image from the Set
91
92 // clipboard_image_data_decoder_ will manage its own lifetime.
93 clipboard_image_data_decoder_ = new ClipboardImageDataDecoder(
94 weak_factory_.GetWeakPtr());
95 image_save_success_callback_ = success_callback;
96 image_save_error_callback_ = error_callback;
97 clipboard_image_data_decoder_->Start(data, type);
98 }
99
100 void ClipboardExtensionHelper::OnImageDecodeFailure() {
101 clipboard_image_data_decoder_ = nullptr;
102 image_save_error_callback_.Run();
Devlin 2016/12/09 15:23:46 prefer using base::ResetAndReturn or a OnceCallbac
jennyz 2016/12/14 01:15:35 Done.
103 }
104
105 void ClipboardExtensionHelper::OnImageDecoded(const SkBitmap& bitmap) {
106 clipboard_image_data_decoder_ = nullptr;
107
108 // Write the decoded image data to clipboard.
109 if (!bitmap.empty() && !bitmap.isNull())
110 clipboard_writer_->WriteImage(bitmap);
111 clipboard_writer_.reset(
112 new ui::ScopedClipboardWriter(ui::CLIPBOARD_TYPE_COPY_PASTE));
113
114 image_save_success_callback_.Run();
115 }
116
117 void ClipboardExtensionHelper::OnImageDecodeCancel() {
118 image_save_error_callback_.Run();
119 }
120
121 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698