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

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

Issue 740003003: Revert of Rewrite clipboard write IPC handling to be easier to understand. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: 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
17 base::LazyInstance<Clipboard::AllowedThreadsVector> 38 base::LazyInstance<Clipboard::AllowedThreadsVector>
18 Clipboard::allowed_threads_ = LAZY_INSTANCE_INITIALIZER; 39 Clipboard::allowed_threads_ = LAZY_INSTANCE_INITIALIZER;
19 base::LazyInstance<Clipboard::ClipboardMap> Clipboard::clipboard_map_ = 40 base::LazyInstance<Clipboard::ClipboardMap> Clipboard::clipboard_map_ =
20 LAZY_INSTANCE_INITIALIZER; 41 LAZY_INSTANCE_INITIALIZER;
21 base::LazyInstance<base::Lock>::Leaky Clipboard::clipboard_map_lock_ = 42 base::LazyInstance<base::Lock>::Leaky Clipboard::clipboard_map_lock_ =
22 LAZY_INSTANCE_INITIALIZER; 43 LAZY_INSTANCE_INITIALIZER;
23 44
24 // static 45 // static
25 void Clipboard::SetAllowedThreads( 46 void Clipboard::SetAllowedThreads(
26 const std::vector<base::PlatformThreadId>& allowed_threads) { 47 const std::vector<base::PlatformThreadId>& allowed_threads) {
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
67 ClipboardMap* clipboard_map = clipboard_map_.Pointer(); 88 ClipboardMap* clipboard_map = clipboard_map_.Pointer();
68 base::PlatformThreadId id = base::PlatformThread::CurrentId(); 89 base::PlatformThreadId id = base::PlatformThread::CurrentId();
69 ClipboardMap::iterator it = clipboard_map->find(id); 90 ClipboardMap::iterator it = clipboard_map->find(id);
70 if (it != clipboard_map->end()) { 91 if (it != clipboard_map->end()) {
71 delete it->second; 92 delete it->second;
72 clipboard_map->erase(it); 93 clipboard_map->erase(it);
73 } 94 }
74 } 95 }
75 96
76 void Clipboard::DispatchObject(ObjectType type, const ObjectMapParams& params) { 97 void Clipboard::DispatchObject(ObjectType type, const ObjectMapParams& params) {
98 // All types apart from CBF_WEBKIT need at least 1 non-empty param.
99 if (type != CBF_WEBKIT && (params.empty() || params[0].empty()))
100 return;
101 // Some other types need a non-empty 2nd param.
102 if ((type == CBF_BOOKMARK || type == CBF_SMBITMAP || type == CBF_DATA) &&
103 (params.size() != 2 || params[1].empty()))
104 return;
77 switch (type) { 105 switch (type) {
78 case CBF_TEXT: 106 case CBF_TEXT:
79 WriteText(&(params[0].front()), params[0].size()); 107 WriteText(&(params[0].front()), params[0].size());
80 break; 108 break;
81 109
82 case CBF_HTML: 110 case CBF_HTML:
83 if (params.size() == 2) { 111 if (params.size() == 2) {
84 if (params[1].empty()) 112 if (params[1].empty())
85 return; 113 return;
86 WriteHTML(&(params[0].front()), params[0].size(), 114 WriteHTML(&(params[0].front()), params[0].size(),
(...skipping 10 matching lines...) Expand all
97 case CBF_BOOKMARK: 125 case CBF_BOOKMARK:
98 WriteBookmark(&(params[0].front()), params[0].size(), 126 WriteBookmark(&(params[0].front()), params[0].size(),
99 &(params[1].front()), params[1].size()); 127 &(params[1].front()), params[1].size());
100 break; 128 break;
101 129
102 case CBF_WEBKIT: 130 case CBF_WEBKIT:
103 WriteWebSmartPaste(); 131 WriteWebSmartPaste();
104 break; 132 break;
105 133
106 case CBF_SMBITMAP: { 134 case CBF_SMBITMAP: {
107 // Usually, the params are just UTF-8 strings. However, for images, 135 using base::SharedMemory;
108 // ScopedClipboardWriter actually sizes the buffer to sizeof(SkBitmap*), 136 using base::SharedMemoryHandle;
109 // aliases the contents of the vector to a SkBitmap**, and writes the 137
110 // pointer to the actual SkBitmap in the clipboard object param. 138 if (params[0].size() != sizeof(SharedMemory*) ||
111 const char* packed_pointer_buffer = &params[0].front(); 139 params[1].size() != sizeof(gfx::Size)) {
112 WriteBitmap( 140 return;
113 **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);
114 break; 170 break;
115 } 171 }
116 172
117 case CBF_DATA: 173 case CBF_DATA:
118 WriteData( 174 WriteData(
119 FormatType::Deserialize( 175 FormatType::Deserialize(
120 std::string(&(params[0].front()), params[0].size())), 176 std::string(&(params[0].front()), params[0].size())),
121 &(params[1].front()), 177 &(params[1].front()),
122 params[1].size()); 178 params[1].size());
123 break; 179 break;
124 180
125 default: 181 default:
126 NOTREACHED(); 182 NOTREACHED();
127 } 183 }
128 } 184 }
129 185
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
130 } // namespace ui 222 } // 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