Make sure that Clipboard operations that require dispatching
of windows messages are performed on the UI thread.

SetClipboardData requires the clipboard to be open with a handle
to a window that will be notified when the contents are going to
change again. If Windows messages are not processed, any other app
writing to the clipboard will be locked while we acknowledge their
request (by processing the message).

The IO thread doesn't pump windows messages anymore so write
clipboard operations cannot be performed from that thread and have
to be posted to another thread.

BUG=5823

Review URL: http://codereview.chromium.org/19733

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@9003 0039d316-1c4b-4281-b951-d872f2087c98


CrOS-Libchrome-Original-Commit: a92d2fd9d1fe0e74f6ca7d540858a4711b46367e
diff --git a/base/clipboard.h b/base/clipboard.h
index 64f9e3a..abaaa1b 100644
--- a/base/clipboard.h
+++ b/base/clipboard.h
@@ -130,6 +130,11 @@
   static FormatType GetCFHDropFormatType();
   static FormatType GetFileDescriptorFormatType();
   static FormatType GetFileContentFormatZeroType();
+
+  // Duplicates any remote shared memory handle embedded inside |objects| that
+  // was created by |process| so that it can be used by this process.
+  static void DuplicateRemoteHandles(base::ProcessHandle process,
+                                     ObjectMap* objects);
 #endif
 
  private:
@@ -181,6 +186,9 @@
 
   // Mark this as mutable so const methods can still do lazy initialization.
   mutable HWND clipboard_owner_;
+
+  // True if we can create a window.
+  bool create_window_;
 #elif defined(OS_LINUX)
   // Data is stored in the |clipboard_data_| map until it is saved to the system
   // clipboard. The Store* functions save data to the |clipboard_data_| map. The
diff --git a/base/clipboard_unittest.cc b/base/clipboard_unittest.cc
index c752b4c..18f5fbc 100644
--- a/base/clipboard_unittest.cc
+++ b/base/clipboard_unittest.cc
@@ -6,12 +6,27 @@
 
 #include "base/basictypes.h"
 #include "base/clipboard.h"
+#include "base/message_loop.h"
 #include "base/scoped_clipboard_writer.h"
 #include "base/string_util.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "testing/platform_test.h"
 
+#if defined(OS_WIN)
+class ClipboardTest : public PlatformTest {
+ protected:  
+  virtual void SetUp() {
+    message_loop_.reset(new MessageLoopForUI());
+  }
+  virtual void TearDown() {
+  }
+
+ private:
+  scoped_ptr<MessageLoop> message_loop_;
+};
+#elif defined(OS_POSIX)
 typedef PlatformTest ClipboardTest;
+#endif  // defined(OS_WIN)
 
 TEST_F(ClipboardTest, ClearTest) {
   Clipboard clipboard;
diff --git a/base/file_util_unittest.cc b/base/file_util_unittest.cc
index 8f5ce19..98c2032 100644
--- a/base/file_util_unittest.cc
+++ b/base/file_util_unittest.cc
@@ -984,7 +984,9 @@
   data_dir = data_dir.Append(FILE_PATH_LITERAL("FilePathTest"));
 
   // Create a fresh, empty copy of this directory.
-  ASSERT_TRUE(file_util::Delete(data_dir, true));
+  if (file_util::PathExists(data_dir)) {
+    ASSERT_TRUE(file_util::Delete(data_dir, true));
+  }
   ASSERT_TRUE(file_util::CreateDirectory(data_dir));
 
   FilePath foo(data_dir.Append(FILE_PATH_LITERAL("foo")));