Commit bcd60dd2 authored by Joel Hockey's avatar Joel Hockey Committed by Chromium LUCI CQ

Check DataDevice still alive after nested RunLoop in OnPerformDrop()

DataDevice::OnPerformDrop() has a nested RunLoop() and the current
object can be destroyed inside that loop.

Bug: 1160553, 1160925
Change-Id: I09872e5f88d4d5c3e582ce7b3e6e4085afed0518
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2598519
Commit-Queue: Joel Hockey <joelhockey@chromium.org>
Reviewed-by: default avatarMitsuru Oshima (slow: gardener) <oshima@chromium.org>
Auto-Submit: Joel Hockey <joelhockey@chromium.org>
Cr-Commit-Position: refs/heads/master@{#838700}
parent f8997c62
...@@ -124,14 +124,18 @@ int DataDevice::OnPerformDrop(const ui::DropTargetEvent& event) { ...@@ -124,14 +124,18 @@ int DataDevice::OnPerformDrop(const ui::DropTargetEvent& event) {
delegate_->OnDrop(); delegate_->OnDrop();
// TODO(tetsui): Avoid using nested loop by adding asynchronous callback to // TODO(crbug.com/1160925): Avoid using nested loop by adding asynchronous
// aura::client::DragDropDelegate. // callback to aura::client::DragDropDelegate.
base::WeakPtr<DataDevice> alive(weak_factory_.GetWeakPtr());
base::RunLoop run_loop(base::RunLoop::Type::kNestableTasksAllowed); base::RunLoop run_loop(base::RunLoop::Type::kNestableTasksAllowed);
base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
FROM_HERE, run_loop.QuitClosure(), kDataOfferDestructionTimeout); FROM_HERE, run_loop.QuitClosure(), kDataOfferDestructionTimeout);
quit_closure_ = run_loop.QuitClosure(); quit_closure_ = run_loop.QuitClosure();
run_loop.Run(); run_loop.Run();
if (!alive)
return ui::DragDropTypes::DRAG_NONE;
if (quit_closure_) { if (quit_closure_) {
// DataOffer not destroyed by the client until the timeout. // DataOffer not destroyed by the client until the timeout.
quit_closure_.Reset(); quit_closure_.Reset();
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include <cstdint> #include <cstdint>
#include "base/macros.h" #include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "components/exo/data_offer_observer.h" #include "components/exo/data_offer_observer.h"
#include "components/exo/seat_observer.h" #include "components/exo/seat_observer.h"
#include "components/exo/surface.h" #include "components/exo/surface.h"
...@@ -87,6 +88,7 @@ class DataDevice : public WMHelper::DragDropObserver, ...@@ -87,6 +88,7 @@ class DataDevice : public WMHelper::DragDropObserver,
base::OnceClosure quit_closure_; base::OnceClosure quit_closure_;
bool drop_succeeded_; bool drop_succeeded_;
base::WeakPtrFactory<DataDevice> weak_factory_{this};
DISALLOW_COPY_AND_ASSIGN(DataDevice); DISALLOW_COPY_AND_ASSIGN(DataDevice);
}; };
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include "ash/shell.h" #include "ash/shell.h"
#include "base/strings/string16.h" #include "base/strings/string16.h"
#include "base/strings/utf_string_conversions.h" #include "base/strings/utf_string_conversions.h"
#include "base/test/bind.h"
#include "components/exo/data_device_delegate.h" #include "components/exo/data_device_delegate.h"
#include "components/exo/data_exchange_delegate.h" #include "components/exo/data_exchange_delegate.h"
#include "components/exo/data_offer.h" #include "components/exo/data_offer.h"
...@@ -199,6 +200,17 @@ TEST_F(DataDeviceTest, DataEventsExit) { ...@@ -199,6 +200,17 @@ TEST_F(DataDeviceTest, DataEventsExit) {
EXPECT_EQ(DataEvent::kLeave, events[0]); EXPECT_EQ(DataEvent::kLeave, events[0]);
} }
TEST_F(DataDeviceTest, DeleteDataDeviceDuringDrop) {
ui::DropTargetEvent event(data_, gfx::PointF(), gfx::PointF(),
ui::DragDropTypes::DRAG_MOVE);
ui::Event::DispatcherApi(&event).set_target(surface_->window());
device_->OnDragEntered(event);
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::BindLambdaForTesting([&]() { device_.reset(); }));
int result = device_->OnPerformDrop(event);
EXPECT_EQ(ui::DragDropTypes::DRAG_NONE, result);
}
TEST_F(DataDeviceTest, DeleteDataOfferDuringDrag) { TEST_F(DataDeviceTest, DeleteDataOfferDuringDrag) {
ui::DropTargetEvent event(data_, gfx::PointF(), gfx::PointF(), ui::DropTargetEvent event(data_, gfx::PointF(), gfx::PointF(),
ui::DragDropTypes::DRAG_MOVE); ui::DragDropTypes::DRAG_MOVE);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment