Fix OSExchangeData::IsFromPrivileged does not convey on
OSExchangeDataProvider::Clone()

On WaylandDataDragController[1], OSExchangeData is copied using
OSExchangeDataProvider::Clone(). This CL makes the recently
added OSExchangeData::IsFromPrivileged() in CL[2] backed
by OSExchangeDataProvider so it can convey on
OSExchangeDataProvider::Clone().

The change fixes an issue of WebUI tab strip tab dragging not working
within the same window in Lacros.

[1] https://source.chromium.org/chromium/chromium/src/+/main:ui/ozone/platform/wayland/host/wayland_data_drag_controller.cc;l=224;drc=751bbeb73a0dacc98a2b9486e0cf788fe763356a;bpv=1;bpt=1
[2] https://chromium-review.googlesource.com/c/chromium/src/+/3343455

Bug: 1284996, 1257837, 1283077
Change-Id: If361d2e0f507be0c53ea57c8fd0a418b89291474
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3388844
Reviewed-by: Daniel Cheng <[email protected]>
Reviewed-by: Sadrul Chowdhury <[email protected]>
Commit-Queue: Yuheng Huang <[email protected]>
Cr-Commit-Position: refs/heads/main@{#961529}
diff --git a/ui/base/dragdrop/os_exchange_data.cc b/ui/base/dragdrop/os_exchange_data.cc
index 9757d98f..e71b921 100644
--- a/ui/base/dragdrop/os_exchange_data.cc
+++ b/ui/base/dragdrop/os_exchange_data.cc
@@ -35,11 +35,11 @@
 }
 
 void OSExchangeData::MarkAsFromPrivileged() {
-  is_from_privileged_ = true;
+  provider_->MarkAsFromPrivileged();
 }
 
 bool OSExchangeData::IsFromPrivileged() const {
-  return is_from_privileged_;
+  return provider_->IsFromPrivileged();
 }
 
 void OSExchangeData::SetString(const std::u16string& data) {
diff --git a/ui/base/dragdrop/os_exchange_data.h b/ui/base/dragdrop/os_exchange_data.h
index 08216228..a3522764 100644
--- a/ui/base/dragdrop/os_exchange_data.h
+++ b/ui/base/dragdrop/os_exchange_data.h
@@ -199,8 +199,6 @@
  private:
   // Provides the actual data.
   std::unique_ptr<OSExchangeDataProvider> provider_;
-
-  bool is_from_privileged_ = false;
 };
 
 }  // namespace ui
diff --git a/ui/base/dragdrop/os_exchange_data_provider.h b/ui/base/dragdrop/os_exchange_data_provider.h
index 63e88866..18c12bf 100644
--- a/ui/base/dragdrop/os_exchange_data_provider.h
+++ b/ui/base/dragdrop/os_exchange_data_provider.h
@@ -47,6 +47,9 @@
   virtual void MarkOriginatedFromRenderer() = 0;
   virtual bool DidOriginateFromRenderer() const = 0;
 
+  virtual void MarkAsFromPrivileged() = 0;
+  virtual bool IsFromPrivileged() const = 0;
+
   virtual void SetString(const std::u16string& data) = 0;
   virtual void SetURL(const GURL& url, const std::u16string& title) = 0;
   virtual void SetFilename(const base::FilePath& path) = 0;
diff --git a/ui/base/dragdrop/os_exchange_data_provider_mac.h b/ui/base/dragdrop/os_exchange_data_provider_mac.h
index 66518c1..5b2746a 100644
--- a/ui/base/dragdrop/os_exchange_data_provider_mac.h
+++ b/ui/base/dragdrop/os_exchange_data_provider_mac.h
@@ -41,6 +41,8 @@
   // Overridden from OSExchangeDataProvider:
   void MarkOriginatedFromRenderer() override;
   bool DidOriginateFromRenderer() const override;
+  void MarkAsFromPrivileged() override;
+  bool IsFromPrivileged() const override;
   void SetString(const std::u16string& data) override;
   void SetURL(const GURL& url, const std::u16string& title) override;
   void SetFilename(const base::FilePath& path) override;
diff --git a/ui/base/dragdrop/os_exchange_data_provider_mac.mm b/ui/base/dragdrop/os_exchange_data_provider_mac.mm
index 3f50150..ea59d6d 100644
--- a/ui/base/dragdrop/os_exchange_data_provider_mac.mm
+++ b/ui/base/dragdrop/os_exchange_data_provider_mac.mm
@@ -140,6 +140,17 @@
 }
 
 bool OSExchangeDataProviderMac::DidOriginateFromRenderer() const {
+  // TODO(crbug.com/1288599): Implement this method.
+  NOTIMPLEMENTED();
+  return false;
+}
+
+void OSExchangeDataProviderMac::MarkAsFromPrivileged() {
+  NOTIMPLEMENTED();
+}
+
+bool OSExchangeDataProviderMac::IsFromPrivileged() const {
+  // TODO(crbug.com/1288601): Implement this method.
   NOTIMPLEMENTED();
   return false;
 }
