Home | History | Annotate | Download | only in renderer
      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
      3 // found in the LICENSE file.
      4 
      5 // This file provides the embedder's side of the Clipboard interface.
      6 
      7 #include "content/renderer/renderer_clipboard_client.h"
      8 
      9 #include "base/memory/shared_memory.h"
     10 #include "base/numerics/safe_math.h"
     11 #include "base/strings/string16.h"
     12 #include "content/common/clipboard_messages.h"
     13 #include "content/public/renderer/content_renderer_client.h"
     14 #include "content/renderer/render_thread_impl.h"
     15 #include "content/renderer/scoped_clipboard_writer_glue.h"
     16 #include "ui/base/clipboard/clipboard.h"
     17 #include "ui/gfx/size.h"
     18 
     19 namespace content {
     20 
     21 namespace {
     22 
     23 class RendererClipboardWriteContext : public ClipboardClient::WriteContext {
     24  public:
     25   RendererClipboardWriteContext();
     26   virtual ~RendererClipboardWriteContext();
     27   virtual void WriteBitmapFromPixels(ui::Clipboard::ObjectMap* objects,
     28                                      const void* pixels,
     29                                      const gfx::Size& size) OVERRIDE;
     30   virtual void Flush(const ui::Clipboard::ObjectMap& objects) OVERRIDE;
     31 
     32  private:
     33   scoped_ptr<base::SharedMemory> shared_buf_;
     34   DISALLOW_COPY_AND_ASSIGN(RendererClipboardWriteContext);
     35 };
     36 
     37 RendererClipboardWriteContext::RendererClipboardWriteContext() {
     38 }
     39 
     40 RendererClipboardWriteContext::~RendererClipboardWriteContext() {
     41 }
     42 
     43 // This definition of WriteBitmapFromPixels uses shared memory to communicate
     44 // across processes.
     45 void RendererClipboardWriteContext::WriteBitmapFromPixels(
     46     ui::Clipboard::ObjectMap* objects,
     47     const void* pixels,
     48     const gfx::Size& size) {
     49   // Do not try to write a bitmap more than once
     50   if (shared_buf_)
     51     return;
     52 
     53   base::CheckedNumeric<uint32> checked_buf_size = 4;
     54   checked_buf_size *= size.width();
     55   checked_buf_size *= size.height();
     56   if (!checked_buf_size.IsValid())
     57     return;
     58 
     59   uint32 buf_size = checked_buf_size.ValueOrDie();
     60 
     61   // Allocate a shared memory buffer to hold the bitmap bits.
     62   shared_buf_.reset(ChildThread::current()->AllocateSharedMemory(buf_size));
     63   if (!shared_buf_)
     64     return;
     65 
     66   // Copy the bits into shared memory
     67   DCHECK(shared_buf_->memory());
     68   memcpy(shared_buf_->memory(), pixels, buf_size);
     69   shared_buf_->Unmap();
     70 
     71   ui::Clipboard::ObjectMapParam size_param;
     72   const char* size_data = reinterpret_cast<const char*>(&size);
     73   for (size_t i = 0; i < sizeof(gfx::Size); ++i)
     74     size_param.push_back(size_data[i]);
     75 
     76   ui::Clipboard::ObjectMapParams params;
     77 
     78   // The first parameter is replaced on the receiving end with a pointer to
     79   // a shared memory object containing the bitmap. We reserve space for it here.
     80   ui::Clipboard::ObjectMapParam place_holder_param;
     81   params.push_back(place_holder_param);
     82   params.push_back(size_param);
     83   (*objects)[ui::Clipboard::CBF_SMBITMAP] = params;
     84 }
     85 
     86 // Flushes the objects to the clipboard with an IPC.
     87 void RendererClipboardWriteContext::Flush(
     88     const ui::Clipboard::ObjectMap& objects) {
     89   if (shared_buf_) {
     90     RenderThreadImpl::current()->Send(
     91         new ClipboardHostMsg_WriteObjectsSync(objects, shared_buf_->handle()));
     92   } else {
     93     RenderThreadImpl::current()->Send(
     94         new ClipboardHostMsg_WriteObjectsAsync(objects));
     95   }
     96 }
     97 
     98 }  // anonymous namespace
     99 
    100 RendererClipboardClient::RendererClipboardClient() {
    101 }
    102 
    103 RendererClipboardClient::~RendererClipboardClient() {
    104 }
    105 
    106 ui::Clipboard* RendererClipboardClient::GetClipboard() {
    107   return NULL;
    108 }
    109 
    110 uint64 RendererClipboardClient::GetSequenceNumber(ui::ClipboardType type) {
    111   uint64 sequence_number = 0;
    112   RenderThreadImpl::current()->Send(
    113       new ClipboardHostMsg_GetSequenceNumber(type, &sequence_number));
    114   return sequence_number;
    115 }
    116 
    117 bool RendererClipboardClient::IsFormatAvailable(content::ClipboardFormat format,
    118                                                 ui::ClipboardType type) {
    119   bool result;
    120   RenderThreadImpl::current()->Send(
    121       new ClipboardHostMsg_IsFormatAvailable(format, type, &result));
    122   return result;
    123 }
    124 
    125 void RendererClipboardClient::Clear(ui::ClipboardType type) {
    126   RenderThreadImpl::current()->Send(new ClipboardHostMsg_Clear(type));
    127 }
    128 
    129 void RendererClipboardClient::ReadAvailableTypes(
    130     ui::ClipboardType type,
    131     std::vector<base::string16>* types,
    132     bool* contains_filenames) {
    133   RenderThreadImpl::current()->Send(new ClipboardHostMsg_ReadAvailableTypes(
    134       type, types, contains_filenames));
    135 }
    136 
    137 void RendererClipboardClient::ReadText(ui::ClipboardType type,
    138                                        base::string16* result) {
    139   RenderThreadImpl::current()->Send(
    140       new ClipboardHostMsg_ReadText(type, result));
    141 }
    142 
    143 void RendererClipboardClient::ReadHTML(ui::ClipboardType type,
    144                                        base::string16* markup,
    145                                        GURL* url, uint32* fragment_start,
    146                                        uint32* fragment_end) {
    147   RenderThreadImpl::current()->Send(new ClipboardHostMsg_ReadHTML(
    148       type, markup, url, fragment_start, fragment_end));
    149 }
    150 
    151 void RendererClipboardClient::ReadRTF(ui::ClipboardType type,
    152                                       std::string* result) {
    153   RenderThreadImpl::current()->Send(new ClipboardHostMsg_ReadRTF(type, result));
    154 }
    155 
    156 void RendererClipboardClient::ReadImage(ui::ClipboardType type,
    157                                         std::string* data) {
    158   base::SharedMemoryHandle image_handle;
    159   uint32 image_size;
    160   RenderThreadImpl::current()->Send(
    161       new ClipboardHostMsg_ReadImage(type, &image_handle, &image_size));
    162   if (base::SharedMemory::IsHandleValid(image_handle)) {
    163     base::SharedMemory buffer(image_handle, true);
    164     buffer.Map(image_size);
    165     data->append(static_cast<char*>(buffer.memory()), image_size);
    166   }
    167 }
    168 
    169 void RendererClipboardClient::ReadCustomData(ui::ClipboardType clipboard_type,
    170                                              const base::string16& type,
    171                                              base::string16* data) {
    172   RenderThreadImpl::current()->Send(
    173       new ClipboardHostMsg_ReadCustomData(clipboard_type, type, data));
    174 }
    175 
    176 ClipboardClient::WriteContext* RendererClipboardClient::CreateWriteContext() {
    177   return new RendererClipboardWriteContext;
    178 }
    179 
    180 }  // namespace content
    181