15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/renderer_host/clipboard_message_filter.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind_helpers.h" 9f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/location.h" 10f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/memory/scoped_ptr.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/stl_util.h" 1223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "base/strings/utf_string_conversions.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/clipboard_messages.h" 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/browser_context.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ipc/ipc_message_macros.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/skia/include/core/SkBitmap.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/codec/png_codec.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/size.h" 197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "url/gurl.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content { 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 25a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)enum BitmapPolicy { 26a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) kFilterBitmap, 27a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) kAllowBitmap, 28a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}; 29a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void SanitizeObjectMap(ui::Clipboard::ObjectMap* objects, 30a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) BitmapPolicy bitmap_policy) { 31a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (bitmap_policy != kAllowBitmap) 32a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) objects->erase(ui::Clipboard::CBF_SMBITMAP); 33a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 34a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ui::Clipboard::ObjectMap::iterator data_it = 35a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) objects->find(ui::Clipboard::CBF_DATA); 36a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (data_it != objects->end()) { 37a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const ui::Clipboard::FormatType& web_custom_format = 38a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ui::Clipboard::GetWebCustomDataFormatType(); 39a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (data_it->second.size() != 2 || 40a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) !web_custom_format.Equals( 41a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ui::Clipboard::FormatType::Deserialize(std::string( 42a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) &data_it->second[0].front(), 43a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) data_it->second[0].size())))) { 44a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // CBF_DATA should always have two parameters associated with it, and the 45a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // associated FormatType should always be web custom data. If not, then 46a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // data is malformed and we'll ignore it. 47a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) objects->erase(ui::Clipboard::CBF_DATA); 48a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 49a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 50a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 51a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)ClipboardMessageFilter::ClipboardMessageFilter() 565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) : BrowserMessageFilter(ClipboardMsgStart) {} 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ClipboardMessageFilter::OverrideThreadForMessage( 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const IPC::Message& message, BrowserThread::ID* thread) { 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Clipboard writes should always occur on the UI thread due the restrictions 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // of various platform APIs. In general, the clipboard is not thread-safe, so 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // all clipboard calls should be serviced from the UI thread. 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Windows needs clipboard reads to be serviced from the IO thread because 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // these are sync IPCs which can result in deadlocks with NPAPI plugins if 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // serviced from the UI thread. Note that Windows clipboard calls ARE 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // thread-safe so it is ok for reads and writes to be serviced from different 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // threads. 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(OS_WIN) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IPC_MESSAGE_CLASS(message) == ClipboardMsgStart) 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *thread = BrowserThread::UI; 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (message.type() == ClipboardHostMsg_ReadImage::ID) 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *thread = BrowserThread::FILE; 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 80cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool ClipboardMessageFilter::OnMessageReceived(const IPC::Message& message) { 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool handled = true; 82cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) IPC_BEGIN_MESSAGE_MAP(ClipboardMessageFilter, message) 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_MESSAGE_HANDLER(ClipboardHostMsg_WriteObjectsAsync, OnWriteObjectsAsync) 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_MESSAGE_HANDLER(ClipboardHostMsg_WriteObjectsSync, OnWriteObjectsSync) 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_MESSAGE_HANDLER(ClipboardHostMsg_GetSequenceNumber, OnGetSequenceNumber) 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_MESSAGE_HANDLER(ClipboardHostMsg_IsFormatAvailable, OnIsFormatAvailable) 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_MESSAGE_HANDLER(ClipboardHostMsg_Clear, OnClear) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_MESSAGE_HANDLER(ClipboardHostMsg_ReadAvailableTypes, 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnReadAvailableTypes) 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_MESSAGE_HANDLER(ClipboardHostMsg_ReadText, OnReadText) 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_MESSAGE_HANDLER(ClipboardHostMsg_ReadHTML, OnReadHTML) 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_MESSAGE_HANDLER(ClipboardHostMsg_ReadRTF, OnReadRTF) 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_MESSAGE_HANDLER_DELAY_REPLY(ClipboardHostMsg_ReadImage, OnReadImage) 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_MESSAGE_HANDLER(ClipboardHostMsg_ReadCustomData, OnReadCustomData) 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_MACOSX) 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_MESSAGE_HANDLER(ClipboardHostMsg_FindPboardWriteStringAsync, 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnFindPboardWriteString) 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_MESSAGE_UNHANDLED(handled = false) 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_END_MESSAGE_MAP() 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return handled; 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ClipboardMessageFilter::~ClipboardMessageFilter() { 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ClipboardMessageFilter::OnWriteObjectsSync( 108f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const ui::Clipboard::ObjectMap& objects, 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::SharedMemoryHandle bitmap_handle) { 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(base::SharedMemory::IsHandleValid(bitmap_handle)) 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "Bad bitmap handle"; 112f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 113f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // On Windows, we can't write directly from the IO thread, so we copy the data 114f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // into a heap allocated map and post a task to the UI thread. On other 115f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // platforms, to lower the amount of time the renderer has to wait for the 116f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // sync IPC to complete, we also take a copy and post a task to flush the data 117f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // to the clipboard later. 118f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_ptr<ui::Clipboard::ObjectMap> long_living_objects( 119f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) new ui::Clipboard::ObjectMap(objects)); 120a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) SanitizeObjectMap(long_living_objects.get(), kAllowBitmap); 121f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Splice the shared memory handle into the data. |long_living_objects| now 122f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // contains a heap-allocated SharedMemory object that references 123f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // |bitmap_handle|. This reference will keep the shared memory section alive 124f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // when this IPC returns, and the SharedMemory object will eventually be 125f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // freed by ui::Clipboard::WriteObjects(). 126f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!ui::Clipboard::ReplaceSharedMemHandle( 127f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) long_living_objects.get(), bitmap_handle, PeerHandle())) 128f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return; 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::PostTask( 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::UI, 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 13323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) base::Bind(&ClipboardMessageFilter::WriteObjectsOnUIThread, 134f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::Owned(long_living_objects.release()))); 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// On Windows, the write must be performed on the UI thread because the 13823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// clipboard object from the IO thread cannot create windows so it cannot be 13923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// the "owner" of the clipboard's contents. See http://crbug.com/5823. 14023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// TODO(dcheng): Temporarily a member of ClipboardMessageFilter so it can access 14123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// ui::Clipboard::WriteObjects(). 14223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)void ClipboardMessageFilter::WriteObjectsOnUIThread( 14323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) const ui::Clipboard::ObjectMap* objects) { 144effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::UI); 14523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) static ui::Clipboard* clipboard = ui::Clipboard::GetForCurrentThread(); 14623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) clipboard->WriteObjects(ui::CLIPBOARD_TYPE_COPY_PASTE, *objects); 14723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)} 14823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ClipboardMessageFilter::OnWriteObjectsAsync( 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ui::Clipboard::ObjectMap& objects) { 151f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // This async message doesn't support shared-memory based bitmaps; they must 152f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // be removed otherwise we might dereference a rubbish pointer. 153f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_ptr<ui::Clipboard::ObjectMap> sanitized_objects( 154f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) new ui::Clipboard::ObjectMap(objects)); 155a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) SanitizeObjectMap(sanitized_objects.get(), kFilterBitmap); 156f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We cannot write directly from the IO thread, and cannot service the IPC 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // on the UI thread. We'll copy the relevant data and post a task to preform 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the write on the UI thread. 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::PostTask( 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::UI, 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 164f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::Bind( 165f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) &WriteObjectsOnUIThread, base::Owned(sanitized_objects.release()))); 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 167f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) GetClipboard()->WriteObjects( 168f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ui::CLIPBOARD_TYPE_COPY_PASTE, *sanitized_objects.get()); 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void ClipboardMessageFilter::OnGetSequenceNumber(ui::ClipboardType type, 1734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) uint64* sequence_number) { 1744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) *sequence_number = GetClipboard()->GetSequenceNumber(type); 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 177a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void ClipboardMessageFilter::OnReadAvailableTypes( 178a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ui::ClipboardType type, 179a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) std::vector<base::string16>* types, 180a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) bool* contains_filenames) { 1814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) GetClipboard()->ReadAvailableTypes(type, types, contains_filenames); 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)void ClipboardMessageFilter::OnIsFormatAvailable(ClipboardFormat format, 18523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) ui::ClipboardType type, 18623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) bool* result) { 18723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) switch (format) { 18823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) case CLIPBOARD_FORMAT_PLAINTEXT: 18923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) *result = GetClipboard()->IsFormatAvailable( 19023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) ui::Clipboard::GetPlainTextWFormatType(), type) || 19123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) GetClipboard()->IsFormatAvailable( 19223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) ui::Clipboard::GetPlainTextFormatType(), type); 19323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) break; 19423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) case CLIPBOARD_FORMAT_HTML: 19523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) *result = GetClipboard()->IsFormatAvailable( 19623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) ui::Clipboard::GetHtmlFormatType(), type); 197effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch break; 19823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) case CLIPBOARD_FORMAT_SMART_PASTE: 19923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) *result = GetClipboard()->IsFormatAvailable( 20023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) ui::Clipboard::GetWebKitSmartPasteFormatType(), type); 201effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch break; 20223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) case CLIPBOARD_FORMAT_BOOKMARK: 20323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#if defined(OS_WIN) || defined(OS_MACOSX) 20423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) *result = GetClipboard()->IsFormatAvailable( 20523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) ui::Clipboard::GetUrlWFormatType(), type); 20623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#else 20723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) *result = false; 20823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#endif 209effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch break; 21023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void ClipboardMessageFilter::OnClear(ui::ClipboardType type) { 2144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) GetClipboard()->Clear(type); 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void ClipboardMessageFilter::OnReadText(ui::ClipboardType type, 218a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::string16* result) { 21923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (GetClipboard()->IsFormatAvailable( 22023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) ui::Clipboard::GetPlainTextWFormatType(), type)) { 22123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) GetClipboard()->ReadText(type, result); 22223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } else if (GetClipboard()->IsFormatAvailable( 22323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) ui::Clipboard::GetPlainTextFormatType(), type)) { 22423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) std::string ascii; 22523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) GetClipboard()->ReadAsciiText(type, &ascii); 22623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) *result = base::ASCIIToUTF16(ascii); 22723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } else { 22823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) result->clear(); 22923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void ClipboardMessageFilter::OnReadHTML(ui::ClipboardType type, 233a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::string16* markup, 2344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) GURL* url, 2354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) uint32* fragment_start, 2364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) uint32* fragment_end) { 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string src_url_str; 2384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) GetClipboard()->ReadHTML(type, markup, &src_url_str, fragment_start, 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fragment_end); 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *url = GURL(src_url_str); 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void ClipboardMessageFilter::OnReadRTF(ui::ClipboardType type, 2444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) std::string* result) { 2454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) GetClipboard()->ReadRTF(type, result); 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void ClipboardMessageFilter::OnReadImage(ui::ClipboardType type, 2494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) IPC::Message* reply_msg) { 2504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) SkBitmap bitmap = GetClipboard()->ReadImage(type); 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(USE_X11) 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::PostTask( 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::FILE, FROM_HERE, 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind( 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &ClipboardMessageFilter::OnReadImageReply, this, bitmap, reply_msg)); 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnReadImageReply(bitmap, reply_msg); 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ClipboardMessageFilter::OnReadImageReply( 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SkBitmap& bitmap, IPC::Message* reply_msg) { 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::SharedMemoryHandle image_handle = base::SharedMemory::NULLHandle(); 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32 image_size = 0; 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!bitmap.isNull()) { 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<unsigned char> png_data; 268424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (gfx::PNGCodec::FastEncodeBGRASkBitmap(bitmap, false, &png_data)) { 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::SharedMemory buffer; 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (buffer.CreateAndMapAnonymous(png_data.size())) { 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(buffer.memory(), vector_as_array(&png_data), png_data.size()); 2727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (buffer.GiveToProcess(PeerHandle(), &image_handle)) { 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) image_size = png_data.size(); 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ClipboardHostMsg_ReadImage::WriteReplyParams(reply_msg, image_handle, 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) image_size); 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Send(reply_msg); 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void ClipboardMessageFilter::OnReadCustomData(ui::ClipboardType clipboard_type, 284a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const base::string16& type, 285a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::string16* result) { 2864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) GetClipboard()->ReadCustomData(clipboard_type, type, result); 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ui::Clipboard* ClipboardMessageFilter::GetClipboard() { 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We have a static instance of the clipboard service for use by all message 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // filters. This instance lives for the life of the browser processes. 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static ui::Clipboard* clipboard = ui::Clipboard::GetForCurrentThread(); 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return clipboard; 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace content 298