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

Side by Side Diff: ui/base/clipboard/clipboard.cc

Issue 740763003: Reland rewrite clipboard write IPC handling to be easier to understand. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Formatted Created 6 years, 1 month 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 | « ui/base/clipboard/clipboard.h ('k') | ui/base/clipboard/clipboard_test_template.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ui/base/clipboard/clipboard.h" 5 #include "ui/base/clipboard/clipboard.h"
6 6
7 #include <iterator> 7 #include <iterator>
8 #include <limits> 8 #include <limits>
9 9
10 #include "base/logging.h" 10 #include "base/logging.h"
11 #include "base/memory/scoped_ptr.h" 11 #include "base/memory/scoped_ptr.h"
12 #include "third_party/skia/include/core/SkBitmap.h" 12 #include "third_party/skia/include/core/SkBitmap.h"
13 #include "ui/gfx/size.h" 13 #include "ui/gfx/size.h"
14 14
15 namespace ui { 15 namespace ui {
16 16
17 namespace {
18
19 // Valides a shared bitmap on the clipboard.
20 // Returns true if the clipboard data makes sense and it's safe to access the
21 // bitmap.
22 bool ValidateAndMapSharedBitmap(size_t bitmap_bytes,
23 base::SharedMemory* bitmap_data) {
24 using base::SharedMemory;
25
26 if (!bitmap_data || !SharedMemory::IsHandleValid(bitmap_data->handle()))
27 return false;
28
29 if (!bitmap_data->Map(bitmap_bytes)) {
30 PLOG(ERROR) << "Failed to map bitmap memory";
31 return false;
32 }
33 return true;
34 }
35
36 } // namespace
37
38 base::LazyInstance<Clipboard::AllowedThreadsVector> 17 base::LazyInstance<Clipboard::AllowedThreadsVector>
39 Clipboard::allowed_threads_ = LAZY_INSTANCE_INITIALIZER; 18 Clipboard::allowed_threads_ = LAZY_INSTANCE_INITIALIZER;
40 base::LazyInstance<Clipboard::ClipboardMap> Clipboard::clipboard_map_ = 19 base::LazyInstance<Clipboard::ClipboardMap> Clipboard::clipboard_map_ =
41 LAZY_INSTANCE_INITIALIZER; 20 LAZY_INSTANCE_INITIALIZER;
42 base::LazyInstance<base::Lock>::Leaky Clipboard::clipboard_map_lock_ = 21 base::LazyInstance<base::Lock>::Leaky Clipboard::clipboard_map_lock_ =
43 LAZY_INSTANCE_INITIALIZER; 22 LAZY_INSTANCE_INITIALIZER;
44 23
45 // static 24 // static
46 void Clipboard::SetAllowedThreads( 25 void Clipboard::SetAllowedThreads(
47 const std::vector<base::PlatformThreadId>& allowed_threads) { 26 const std::vector<base::PlatformThreadId>& allowed_threads) {
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
88 ClipboardMap* clipboard_map = clipboard_map_.Pointer(); 67 ClipboardMap* clipboard_map = clipboard_map_.Pointer();
89 base::PlatformThreadId id = base::PlatformThread::CurrentId(); 68 base::PlatformThreadId id = base::PlatformThread::CurrentId();
90 ClipboardMap::iterator it = clipboard_map->find(id); 69 ClipboardMap::iterator it = clipboard_map->find(id);
91 if (it != clipboard_map->end()) { 70 if (it != clipboard_map->end()) {
92 delete it->second; 71 delete it->second;
93 clipboard_map->erase(it); 72 clipboard_map->erase(it);
94 } 73 }
95 } 74 }
96 75
97 void Clipboard::DispatchObject(ObjectType type, const ObjectMapParams& params) { 76 void Clipboard::DispatchObject(ObjectType type, const ObjectMapParams& params) {
98 // All types apart from CBF_WEBKIT need at least 1 non-empty param. 77 // Ignore writes with empty parameters.
99 if (type != CBF_WEBKIT && (params.empty() || params[0].empty())) 78 for (const auto& param : params) {
100 return; 79 if (param.empty())
101 // Some other types need a non-empty 2nd param. 80 return;
102 if ((type == CBF_BOOKMARK || type == CBF_SMBITMAP || type == CBF_DATA) && 81 }
103 (params.size() != 2 || params[1].empty())) 82
104 return;
105 switch (type) { 83 switch (type) {
106 case CBF_TEXT: 84 case CBF_TEXT:
107 WriteText(&(params[0].front()), params[0].size()); 85 WriteText(&(params[0].front()), params[0].size());
108 break; 86 break;
109 87
110 case CBF_HTML: 88 case CBF_HTML:
111 if (params.size() == 2) { 89 if (params.size() == 2) {
112 if (params[1].empty()) 90 if (params[1].empty())
113 return; 91 return;
114 WriteHTML(&(params[0].front()), params[0].size(), 92 WriteHTML(&(params[0].front()), params[0].size(),
(...skipping 10 matching lines...) Expand all
125 case CBF_BOOKMARK: 103 case CBF_BOOKMARK:
126 WriteBookmark(&(params[0].front()), params[0].size(), 104 WriteBookmark(&(params[0].front()), params[0].size(),
127 &(params[1].front()), params[1].size()); 105 &(params[1].front()), params[1].size());
128 break; 106 break;
129 107
130 case CBF_WEBKIT: 108 case CBF_WEBKIT:
131 WriteWebSmartPaste(); 109 WriteWebSmartPaste();
132 break; 110 break;
133 111
134 case CBF_SMBITMAP: { 112 case CBF_SMBITMAP: {
135 using base::SharedMemory; 113 // Usually, the params are just UTF-8 strings. However, for images,
136 using base::SharedMemoryHandle; 114 // ScopedClipboardWriter actually sizes the buffer to sizeof(SkBitmap*),
137 115 // aliases the contents of the vector to a SkBitmap**, and writes the
138 if (params[0].size() != sizeof(SharedMemory*) || 116 // pointer to the actual SkBitmap in the clipboard object param.
139 params[1].size() != sizeof(gfx::Size)) { 117 const char* packed_pointer_buffer = &params[0].front();
140 return; 118 WriteBitmap(**reinterpret_cast<SkBitmap* const*>(packed_pointer_buffer));
141 }
142
143 SkBitmap bitmap;
144 const gfx::Size* unvalidated_size =
145 reinterpret_cast<const gfx::Size*>(&params[1].front());
146 // Let Skia do some sanity checking for us (no negative widths/heights, no
147 // overflows while calculating bytes per row, etc).
148 if (!bitmap.setInfo(SkImageInfo::MakeN32Premul(
149 unvalidated_size->width(), unvalidated_size->height()))) {
150 return;
151 }
152 // Make sure the size is representable as a signed 32-bit int, so
153 // SkBitmap::getSize() won't be truncated.
154 if (!sk_64_isS32(bitmap.computeSize64()))
155 return;
156
157 // It's OK to cast away constness here since we map the handle as
158 // read-only.
159 const char* raw_bitmap_data_const =
160 reinterpret_cast<const char*>(&params[0].front());
161 char* raw_bitmap_data = const_cast<char*>(raw_bitmap_data_const);
162 scoped_ptr<SharedMemory> bitmap_data(
163 *reinterpret_cast<SharedMemory**>(raw_bitmap_data));
164
165 if (!ValidateAndMapSharedBitmap(bitmap.getSize(), bitmap_data.get()))
166 return;
167 bitmap.setPixels(bitmap_data->memory());
168
169 WriteBitmap(bitmap);
170 break; 119 break;
171 } 120 }
172 121
173 case CBF_DATA: 122 case CBF_DATA:
174 WriteData( 123 WriteData(
175 FormatType::Deserialize( 124 FormatType::Deserialize(
176 std::string(&(params[0].front()), params[0].size())), 125 std::string(&(params[0].front()), params[0].size())),
177 &(params[1].front()), 126 &(params[1].front()),
178 params[1].size()); 127 params[1].size());
179 break; 128 break;
180 129
181 default: 130 default:
182 NOTREACHED(); 131 NOTREACHED();
183 } 132 }
184 } 133 }
185 134
186 // static
187 bool Clipboard::ReplaceSharedMemHandle(ObjectMap* objects,
188 base::SharedMemoryHandle bitmap_handle,
189 base::ProcessHandle process) {
190 using base::SharedMemory;
191 bool has_shared_bitmap = false;
192
193 for (ObjectMap::iterator iter = objects->begin(); iter != objects->end();
194 ++iter) {
195 if (iter->first == CBF_SMBITMAP) {
196 // The code currently only accepts sending a single bitmap over this way.
197 // Fail if we ever encounter more than one shmem bitmap structure to fill.
198 if (has_shared_bitmap)
199 return false;
200
201 #if defined(OS_WIN)
202 SharedMemory* bitmap = new SharedMemory(bitmap_handle, true, process);
203 #else
204 SharedMemory* bitmap = new SharedMemory(bitmap_handle, true);
205 #endif
206
207 // There must always be two parameters associated with each shmem bitmap.
208 if (iter->second.size() != 2)
209 return false;
210
211 // We store the shared memory object pointer so it can be retrieved by the
212 // UI thread (see DispatchObject()).
213 iter->second[0].clear();
214 for (size_t i = 0; i < sizeof(SharedMemory*); ++i)
215 iter->second[0].push_back(reinterpret_cast<char*>(&bitmap)[i]);
216 has_shared_bitmap = true;
217 }
218 }
219 return true;
220 }
221
222 } // namespace ui 135 } // namespace ui
OLDNEW
« no previous file with comments | « ui/base/clipboard/clipboard.h ('k') | ui/base/clipboard/clipboard_test_template.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698