DevTools Network Agent implementation #725
Conversation
add generated Network backend/frontend dispatchers
…ion on debugger connection
…the app is built in debug or release expose __inspector object to the global JS object that has callbacks for co mmunicating with the devtools inspector frontend rename loaderId in Page agent implementation to be matching with the one used in the network agent - NSLoaderIndentifier
update project template code to pass an additional parameter to StaticConfig
|
💚 |
|
PR can be tested internally with the Groceries project: |
|
|
||
| public class Runtime { | ||
| private native void initNativeScript(int runtimeId, String filesPath, String nativeLibDir, boolean verboseLoggingEnabled, String packageName, Object[] v8Options, String callingDir); | ||
| private native void initNativeScript(int runtimeId, String filesPath, String nativeLibDir, boolean verboseLoggingEnabled, boolean isDebuggable, String packageName, Object[] v8Options, String callingDir); |
There was a problem hiding this comment.
8 Parameters sound like refactoring and class
There was a problem hiding this comment.
Passing raw objects as parameters through JNI is much less cumbersome to deal with on the native (C++) side as it won't require precaching fieldIds for each (8 in total) of the properties.
|
|
||
| v8::Local<v8::Object> argsObj = args[0]->ToObject(); | ||
|
|
||
| if ((!argsObj->Has(context, ArgConverter::ConvertToV8String(isolate, "requestId")).FromMaybe(false) || |
There was a problem hiding this comment.
do you think it's ok these to be constants? we repeat them twice here
There was a problem hiding this comment.
Do you think all of the strings that we check for should be constants, or just some of them?
|
|
||
| v8::Local<v8::Object> argsObj = args[0]->ToObject(); | ||
|
|
||
| if ((!argsObj->Has(context, ArgConverter::ConvertToV8String(isolate, "requestId")).FromMaybe(false) || |
There was a problem hiding this comment.
why not use a for statement - we check for 4 different parameters in the same pattern
There was a problem hiding this comment.
The v8::Object has no iterator, and while we can go over all of its properties (https://github.com/NativeScript/android-runtime/blob/master/runtime/src/main/jni/include/v8.h#L3086 GetOwnPropertyNames), we will still have to validate each one.
| "Not all parameters are present in the object argument in the call to ResponseReceived! Required params: 'requestId', `timestamp`, `type`, `response`"); | ||
| } | ||
|
|
||
| auto requestId = argsObj->Get(context, ArgConverter::ConvertToV8String(isolate, "requestId")).ToLocalChecked()->ToString(); |
There was a problem hiding this comment.
can we extract the validation + extraction logic to a function which returns a struct/class?
There was a problem hiding this comment.
We can certainly move the validation and extraction in separate methods, but it won't be one universal method that can validate each and every callback, so I don't think there will be use of separate validation.
|
|
||
| static void LoadingFinishedCallback(const v8::FunctionCallbackInfo<v8::Value>& args) { | ||
| try { | ||
| auto networkAgentInstance = V8NetworkAgentImpl::Instance; |
There was a problem hiding this comment.
This is seen at least 3 times. Can we make a Guard method and extract this functionality there?
There was a problem hiding this comment.
I am not sure making a Guard method will make the code more readable than it is right now. We will have to check whether the guard has passed, and code will look almost the same.
| NetworkRequestData::NetworkRequestData() | ||
| : m_data(""), | ||
| m_hasTextContent(true) { } | ||
| NetworkRequestData::NetworkRequestData(std::string data, bool hasTextContent) |
| nsEx.ReThrowToV8(); | ||
| } | ||
| } | ||
| } |
There was a problem hiding this comment.
strange identation for the 3 }}}
There was a problem hiding this comment.
Code is formatted according to the tool used - astyle. https://github.com/NativeScript/android-runtime/blob/master/tools/astyle.js#L11
| } | ||
|
|
||
| void setHasTextContent(const bool hasTextContent) { | ||
| m_hasTextContent = hasTextContent; |
There was a problem hiding this comment.
Do we have a convention to use this-> for instance members?
| namespace v8_inspector { | ||
|
|
||
| namespace NetworkAgentState { | ||
| static const char networkEnabled[] = "networkEnabled"; |
There was a problem hiding this comment.
identation is not ok here
There was a problem hiding this comment.
Indentation is according to the formatting tool used - astyle. https://github.com/NativeScript/android-runtime/blob/master/tools/astyle.js#L11
| namespace v8_inspector { | ||
|
|
||
| namespace NetworkAgentState { | ||
| static const char networkEnabled[] = "networkEnabled"; |
There was a problem hiding this comment.
aren't constants upperCase-named by convention? You can give me a convention for the C++ code we right, so that I don't write dummy comments :)
There was a problem hiding this comment.
I've simply used the same convention that was in place by the default v8 inspector implementations that came from the chromium project -> https://github.com/NativeScript/android-runtime/blob/master/runtime/src/main/jni/v8_inspector/src/inspector/v8-profiler-agent-impl.cc#L24
| try { | ||
| v8Inspector = new AndroidJsV8Inspector(app, logger); | ||
| v8Inspector.start(); | ||
| File debugBreakFile = new File("/data/local/tmp", app.getPackageName() + "-debugger-started"); |
There was a problem hiding this comment.
what's the reasoning here?
There was a problem hiding this comment.
Oops, must have committed this by mistake. Nice catch!
Plamen5kov
left a comment
There was a problem hiding this comment.
In modules implementation: https://github.com/NativeScript/NativeScript/blob/master/tns-core-modules/debugger/debugger.ts#L169
Please check that mimetype exists before doing operations on it.
|
@Plamen5kov addressed in NativeScript/NativeScript#3867 |
|
💚 |
|
💚 |
Plamen5kov
left a comment
There was a problem hiding this comment.
After running builds and a fix for the commented issue.
|
|
||
| inspectorJSObject->Set(ArgConverter::ConvertToV8String(isolate, "responseReceived"), FunctionTemplate::New(isolate, NetworkDomainCallbackHandlers::ResponseReceivedCallback)); | ||
| inspectorJSObject->Set(ArgConverter::ConvertToV8String(isolate, "requestWillBeSent"), FunctionTemplate::New(isolate, NetworkDomainCallbackHandlers::RequestWillBeSentCallback)); | ||
| inspectorJSObject->Set(ArgConverter::ConvertToV8String(isolate, "dataForRequestId"), FunctionTemplate::New(isolate, NetworkDomainCallbackHandlers::DataForRequestId)); |
There was a problem hiding this comment.
DataForRequestId -> DataForRequestIdCallback
| static const char* FrameId = "NSFrameIdentifier"; | ||
| static const char* LoaderId = "NSLoaderIdentifier"; | ||
|
|
||
| static void ResponseReceivedCallback(const v8::FunctionCallbackInfo<v8::Value>& args) { |
There was a problem hiding this comment.
Extract all methods to a source file, and leave only the API in the header.
Please add comments on all methods, so their function is clear without reading the code. The name's just not verbose enough.
There was a problem hiding this comment.
Callbacks have since been documented. I'll just extract them as static members of a new class now.
| @@ -19,7 +20,8 @@ JsV8InspectorClient::JsV8InspectorClient(v8::Isolate* isolate) | |||
| session_(nullptr), | |||
| connection(nullptr), | |||
| context_(), | |||
There was a problem hiding this comment.
initialize context with default value
There was a problem hiding this comment.
It would be wrong to initialize the persistent container with value different than the default (0).
|
💚 |
The Runtime will now expose
__inspectorobject that contains methods for communicating directly with the DevTools frontend. JavaScript objects are constructed in compliance with the v8 inspector protocol and sent to the DevTools frontend when:Features:
Current limitations:
Associated issue: #715
Associated PRs:
Part of the #563 effort
Demo images (Click to enlarge):