Commit da6245e7 authored by Andrey Kosyakov's avatar Andrey Kosyakov Committed by Commit Bot

DevTools: add IO.resolveBlob

This adds a protocol method to obtain the UUID of a Blob based on a
remote object id.
The intended usage is in conjunction with IO.read that would be able
to read the contents of a Blob on the browser side.

Bug: 747508

Change-Id: I18b7395833265665d80493f611888285f9730458
Reviewed-on: https://chromium-review.googlesource.com/580353
Commit-Queue: Andrey Kosyakov <caseq@chromium.org>
Reviewed-by: default avatarDmitry Gozman <dgozman@chromium.org>
Cr-Commit-Position: refs/heads/master@{#488751}
parent 96af2279
...@@ -29,7 +29,8 @@ ...@@ -29,7 +29,8 @@
}, },
{ {
"domain": "IO", "domain": "IO",
"async": ["read"] "async": ["read"],
"exclude": ["resolveBlob"]
}, },
{ {
"domain": "Memory", "domain": "Memory",
......
Tests IO.resolveBlob method
Blobs:
uuid_a: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
uuid_b: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
uuid_a != uuid_b: true
Not a blob:
error:{"code":-32000,"message":"Object id doesn't reference a Blob"}
Bad id:
error:{"code":-32000,"message":"Invalid remote object id"}
(async function(testRunner) {
let {page, session, dp} = await testRunner.startBlank('Tests IO.resolveBlob method');
async function createBlob(content) {
const result = await dp.Runtime.evaluate({expression: `new Blob(["${content}"])`});
return result.result.result.objectId;
}
testRunner.log('Blobs:');
const blobA = await createBlob('a');
const blobB = await createBlob('b');
const uuid_a = (await dp.IO.resolveBlob({objectId: blobA})).result.uuid;
const uuid_b = (await dp.IO.resolveBlob({objectId: blobB})).result.uuid;
testRunner.log('uuid_a: ' + uuid_a.replace(/[a-z0-9]/g, 'x'));
testRunner.log('uuid_b: ' + uuid_b.replace(/[a-z0-9]/g, 'x'));
testRunner.log('uuid_a != uuid_b: ' + (uuid_a != uuid_b));
testRunner.log('Not a blob:');
const objectId = (await dp.Runtime.evaluate({expression: '({})'})).result.result.objectId;
let error = (await dp.IO.resolveBlob({'objectId': objectId})).error;
testRunner.log('error:' + JSON.stringify(error));
testRunner.log('Bad id:');
error = (await dp.IO.resolveBlob({objectId: 'boo'})).error;
testRunner.log('error:' + JSON.stringify(error));
testRunner.completeTest();
})
\ No newline at end of file
...@@ -53,6 +53,7 @@ ...@@ -53,6 +53,7 @@
#include "core/inspector/InspectorDOMDebuggerAgent.h" #include "core/inspector/InspectorDOMDebuggerAgent.h"
#include "core/inspector/InspectorDOMSnapshotAgent.h" #include "core/inspector/InspectorDOMSnapshotAgent.h"
#include "core/inspector/InspectorEmulationAgent.h" #include "core/inspector/InspectorEmulationAgent.h"
#include "core/inspector/InspectorIOAgent.h"
#include "core/inspector/InspectorInputAgent.h" #include "core/inspector/InspectorInputAgent.h"
#include "core/inspector/InspectorLayerTreeAgent.h" #include "core/inspector/InspectorLayerTreeAgent.h"
#include "core/inspector/InspectorLogAgent.h" #include "core/inspector/InspectorLogAgent.h"
...@@ -366,6 +367,8 @@ InspectorSession* WebDevToolsAgentImpl::InitializeSession(int session_id, ...@@ -366,6 +367,8 @@ InspectorSession* WebDevToolsAgentImpl::InitializeSession(int session_id,
overlay_agents_.Set(session_id, overlay_agent); overlay_agents_.Set(session_id, overlay_agent);
session->Append(overlay_agent); session->Append(overlay_agent);
session->Append(new InspectorIOAgent(isolate, session->V8Session()));
tracing_agent->SetLayerTreeId(layer_tree_id_); tracing_agent->SetLayerTreeId(layer_tree_id_);
network_agent->SetHostId(host_id); network_agent->SetHostId(host_id);
......
...@@ -50,6 +50,8 @@ blink_core_sources("inspector") { ...@@ -50,6 +50,8 @@ blink_core_sources("inspector") {
"InspectorHighlight.h", "InspectorHighlight.h",
"InspectorHistory.cpp", "InspectorHistory.cpp",
"InspectorHistory.h", "InspectorHistory.h",
"InspectorIOAgent.cpp",
"InspectorIOAgent.h",
"InspectorInputAgent.cpp", "InspectorInputAgent.cpp",
"InspectorInputAgent.h", "InspectorInputAgent.h",
"InspectorLayerTreeAgent.cpp", "InspectorLayerTreeAgent.cpp",
......
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "core/inspector/InspectorIOAgent.h"
#include "bindings/core/v8/V8Blob.h"
#include "core/fileapi/Blob.h"
#include "v8/include/v8-inspector.h"
namespace blink {
using protocol::Response;
InspectorIOAgent::InspectorIOAgent(v8::Isolate* isolate,
v8_inspector::V8InspectorSession* session)
: isolate_(isolate), v8_session_(session) {}
InspectorIOAgent::~InspectorIOAgent() = default;
Response InspectorIOAgent::resolveBlob(const String& object_id, String* uuid) {
v8::HandleScope handles(isolate_);
v8::Local<v8::Value> value;
v8::Local<v8::Context> context;
std::unique_ptr<v8_inspector::StringBuffer> error;
if (!v8_session_->unwrapObject(&error, ToV8InspectorStringView(object_id),
&value, &context, nullptr)) {
return Response::Error(ToCoreString(std::move(error)));
}
if (!V8Blob::hasInstance(value, isolate_))
return Response::Error("Object id doesn't reference a Blob");
Blob* blob = V8Blob::toImpl(v8::Local<v8::Object>::Cast(value));
if (!blob) {
return Response::Error(
"Couldn't convert object with given objectId to Blob");
}
*uuid = blob->Uuid();
return Response::OK();
}
} // namespace blink
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef InspectorIOAgent_h
#define InspectorIOAgent_h
#include "core/CoreExport.h"
#include "core/inspector/InspectorBaseAgent.h"
#include "core/inspector/protocol/IO.h"
#include "platform/wtf/Noncopyable.h"
#include "platform/wtf/text/WTFString.h"
namespace v8 {
class Isolate;
}
namespace v8_inspector {
class V8InspectorSession;
}
namespace blink {
class CORE_EXPORT InspectorIOAgent final
: public InspectorBaseAgent<protocol::IO::Metainfo> {
WTF_MAKE_NONCOPYABLE(InspectorIOAgent);
public:
InspectorIOAgent(v8::Isolate*, v8_inspector::V8InspectorSession*);
private:
~InspectorIOAgent() override;
// Called from the front-end.
protocol::Response resolveBlob(const String& object_id,
String* uuid) override;
v8::Isolate* isolate_;
v8_inspector::V8InspectorSession* v8_session_;
};
} // namespace blink
#endif // !defined(InspectorIOAgent_h)
...@@ -3470,6 +3470,7 @@ ...@@ -3470,6 +3470,7 @@
{ {
"domain": "IO", "domain": "IO",
"description": "Input/Output operations for streams produced by DevTools.", "description": "Input/Output operations for streams produced by DevTools.",
"dependencies": ["Runtime"],
"experimental": true, "experimental": true,
"types": [ "types": [
{ {
...@@ -3497,6 +3498,16 @@ ...@@ -3497,6 +3498,16 @@
"parameters": [ "parameters": [
{ "name": "handle", "$ref": "StreamHandle", "description": "Handle of the stream to close." } { "name": "handle", "$ref": "StreamHandle", "description": "Handle of the stream to close." }
] ]
},
{
"name": "resolveBlob",
"parameters": [
{ "name": "objectId", "$ref": "Runtime.RemoteObjectId", "description": "Object id of a Blob object wrapper." }
],
"returns": [
{ "name": "uuid", "type": "string", "description": "UUID of the specified Blob." }
],
"description": "Return UUID of Blob object specified by a remote object id."
} }
] ]
}, },
......
...@@ -62,7 +62,7 @@ ...@@ -62,7 +62,7 @@
}, },
{ {
"domain": "IO", "domain": "IO",
"include": [] "include": ["resolveBlob"]
}, },
{ {
"domain": "Security", "domain": "Security",
......
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