diff --git a/ui/base/dragdrop/os_exchange_data_provider_non_backed.cc b/ui/base/dragdrop/os_exchange_data_provider_non_backed.cc
index 3c10f2d..8311f72 100644
--- a/ui/base/dragdrop/os_exchange_data_provider_non_backed.cc
+++ b/ui/base/dragdrop/os_exchange_data_provider_non_backed.cc
@@ -48,6 +48,14 @@
 #endif
 }
 
+void OSExchangeDataProviderNonBacked::MarkAsFromPrivileged() {
+  is_from_privileged_ = true;
+}
+
+bool OSExchangeDataProviderNonBacked::IsFromPrivileged() const {
+  return is_from_privileged_;
+}
+
 void OSExchangeDataProviderNonBacked::SetString(const std::u16string& data) {
   if (HasString())
     return;
@@ -278,6 +286,7 @@
   provider->source_ =
       source_ ? std::make_unique<DataTransferEndpoint>(*source_.get())
               : nullptr;
+  provider->is_from_privileged_ = is_from_privileged_;
 #if !BUILDFLAG(IS_CHROMEOS_ASH)
   provider->originated_from_renderer_ = originated_from_renderer_;
 #endif
diff --git a/ui/base/dragdrop/os_exchange_data_provider_non_backed.h b/ui/base/dragdrop/os_exchange_data_provider_non_backed.h
index 3fcf989..5dea6ef 100644
--- a/ui/base/dragdrop/os_exchange_data_provider_non_backed.h
+++ b/ui/base/dragdrop/os_exchange_data_provider_non_backed.h
@@ -43,6 +43,8 @@
   std::unique_ptr<OSExchangeDataProvider> Clone() const override;
   void MarkOriginatedFromRenderer() override;
   bool DidOriginateFromRenderer() const override;
+  void MarkAsFromPrivileged() override;
+  bool IsFromPrivileged() const override;
   void SetString(const std::u16string& data) override;
   void SetURL(const GURL& url, const std::u16string& title) override;
   void SetFilename(const base::FilePath& path) override;
@@ -129,6 +131,9 @@
   bool originated_from_renderer_ = false;
 #endif
 
+  // For marking data originating by privileged WebContents.
+  bool is_from_privileged_ = false;
+
   // Data source.
   std::unique_ptr<DataTransferEndpoint> source_;
 };
diff --git a/ui/base/dragdrop/os_exchange_data_provider_win.cc b/ui/base/dragdrop/os_exchange_data_provider_win.cc
index 72c57ad..4d7b2f1 100644
--- a/ui/base/dragdrop/os_exchange_data_provider_win.cc
+++ b/ui/base/dragdrop/os_exchange_data_provider_win.cc
@@ -62,6 +62,7 @@
 STGMEDIUM CreateStorageForFileDescriptor(const base::FilePath& path);
 
 const ClipboardFormatType& GetRendererTaintFormatType();
+const ClipboardFormatType& GetFromPrivilegedFormatType();
 const ClipboardFormatType& GetIgnoreFileContentsFormatType();
 // Creates the contents of an Internet Shortcut file for the given URL.
 std::string GetInternetShortcutFileContents(const GURL& url);
@@ -305,6 +306,16 @@
   return HasCustomFormat(GetRendererTaintFormatType());
 }
 
+void OSExchangeDataProviderWin::MarkAsFromPrivileged() {
+  STGMEDIUM storage = CreateStorageForString(std::string());
+  data_->contents_.push_back(DataObjectImpl::StoredDataInfo::TakeStorageMedium(
+      GetFromPrivilegedFormatType().ToFormatEtc(), storage));
+}
+
+bool OSExchangeDataProviderWin::IsFromPrivileged() const {
+  return HasCustomFormat(GetFromPrivilegedFormatType());
+}
+
 void OSExchangeDataProviderWin::SetString(const std::u16string& data) {
   STGMEDIUM storage = CreateStorageForString(data);
   data_->contents_.push_back(DataObjectImpl::StoredDataInfo::TakeStorageMedium(
@@ -1200,6 +1211,12 @@
   return *format;
 }
 
+const ClipboardFormatType& GetFromPrivilegedFormatType() {
+  static base::NoDestructor<ClipboardFormatType> format(
+      ClipboardFormatType::GetType("chromium/from-privileged"));
+  return *format;
+}
+
 // Used to mark file content as synthesized by Chrome itself during a non-file
 // drag for interoperating with the native OS. Synthesized file contents will be
 // treated as non-existent for the purposes of GetFileContent() to avoid
diff --git a/ui/base/dragdrop/os_exchange_data_provider_win.h b/ui/base/dragdrop/os_exchange_data_provider_win.h
index 94e7495..c84bafb 100644
--- a/ui/base/dragdrop/os_exchange_data_provider_win.h
+++ b/ui/base/dragdrop/os_exchange_data_provider_win.h
@@ -149,6 +149,8 @@
   std::unique_ptr<OSExchangeDataProvider> Clone() const override;
   void MarkOriginatedFromRenderer() override;
   bool DidOriginateFromRenderer() const override;
+  void MarkAsFromPrivileged() override;
+  bool IsFromPrivileged() const override;
   void SetString(const std::u16string& data) override;
   void SetURL(const GURL& url, const std::u16string& title) override;
   void SetFilename(const base::FilePath& path) override;