Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(562)

Side by Side Diff: content/browser/renderer_host/render_widget_host_impl.cc

Issue 2485693003: Drag-and-drop: DragEnter, DragOver, DragLeave, DragDrop (Closed)
Patch Set: Rebased. More fixes. Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/renderer_host/render_widget_host_impl.h" 5 #include "content/browser/renderer_host/render_widget_host_impl.h"
6 6
7 #include <math.h> 7 #include <math.h>
8 8
9 #include <set> 9 #include <set>
10 #include <tuple> 10 #include <tuple>
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
69 #include "content/public/browser/notification_types.h" 69 #include "content/public/browser/notification_types.h"
70 #include "content/public/browser/render_widget_host_iterator.h" 70 #include "content/public/browser/render_widget_host_iterator.h"
71 #include "content/public/browser/storage_partition.h" 71 #include "content/public/browser/storage_partition.h"
72 #include "content/public/common/content_constants.h" 72 #include "content/public/common/content_constants.h"
73 #include "content/public/common/content_switches.h" 73 #include "content/public/common/content_switches.h"
74 #include "content/public/common/result_codes.h" 74 #include "content/public/common/result_codes.h"
75 #include "content/public/common/web_preferences.h" 75 #include "content/public/common/web_preferences.h"
76 #include "gpu/GLES2/gl2extchromium.h" 76 #include "gpu/GLES2/gl2extchromium.h"
77 #include "gpu/command_buffer/service/gpu_switches.h" 77 #include "gpu/command_buffer/service/gpu_switches.h"
78 #include "gpu/ipc/common/gpu_messages.h" 78 #include "gpu/ipc/common/gpu_messages.h"
79 #include "net/base/filename_util.h"
79 #include "skia/ext/image_operations.h" 80 #include "skia/ext/image_operations.h"
80 #include "skia/ext/platform_canvas.h" 81 #include "skia/ext/platform_canvas.h"
82 #include "storage/browser/fileapi/isolated_context.h"
81 #include "third_party/WebKit/public/web/WebCompositionUnderline.h" 83 #include "third_party/WebKit/public/web/WebCompositionUnderline.h"
84 #include "ui/base/clipboard/clipboard.h"
82 #include "ui/events/blink/web_input_event_traits.h" 85 #include "ui/events/blink/web_input_event_traits.h"
83 #include "ui/events/event.h" 86 #include "ui/events/event.h"
84 #include "ui/events/keycodes/keyboard_codes.h" 87 #include "ui/events/keycodes/keyboard_codes.h"
85 #include "ui/gfx/color_space.h" 88 #include "ui/gfx/color_space.h"
86 #include "ui/gfx/geometry/size_conversions.h" 89 #include "ui/gfx/geometry/size_conversions.h"
87 #include "ui/gfx/geometry/vector2d_conversions.h" 90 #include "ui/gfx/geometry/vector2d_conversions.h"
88 #include "ui/gfx/image/image_skia.h" 91 #include "ui/gfx/image/image_skia.h"
89 #include "ui/gfx/skbitmap_operations.h" 92 #include "ui/gfx/skbitmap_operations.h"
90 #include "ui/snapshot/snapshot.h" 93 #include "ui/snapshot/snapshot.h"
91 94
92 #if defined(OS_MACOSX) 95 #if defined(OS_MACOSX)
93 #include "device/power_save_blocker/power_save_blocker.h" 96 #include "device/power_save_blocker/power_save_blocker.h"
94 #include "ui/accelerated_widget_mac/window_resize_helper_mac.h" 97 #include "ui/accelerated_widget_mac/window_resize_helper_mac.h"
95 #endif 98 #endif
96 99
97 using base::Time; 100 using base::Time;
98 using base::TimeDelta; 101 using base::TimeDelta;
99 using base::TimeTicks; 102 using base::TimeTicks;
103 using blink::WebDragOperationsMask;
100 using blink::WebGestureEvent; 104 using blink::WebGestureEvent;
101 using blink::WebInputEvent; 105 using blink::WebInputEvent;
102 using blink::WebKeyboardEvent; 106 using blink::WebKeyboardEvent;
103 using blink::WebMouseEvent; 107 using blink::WebMouseEvent;
104 using blink::WebMouseWheelEvent; 108 using blink::WebMouseWheelEvent;
105 using blink::WebTextDirection; 109 using blink::WebTextDirection;
106 110
107 namespace content { 111 namespace content {
108 namespace { 112 namespace {
109 113
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
175 wrap_gesture_scroll_end.type = blink::WebInputEvent::GestureScrollEnd; 179 wrap_gesture_scroll_end.type = blink::WebInputEvent::GestureScrollEnd;
176 wrap_gesture_scroll_end.timeStampSeconds = gesture_event.timeStampSeconds; 180 wrap_gesture_scroll_end.timeStampSeconds = gesture_event.timeStampSeconds;
177 wrap_gesture_scroll_end.sourceDevice = gesture_event.sourceDevice; 181 wrap_gesture_scroll_end.sourceDevice = gesture_event.sourceDevice;
178 wrap_gesture_scroll_end.resendingPluginId = gesture_event.resendingPluginId; 182 wrap_gesture_scroll_end.resendingPluginId = gesture_event.resendingPluginId;
179 wrap_gesture_scroll_end.data.scrollEnd.deltaUnits = 183 wrap_gesture_scroll_end.data.scrollEnd.deltaUnits =
180 gesture_event.data.scrollUpdate.deltaUnits; 184 gesture_event.data.scrollUpdate.deltaUnits;
181 185
182 return wrap_gesture_scroll_end; 186 return wrap_gesture_scroll_end;
183 } 187 }
184 188
189 std::vector<DropData::Metadata> DropDataToMetaData(const DropData& drop_data) {
190 std::vector<DropData::Metadata> metadata;
191 if (!drop_data.text.is_null()) {
192 metadata.push_back(DropData::Metadata::CreateForMimeType(
193 DropData::Kind::STRING,
194 base::ASCIIToUTF16(ui::Clipboard::kMimeTypeText)));
195 }
196
197 if (drop_data.url.is_valid()) {
198 metadata.push_back(DropData::Metadata::CreateForMimeType(
199 DropData::Kind::STRING,
200 base::ASCIIToUTF16(ui::Clipboard::kMimeTypeURIList)));
201 }
202
203 if (!drop_data.html.is_null()) {
204 metadata.push_back(DropData::Metadata::CreateForMimeType(
205 DropData::Kind::STRING,
206 base::ASCIIToUTF16(ui::Clipboard::kMimeTypeHTML)));
207 }
208
209 // On Aura, filenames are available before drop.
210 for (const auto& file_info : drop_data.filenames) {
211 if (!file_info.path.empty()) {
212 metadata.push_back(DropData::Metadata::CreateForFilePath(file_info.path));
213 }
214 }
215
216 // On Android, only files' mime types are available before drop.
217 for (const auto& mime_type : drop_data.file_mime_types) {
218 if (!mime_type.empty()) {
219 metadata.push_back(DropData::Metadata::CreateForMimeType(
220 DropData::Kind::FILENAME, mime_type));
221 }
222 }
223
224 for (const auto& file_system_file : drop_data.file_system_files) {
225 if (!file_system_file.url.is_empty()) {
226 metadata.push_back(
227 DropData::Metadata::CreateForFileSystemUrl(file_system_file.url));
228 }
229 }
230
231 for (const auto& custom_data_item : drop_data.custom_data) {
232 metadata.push_back(DropData::Metadata::CreateForMimeType(
233 DropData::Kind::STRING, custom_data_item.first));
234 }
235
236 return metadata;
237 }
238
185 } // namespace 239 } // namespace
186 240
187 /////////////////////////////////////////////////////////////////////////////// 241 ///////////////////////////////////////////////////////////////////////////////
188 // RenderWidgetHostImpl 242 // RenderWidgetHostImpl
189 243
190 RenderWidgetHostImpl::RenderWidgetHostImpl(RenderWidgetHostDelegate* delegate, 244 RenderWidgetHostImpl::RenderWidgetHostImpl(RenderWidgetHostDelegate* delegate,
191 RenderProcessHost* process, 245 RenderProcessHost* process,
192 int32_t routing_id, 246 int32_t routing_id,
193 bool hidden) 247 bool hidden)
194 : renderer_initialized_(false), 248 : renderer_initialized_(false),
(...skipping 1076 matching lines...) Expand 10 before | Expand all | Expand 10 after
1271 if (IsUseZoomForDSFEnabled()) 1325 if (IsUseZoomForDSFEnabled())
1272 input_router_->SetDeviceScaleFactor(result->device_scale_factor); 1326 input_router_->SetDeviceScaleFactor(result->device_scale_factor);
1273 } 1327 }
1274 1328
1275 void RenderWidgetHostImpl::HandleCompositorProto( 1329 void RenderWidgetHostImpl::HandleCompositorProto(
1276 const std::vector<uint8_t>& proto) { 1330 const std::vector<uint8_t>& proto) {
1277 DCHECK(!proto.empty()); 1331 DCHECK(!proto.empty());
1278 Send(new ViewMsg_HandleCompositorProto(GetRoutingID(), proto)); 1332 Send(new ViewMsg_HandleCompositorProto(GetRoutingID(), proto));
1279 } 1333 }
1280 1334
1335 void RenderWidgetHostImpl::DragTargetDragEnter(
1336 const DropData& drop_data,
1337 const gfx::Point& client_pt,
1338 const gfx::Point& screen_pt,
1339 WebDragOperationsMask operations_allowed,
1340 int key_modifiers) {
1341 DragTargetDragEnterWithMetaData(DropDataToMetaData(drop_data), client_pt,
1342 screen_pt, operations_allowed, key_modifiers);
1343 }
1344
1345 void RenderWidgetHostImpl::DragTargetDragEnterWithMetaData(
1346 const std::vector<DropData::Metadata>& metadata,
1347 const gfx::Point& client_pt,
1348 const gfx::Point& screen_pt,
1349 WebDragOperationsMask operations_allowed,
1350 int key_modifiers) {
1351 Send(new DragMsg_TargetDragEnter(GetRoutingID(), metadata, client_pt,
1352 screen_pt, operations_allowed,
1353 key_modifiers));
1354 }
1355
1356 void RenderWidgetHostImpl::DragTargetDragOver(
1357 const gfx::Point& client_pt,
1358 const gfx::Point& screen_pt,
1359 WebDragOperationsMask operations_allowed,
1360 int key_modifiers) {
1361 Send(new DragMsg_TargetDragOver(GetRoutingID(), client_pt, screen_pt,
1362 operations_allowed, key_modifiers));
1363 }
1364
1365 void RenderWidgetHostImpl::DragTargetDragLeave() {
1366 Send(new DragMsg_TargetDragLeave(GetRoutingID()));
1367 }
1368
1369 void RenderWidgetHostImpl::DragTargetDrop(const DropData& drop_data,
1370 const gfx::Point& client_pt,
1371 const gfx::Point& screen_pt,
1372 int key_modifiers) {
1373 DropData drop_data_with_permissions(drop_data);
1374 GrantFileAccessFromDropData(&drop_data_with_permissions);
1375 Send(new DragMsg_TargetDrop(GetRoutingID(), drop_data_with_permissions,
1376 client_pt, screen_pt, key_modifiers));
1377 }
1378
1379 void RenderWidgetHostImpl::FilterDropData(DropData* drop_data) {
1380 #if DCHECK_IS_ON()
1381 drop_data->view_id = GetRoutingID();
1382 #endif // DCHECK_IS_ON()
1383
1384 GetProcess()->FilterURL(true, &drop_data->url);
1385 if (drop_data->did_originate_from_renderer) {
1386 drop_data->filenames.clear();
1387 }
1388 }
1389
1281 void RenderWidgetHostImpl::NotifyScreenInfoChanged() { 1390 void RenderWidgetHostImpl::NotifyScreenInfoChanged() {
1282 if (delegate_) 1391 if (delegate_)
1283 delegate_->ScreenInfoChanged(); 1392 delegate_->ScreenInfoChanged();
1284 1393
1285 // The resize message (which may not happen immediately) will carry with it 1394 // The resize message (which may not happen immediately) will carry with it
1286 // the screen info as well as the new size (if the screen has changed scale 1395 // the screen info as well as the new size (if the screen has changed scale
1287 // factor). 1396 // factor).
1288 WasResized(); 1397 WasResized();
1289 } 1398 }
1290 1399
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
1345 if (view_) 1454 if (view_)
1346 view_->SetNeedsBeginFrames(needs_begin_frames); 1455 view_->SetNeedsBeginFrames(needs_begin_frames);
1347 } 1456 }
1348 1457
1349 void RenderWidgetHostImpl::OnStartDragging( 1458 void RenderWidgetHostImpl::OnStartDragging(
1350 const DropData& drop_data, 1459 const DropData& drop_data,
1351 blink::WebDragOperationsMask drag_operations_mask, 1460 blink::WebDragOperationsMask drag_operations_mask,
1352 const SkBitmap& bitmap, 1461 const SkBitmap& bitmap,
1353 const gfx::Vector2d& bitmap_offset_in_dip, 1462 const gfx::Vector2d& bitmap_offset_in_dip,
1354 const DragEventSourceInfo& event_info) { 1463 const DragEventSourceInfo& event_info) {
1464 // TODO(paulmeyer): Stop relying on RenderViewHost once
1465 // DragSourceSystemDragEnded is moved into RenderWidgetHost. See
1466 // crbug.com/647249.
1355 RenderViewHost* rvh = RenderViewHost::From(this); 1467 RenderViewHost* rvh = RenderViewHost::From(this);
1356 if (!rvh) 1468 if (!rvh)
1357 return; 1469 return;
1358 1470
1359 RenderViewHostDelegateView* view = delegate_->GetDelegateView(); 1471 RenderViewHostDelegateView* view = delegate_->GetDelegateView();
1360 if (!view) { 1472 if (!view) {
1361 // Need to clear drag and drop state in blink. 1473 // Need to clear drag and drop state in blink.
1362 rvh->DragSourceSystemDragEnded(); 1474 rvh->DragSourceSystemDragEnded();
1363 return; 1475 return;
1364 } 1476 }
(...skipping 15 matching lines...) Expand all
1380 // 3. DnD operation immediately ends since mouse is not held down. DnD events 1492 // 3. DnD operation immediately ends since mouse is not held down. DnD events
1381 // still fire though, which causes read permissions to be granted to the 1493 // still fire though, which causes read permissions to be granted to the
1382 // renderer for any file paths in the drop. 1494 // renderer for any file paths in the drop.
1383 filtered_data.filenames.clear(); 1495 filtered_data.filenames.clear();
1384 for (const auto& file_info : drop_data.filenames) { 1496 for (const auto& file_info : drop_data.filenames) {
1385 if (policy->CanReadFile(GetProcess()->GetID(), file_info.path)) 1497 if (policy->CanReadFile(GetProcess()->GetID(), file_info.path))
1386 filtered_data.filenames.push_back(file_info); 1498 filtered_data.filenames.push_back(file_info);
1387 } 1499 }
1388 1500
1389 storage::FileSystemContext* file_system_context = 1501 storage::FileSystemContext* file_system_context =
1390 BrowserContext::GetStoragePartition(GetProcess()->GetBrowserContext(), 1502 GetProcess()->GetStoragePartition()->GetFileSystemContext();
1391 rvh->GetSiteInstance())
1392 ->GetFileSystemContext();
1393 filtered_data.file_system_files.clear(); 1503 filtered_data.file_system_files.clear();
1394 for (size_t i = 0; i < drop_data.file_system_files.size(); ++i) { 1504 for (size_t i = 0; i < drop_data.file_system_files.size(); ++i) {
1395 storage::FileSystemURL file_system_url = 1505 storage::FileSystemURL file_system_url =
1396 file_system_context->CrackURL(drop_data.file_system_files[i].url); 1506 file_system_context->CrackURL(drop_data.file_system_files[i].url);
1397 if (policy->CanReadFileSystemFile(GetProcess()->GetID(), file_system_url)) 1507 if (policy->CanReadFileSystemFile(GetProcess()->GetID(), file_system_url))
1398 filtered_data.file_system_files.push_back(drop_data.file_system_files[i]); 1508 filtered_data.file_system_files.push_back(drop_data.file_system_files[i]);
1399 } 1509 }
1400 1510
1401 float scale = GetScaleFactorForView(GetView()); 1511 float scale = GetScaleFactorForView(GetView());
1402 gfx::ImageSkia image(gfx::ImageSkiaRep(bitmap, scale)); 1512 gfx::ImageSkia image(gfx::ImageSkiaRep(bitmap, scale));
(...skipping 869 matching lines...) Expand 10 before | Expand all | Expand 10 after
2272 RenderWidgetHostImpl::GetRootBrowserAccessibilityManager() { 2382 RenderWidgetHostImpl::GetRootBrowserAccessibilityManager() {
2273 return delegate_ ? delegate_->GetRootBrowserAccessibilityManager() : NULL; 2383 return delegate_ ? delegate_->GetRootBrowserAccessibilityManager() : NULL;
2274 } 2384 }
2275 2385
2276 BrowserAccessibilityManager* 2386 BrowserAccessibilityManager*
2277 RenderWidgetHostImpl::GetOrCreateRootBrowserAccessibilityManager() { 2387 RenderWidgetHostImpl::GetOrCreateRootBrowserAccessibilityManager() {
2278 return delegate_ ? 2388 return delegate_ ?
2279 delegate_->GetOrCreateRootBrowserAccessibilityManager() : NULL; 2389 delegate_->GetOrCreateRootBrowserAccessibilityManager() : NULL;
2280 } 2390 }
2281 2391
2392 void RenderWidgetHostImpl::GrantFileAccessFromDropData(DropData* drop_data) {
2393 DCHECK_EQ(GetRoutingID(), drop_data->view_id);
2394 const int renderer_id = GetProcess()->GetID();
2395 ChildProcessSecurityPolicyImpl* policy =
2396 ChildProcessSecurityPolicyImpl::GetInstance();
2397
2398 #if defined(OS_CHROMEOS)
2399 // The externalfile:// scheme is used in Chrome OS to open external files in a
2400 // browser tab.
2401 if (drop_data->url.SchemeIs(content::kExternalFileScheme))
2402 policy->GrantRequestURL(renderer_id, drop_data->url);
2403 #endif
2404
2405 // The filenames vector represents a capability to access the given files.
2406 storage::IsolatedContext::FileInfoSet files;
2407 for (auto& filename : drop_data->filenames) {
2408 // Make sure we have the same display_name as the one we register.
2409 if (filename.display_name.empty()) {
2410 std::string name;
2411 files.AddPath(filename.path, &name);
2412 filename.display_name = base::FilePath::FromUTF8Unsafe(name);
2413 } else {
2414 files.AddPathWithName(filename.path,
2415 filename.display_name.AsUTF8Unsafe());
2416 }
2417 // A dragged file may wind up as the value of an input element, or it
2418 // may be used as the target of a navigation instead. We don't know
2419 // which will happen at this point, so generously grant both access
2420 // and request permissions to the specific file to cover both cases.
2421 // We do not give it the permission to request all file:// URLs.
2422 policy->GrantRequestSpecificFileURL(renderer_id,
2423 net::FilePathToFileURL(filename.path));
2424
2425 // If the renderer already has permission to read these paths, we don't need
2426 // to re-grant them. This prevents problems with DnD for files in the CrOS
2427 // file manager--the file manager already had read/write access to those
2428 // directories, but dragging a file would cause the read/write access to be
2429 // overwritten with read-only access, making them impossible to delete or
2430 // rename until the renderer was killed.
2431 if (!policy->CanReadFile(renderer_id, filename.path))
2432 policy->GrantReadFile(renderer_id, filename.path);
2433 }
2434
2435 storage::IsolatedContext* isolated_context =
2436 storage::IsolatedContext::GetInstance();
2437 DCHECK(isolated_context);
2438
2439 if (!files.fileset().empty()) {
2440 std::string filesystem_id =
2441 isolated_context->RegisterDraggedFileSystem(files);
2442 if (!filesystem_id.empty()) {
2443 // Grant the permission iff the ID is valid.
2444 policy->GrantReadFileSystem(renderer_id, filesystem_id);
2445 }
2446 drop_data->filesystem_id = base::UTF8ToUTF16(filesystem_id);
2447 }
2448
2449 storage::FileSystemContext* file_system_context =
2450 GetProcess()->GetStoragePartition()->GetFileSystemContext();
2451 for (auto& file_system_file : drop_data->file_system_files) {
2452 storage::FileSystemURL file_system_url =
2453 file_system_context->CrackURL(file_system_file.url);
2454
2455 std::string register_name;
2456 std::string filesystem_id = isolated_context->RegisterFileSystemForPath(
2457 file_system_url.type(), file_system_url.filesystem_id(),
2458 file_system_url.path(), &register_name);
2459
2460 if (!filesystem_id.empty()) {
2461 // Grant the permission iff the ID is valid.
2462 policy->GrantReadFileSystem(renderer_id, filesystem_id);
2463 }
2464
2465 // Note: We are using the origin URL provided by the sender here. It may be
2466 // different from the receiver's.
2467 file_system_file.url =
2468 GURL(storage::GetIsolatedFileSystemRootURIString(
2469 file_system_url.origin(), filesystem_id, std::string())
2470 .append(register_name));
2471 }
2472 }
2473
2282 } // namespace content 2474 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/renderer_host/render_widget_host_impl.h ('k') | content/browser/web_contents/web_contents_view_android.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698