Web Inspector: Optionally log WebKit log parameters as JSON
authoreric.carlson@apple.com <eric.carlson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 12 Dec 2017 00:41:54 +0000 (00:41 +0000)
committereric.carlson@apple.com <eric.carlson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 12 Dec 2017 00:41:54 +0000 (00:41 +0000)
https://bugs.webkit.org/show_bug.cgi?id=180529
<rdar://problem/35909462>

Reviewed by Joseph Pecoraro.

Source/JavaScriptCore:

* inspector/ConsoleMessage.cpp:
(Inspector::ConsoleMessage::ConsoleMessage): New constructor that takes a vector of JSON log
values. Concatenate all adjacent strings to make logging cleaner.
(Inspector::ConsoleMessage::addToFrontend): Process WebKit logging arguments.
(Inspector::ConsoleMessage::scriptState const):
* inspector/ConsoleMessage.h:

* inspector/InjectedScript.cpp:
(Inspector::InjectedScript::wrapJSONString const): Wrap JSON string log arguments.
* inspector/InjectedScript.h:
* inspector/InjectedScriptSource.js:
(let.InjectedScript.prototype.wrapJSONString):

Source/WebCore:

* dom/Document.cpp:
(WebCore::Document::didLogMessage):Update for API change. Don't check for main thread, that
is already done in addConsoleMessage.
* dom/Document.h:

* html/HTMLMediaElement.cpp:
(WebCore::HTMLMediaElement::updatePlayState): Cleanup logging.

* html/track/DataCue.cpp:
(WebCore::DataCue::toJSONString const): Serialize to JSON string.
(WebCore::DataCue::toString const): Deleted.
* html/track/DataCue.h:
(WTF::LogArgument<WebCore::DataCue>::toString):

* html/track/TextTrackCue.cpp:
(WebCore::TextTrackCue::toJSON const): Ditto.
(WebCore::TextTrackCue::toJSONString const):
(WebCore::TextTrackCue::toString const): Deleted.
* html/track/TextTrackCue.h:
(WTF::LogArgument<WebCore::TextTrackCue>::toString):

* html/track/TextTrackCueGeneric.cpp:
(WebCore::TextTrackCueGeneric::toJSONString const): Ditto.
(WebCore::TextTrackCueGeneric::toString const): Deleted.
* html/track/TextTrackCueGeneric.h:
(WTF::LogArgument<WebCore::TextTrackCueGeneric>::toString):

* html/track/VTTCue.cpp:
(WebCore::VTTCue::toJSONString const): Ditto.
(WebCore::VTTCue::toString const): Deleted.
* html/track/VTTCue.h:
(WTF::LogArgument<WebCore::VTTCue>::toString):

* platform/graphics/InbandTextTrackPrivateClient.h:
(WebCore::GenericCueData::toJSONString const): Ditto.
(WTF::LogArgument<WebCore::GenericCueData>::toString):
(WebCore::GenericCueData::toString const): Deleted.

* platform/graphics/avfoundation/InbandTextTrackPrivateAVF.cpp:
(WebCore::InbandTextTrackPrivateAVF::processAttributedStrings): Cleanup logging.
(WebCore::InbandTextTrackPrivateAVF::removeCompletedCues): Ditto.
(WebCore::InbandTextTrackPrivateAVF::processNativeSamples): Log the entire cue.
(WebCore::InbandTextTrackPrivateAVF::readNativeSampleBuffer): Cleanup logging.

* platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.cpp:
(WebCore::MediaPlayerPrivateAVFoundation::maxMediaTimeSeekable const): Don't log, it isn't
interesting and happens frequently.
(WebCore::MediaPlayerPrivateAVFoundation::minMediaTimeSeekable const): Ditto.

* platform/graphics/iso/ISOVTTCue.cpp:
(WebCore::ISOWebVTTCue::toJSONString const): Serialize to JSON string.

* platform/graphics/iso/ISOVTTCue.h:
(WTF::LogArgument<WebCore::ISOWebVTTCue>::toString): Ditto.

Source/WTF:

* wtf/Logger.h:
(WTF::Logger::log):
(WTF::LogArgument<Logger::LogSiteIdentifier>::toString):

* wtf/MediaTime.cpp:
(WTF::MediaTime::toJSONString const): Serialize to JSON string.
* wtf/MediaTime.h:

LayoutTests:

* inspector/canvas/recording-2d-expected.txt:
* inspector/canvas/recording-webgl-expected.txt:
* inspector/canvas/recording-webgl-snapshots-expected.txt:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@225764 268f45cc-cd09-0410-ab3c-d52691b4dbfc

31 files changed:
LayoutTests/ChangeLog
LayoutTests/inspector/canvas/recording-2d-expected.txt
LayoutTests/inspector/canvas/recording-webgl-expected.txt
LayoutTests/inspector/canvas/recording-webgl-snapshots-expected.txt
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/inspector/ConsoleMessage.cpp
Source/JavaScriptCore/inspector/ConsoleMessage.h
Source/JavaScriptCore/inspector/InjectedScript.cpp
Source/JavaScriptCore/inspector/InjectedScript.h
Source/JavaScriptCore/inspector/InjectedScriptSource.js
Source/WTF/ChangeLog
Source/WTF/wtf/Logger.h
Source/WTF/wtf/MediaTime.cpp
Source/WTF/wtf/MediaTime.h
Source/WebCore/ChangeLog
Source/WebCore/dom/Document.cpp
Source/WebCore/dom/Document.h
Source/WebCore/html/HTMLMediaElement.cpp
Source/WebCore/html/track/DataCue.cpp
Source/WebCore/html/track/DataCue.h
Source/WebCore/html/track/TextTrackCue.cpp
Source/WebCore/html/track/TextTrackCue.h
Source/WebCore/html/track/TextTrackCueGeneric.cpp
Source/WebCore/html/track/TextTrackCueGeneric.h
Source/WebCore/html/track/VTTCue.cpp
Source/WebCore/html/track/VTTCue.h
Source/WebCore/platform/graphics/InbandTextTrackPrivateClient.h
Source/WebCore/platform/graphics/avfoundation/InbandTextTrackPrivateAVF.cpp
Source/WebCore/platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.cpp
Source/WebCore/platform/graphics/iso/ISOVTTCue.cpp
Source/WebCore/platform/graphics/iso/ISOVTTCue.h

index eeff7719fd93d98096b476af3e90649e40d1a7fd..69428b12a7041be681360c198c319aca984b942b 100644 (file)
@@ -1,3 +1,15 @@
+2017-12-11  Eric Carlson  <eric.carlson@apple.com>
+
+        Web Inspector: Optionally log WebKit log parameters as JSON
+        https://bugs.webkit.org/show_bug.cgi?id=180529
+        <rdar://problem/35909462>
+
+        Reviewed by Joseph Pecoraro.
+
+        * inspector/canvas/recording-2d-expected.txt:
+        * inspector/canvas/recording-webgl-expected.txt:
+        * inspector/canvas/recording-webgl-snapshots-expected.txt:
+
 2017-12-11  Chris Dumez  <cdumez@apple.com>
 
         Layout Test http/tests/workers/service/postmessage-after-sw-process-crash.https.html is flaky
index bd51ce51e175769282ed946c968996e88a75448f..d72de1054f5324900e08e7c2248dc11172d9d26e 100644 (file)
@@ -88,9 +88,9 @@ data:
   25: "evaluateWithScopeExtension"
   26: [25,12,0,0]
   27: "_evaluateOn"
-  28: [27,10,128,29]
+  28: [27,10,130,29]
   29: "_evaluateAndWrap"
-  30: [29,10,122,108]
+  30: [29,10,124,108]
   31: [10,14,79,42]
   32: [10,14,79,28]
 
@@ -1096,9 +1096,9 @@ data:
   25: "evaluateWithScopeExtension"
   26: [25,12,0,0]
   27: "_evaluateOn"
-  28: [27,10,128,29]
+  28: [27,10,130,29]
   29: "_evaluateAndWrap"
-  30: [29,10,122,108]
+  30: [29,10,124,108]
   31: [10,14,79,42]
   32: [10,14,79,28]
   33: "arcTo"
@@ -1488,9 +1488,9 @@ data:
   25: "evaluateWithScopeExtension"
   26: [25,12,0,0]
   27: "_evaluateOn"
-  28: [27,10,128,29]
+  28: [27,10,130,29]
   29: "_evaluateAndWrap"
-  30: [29,10,122,108]
+  30: [29,10,124,108]
 
 -- Running test case: Canvas.recording2D.Console
 PASS: The recording should have the name "TEST".
index e1e64d381b582e944092da1320258e7ac0e573db..422cd4976031210cf2c417872f9c423e2804abd7 100644 (file)
@@ -39,9 +39,9 @@ data:
   12: "evaluateWithScopeExtension"
   13: [12,1,0,0]
   14: "_evaluateOn"
-  15: [14,3,128,29]
+  15: [14,3,130,29]
   16: "_evaluateAndWrap"
-  17: [16,3,122,108]
+  17: [16,3,124,108]
 
 -- Running test case: Canvas.recordingWebGL.multipleFrames
 initialState:
@@ -1041,9 +1041,9 @@ data:
   12: "evaluateWithScopeExtension"
   13: [12,1,0,0]
   14: "_evaluateOn"
-  15: [14,3,128,29]
+  15: [14,3,130,29]
   16: "_evaluateAndWrap"
-  17: [16,3,122,108]
+  17: [16,3,124,108]
   18: "attachShader"
   19: [18,1,0,0]
   20: [3,4,76,33]
@@ -1496,9 +1496,9 @@ data:
   12: "evaluateWithScopeExtension"
   13: [12,1,0,0]
   14: "_evaluateOn"
-  15: [14,3,128,29]
+  15: [14,3,130,29]
   16: "_evaluateAndWrap"
-  17: [16,3,122,108]
+  17: [16,3,124,108]
 
 -- Running test case: Canvas.recordingWebGL.Console
 PASS: The recording should have the name "TEST".
index a093b78eb4ef63772bff8868715699498cf0a4ff..ca13262380206722925c1d66d9b8314f231d0b5c 100644 (file)
@@ -149,9 +149,9 @@ data:
   9: "evaluateWithScopeExtension"
   10: [9,1,0,0]
   11: "_evaluateOn"
-  12: [11,7,128,29]
+  12: [11,7,130,29]
   13: "_evaluateAndWrap"
-  14: [13,7,122,108]
+  14: [13,7,124,108]
   15: "clearColor"
   16: [15,1,0,0]
   17: "clearContext"
index 5451efe724605086c490fdaca6284386f593c999..99d9b04238cc5c91e7b7450aa408b3167d476222 100644 (file)
@@ -1,3 +1,24 @@
+2017-12-11  Eric Carlson  <eric.carlson@apple.com>
+
+        Web Inspector: Optionally log WebKit log parameters as JSON
+        https://bugs.webkit.org/show_bug.cgi?id=180529
+        <rdar://problem/35909462>
+
+        Reviewed by Joseph Pecoraro.
+
+        * inspector/ConsoleMessage.cpp:
+        (Inspector::ConsoleMessage::ConsoleMessage): New constructor that takes a vector of JSON log
+        values. Concatenate all adjacent strings to make logging cleaner.
+        (Inspector::ConsoleMessage::addToFrontend): Process WebKit logging arguments.
+        (Inspector::ConsoleMessage::scriptState const):
+        * inspector/ConsoleMessage.h:
+
+        * inspector/InjectedScript.cpp:
+        (Inspector::InjectedScript::wrapJSONString const): Wrap JSON string log arguments.
+        * inspector/InjectedScript.h:
+        * inspector/InjectedScriptSource.js:
+        (let.InjectedScript.prototype.wrapJSONString):
+
 2017-12-11  Joseph Pecoraro  <pecoraro@apple.com>
 
         Remove unused builtin names
index c028aca9201534763f993bfb58d092b12d728dcc..d88d0f1bb0eb82e02f7e8264e988410a142a850f 100644 (file)
@@ -95,6 +95,43 @@ ConsoleMessage::ConsoleMessage(MessageSource source, MessageType type, MessageLe
     autogenerateMetadata(state);
 }
 
+ConsoleMessage::ConsoleMessage(MessageSource source, MessageType type, MessageLevel level, Vector<JSONLogValue>&& messages, JSC::ExecState* state, unsigned long requestIdentifier)
+    : m_source(source)
+    , m_type(type)
+    , m_level(level)
+    , m_url()
+    , m_scriptState(state)
+    , m_requestId(IdentifiersFactory::requestId(requestIdentifier))
+{
+    if (!messages.size())
+        return;
+
+    m_jsonLogValues.reserveInitialCapacity(messages.size());
+
+    StringBuilder builder;
+    for (auto& message : messages) {
+        switch (message.type) {
+        case JSONLogValue::Type::String:
+            builder.append(message.value);
+            break;
+        case JSONLogValue::Type::JSON:
+            if (builder.length()) {
+                m_jsonLogValues.append({ JSONLogValue::Type::String, JSON::Value::create(builder.toString())->toJSONString() });
+                builder.resize(0);
+            }
+
+            m_jsonLogValues.append(message);
+            break;
+        }
+    }
+
+    if (builder.length())
+        m_jsonLogValues.append({ JSONLogValue::Type::String, JSON::Value::create(builder.toString())->toJSONString() });
+
+    if (m_jsonLogValues.size())
+        m_message = m_jsonLogValues[0].value;
+}
+
 ConsoleMessage::~ConsoleMessage()
 {
 }
@@ -188,32 +225,48 @@ void ConsoleMessage::addToFrontend(ConsoleFrontendDispatcher& consoleFrontendDis
     if (m_source == MessageSource::Network && !m_requestId.isEmpty())
         messageObject->setNetworkRequestId(m_requestId);
 
-    if (m_arguments && m_arguments->argumentCount()) {
-        InjectedScript injectedScript = injectedScriptManager.injectedScriptFor(m_arguments->globalState());
+    if ((m_arguments && m_arguments->argumentCount()) || m_jsonLogValues.size()) {
+        InjectedScript injectedScript = injectedScriptManager.injectedScriptFor(scriptState());
         if (!injectedScript.hasNoValue()) {
             auto argumentsObject = JSON::ArrayOf<Inspector::Protocol::Runtime::RemoteObject>::create();
-            if (m_type == MessageType::Table && generatePreview && m_arguments->argumentCount()) {
-                Deprecated::ScriptValue table = m_arguments->argumentAt(0);
-                Deprecated::ScriptValue columns = m_arguments->argumentCount() > 1 ? m_arguments->argumentAt(1) : Deprecated::ScriptValue();
-                RefPtr<Inspector::Protocol::Runtime::RemoteObject> inspectorValue = injectedScript.wrapTable(table, columns);
-                if (!inspectorValue) {
-                    ASSERT_NOT_REACHED();
-                    return;
-                }
-                argumentsObject->addItem(inspectorValue.copyRef());
-                if (m_arguments->argumentCount() > 1)
-                    argumentsObject->addItem(injectedScript.wrapObject(columns, ASCIILiteral("console"), true));
-            } else {
-                for (unsigned i = 0; i < m_arguments->argumentCount(); ++i) {
-                    RefPtr<Inspector::Protocol::Runtime::RemoteObject> inspectorValue = injectedScript.wrapObject(m_arguments->argumentAt(i), ASCIILiteral("console"), generatePreview);
+            if (m_arguments && m_arguments->argumentCount()) {
+                if (m_type == MessageType::Table && generatePreview && m_arguments->argumentCount()) {
+                    Deprecated::ScriptValue table = m_arguments->argumentAt(0);
+                    Deprecated::ScriptValue columns = m_arguments->argumentCount() > 1 ? m_arguments->argumentAt(1) : Deprecated::ScriptValue();
+                    auto inspectorValue = injectedScript.wrapTable(table, columns);
                     if (!inspectorValue) {
                         ASSERT_NOT_REACHED();
                         return;
                     }
-                    argumentsObject->addItem(inspectorValue.copyRef());
+                    argumentsObject->addItem(WTFMove(inspectorValue));
+                    if (m_arguments->argumentCount() > 1)
+                        argumentsObject->addItem(injectedScript.wrapObject(columns, ASCIILiteral("console"), true));
+                } else {
+                    for (unsigned i = 0; i < m_arguments->argumentCount(); ++i) {
+                        auto inspectorValue = injectedScript.wrapObject(m_arguments->argumentAt(i), ASCIILiteral("console"), generatePreview);
+                        if (!inspectorValue) {
+                            ASSERT_NOT_REACHED();
+                            return;
+                        }
+                        argumentsObject->addItem(WTFMove(inspectorValue));
+                    }
                 }
             }
-            messageObject->setParameters(WTFMove(argumentsObject));
+
+            if (m_jsonLogValues.size()) {
+                for (auto& message : m_jsonLogValues) {
+                    if (message.value.isEmpty())
+                        continue;
+                    auto inspectorValue = injectedScript.wrapJSONString(message.value, ASCIILiteral("console"), generatePreview);
+                    if (!inspectorValue)
+                        continue;
+
+                    argumentsObject->addItem(WTFMove(inspectorValue));
+                }
+            }
+
+            if (argumentsObject->length())
+                messageObject->setParameters(WTFMove(argumentsObject));
         }
     }
 
@@ -272,6 +325,9 @@ JSC::ExecState* ConsoleMessage::scriptState() const
     if (m_arguments)
         return m_arguments->globalState();
 
+    if (m_scriptState)
+        return m_scriptState;
+
     return nullptr;
 }
 
index 0fce9718cd5006dd7c85b061528e1b900ddf5791..f3706dbb97925421487b215bbe8fd335c210aed1 100644 (file)
@@ -33,6 +33,7 @@
 #include "ConsoleTypes.h"
 #include <wtf/FastMalloc.h>
 #include <wtf/Forward.h>
+#include <wtf/Logger.h>
 #include <wtf/Noncopyable.h>
 #include <wtf/text/WTFString.h>
 
@@ -55,6 +56,7 @@ public:
     ConsoleMessage(MessageSource, MessageType, MessageLevel, const String& message, const String& url, unsigned line, unsigned column, JSC::ExecState* = nullptr, unsigned long requestIdentifier = 0);
     ConsoleMessage(MessageSource, MessageType, MessageLevel, const String& message, Ref<ScriptCallStack>&&, unsigned long requestIdentifier = 0);
     ConsoleMessage(MessageSource, MessageType, MessageLevel, const String& message, Ref<ScriptArguments>&&, JSC::ExecState*, unsigned long requestIdentifier = 0);
+    ConsoleMessage(MessageSource, MessageType, MessageLevel, Vector<JSONLogValue>&&, JSC::ExecState*, unsigned long requestIdentifier = 0);
     ~ConsoleMessage();
 
     void addToFrontend(ConsoleFrontendDispatcher&, InjectedScriptManager&, bool generatePreview);
@@ -87,7 +89,9 @@ private:
     String m_message;
     RefPtr<ScriptArguments> m_arguments;
     RefPtr<ScriptCallStack> m_callStack;
+    Vector<JSONLogValue> m_jsonLogValues;
     String m_url;
+    JSC::ExecState* m_scriptState { nullptr };
     unsigned m_line { 0 };
     unsigned m_column { 0 };
     unsigned m_repeatCount { 1 };
index d780f253c27ca1246bd85debd4984dcc93b5f7c3..3ca25c4da21cf7d0ef9ba19b6066b89e236a4329 100644 (file)
@@ -263,6 +263,29 @@ RefPtr<Inspector::Protocol::Runtime::RemoteObject> InjectedScript::wrapObject(JS
     return BindingTraits<Inspector::Protocol::Runtime::RemoteObject>::runtimeCast(resultObject);
 }
 
+RefPtr<Protocol::Runtime::RemoteObject> InjectedScript::wrapJSONString(const String& json, const String& groupName, bool generatePreview) const
+{
+    ASSERT(!hasNoValue());
+    Deprecated::ScriptFunctionCall wrapFunction(injectedScriptObject(), ASCIILiteral("wrapJSONString"), inspectorEnvironment()->functionCallHandler());
+    wrapFunction.appendArgument(json);
+    wrapFunction.appendArgument(groupName);
+    wrapFunction.appendArgument(generatePreview);
+
+    bool hadException = false;
+    auto evalResult = callFunctionWithEvalEnabled(wrapFunction, hadException);
+    if (hadException)
+        return nullptr;
+
+    if (evalResult.isNull())
+        return nullptr;
+
+    RefPtr<JSON::Object> resultObject;
+    bool castSucceeded = toInspectorValue(*scriptState(), evalResult)->asObject(resultObject);
+    ASSERT_UNUSED(castSucceeded, castSucceeded);
+
+    return BindingTraits<Inspector::Protocol::Runtime::RemoteObject>::runtimeCast(resultObject);
+}
+
 RefPtr<Inspector::Protocol::Runtime::RemoteObject> InjectedScript::wrapTable(JSC::JSValue table, JSC::JSValue columns) const
 {
     ASSERT(!hasNoValue());
index 91f255156374e2c6a637d29f21b42e54fb84397c..a13f5e7a6e980b9f365a093af05c2d871ba67286 100644 (file)
@@ -64,6 +64,7 @@ public:
 
     Ref<JSON::ArrayOf<Protocol::Debugger::CallFrame>> wrapCallFrames(JSC::JSValue) const;
     RefPtr<Protocol::Runtime::RemoteObject> wrapObject(JSC::JSValue, const String& groupName, bool generatePreview = false) const;
+    RefPtr<Protocol::Runtime::RemoteObject> wrapJSONString(const String& json, const String& groupName, bool generatePreview = false) const;
     RefPtr<Protocol::Runtime::RemoteObject> wrapTable(JSC::JSValue table, JSC::JSValue columns) const;
     RefPtr<Protocol::Runtime::ObjectPreview> previewValue(JSC::JSValue) const;
 
index 92ca6fb428256fe7d073dee1f979a48ce6c34d12..65426bc3171ebf144eb2171501ca45802a4627a9 100644 (file)
@@ -270,6 +270,15 @@ let InjectedScript = class InjectedScript
         return RemoteObject.create(object, groupName, false, generatePreview);
     }
 
+    wrapJSONString(jsonString, groupName, generatePreview)
+    {
+        try {
+            return this.wrapObject(JSON.parse(jsonString), groupName, true, generatePreview);
+        } catch {
+            return null;
+        }
+    }
+
     wrapTable(canAccessInspectedGlobalObject, table, columns)
     {
         if (!canAccessInspectedGlobalObject)
index 8c8eefa1ffdc9586160f462e9cf1823589e8c0da..1880d866cb459a82c2d2a443e0e3f09346dc5267 100644 (file)
@@ -1,3 +1,19 @@
+2017-12-11  Eric Carlson  <eric.carlson@apple.com>
+
+        Web Inspector: Optionally log WebKit log parameters as JSON
+        https://bugs.webkit.org/show_bug.cgi?id=180529
+        <rdar://problem/35909462>
+
+        Reviewed by Joseph Pecoraro.
+
+        * wtf/Logger.h:
+        (WTF::Logger::log):
+        (WTF::LogArgument<Logger::LogSiteIdentifier>::toString):
+
+        * wtf/MediaTime.cpp:
+        (WTF::MediaTime::toJSONString const): Serialize to JSON string.
+        * wtf/MediaTime.h:
+
 2017-12-11  Tim Horton  <timothy_horton@apple.com>
 
         Stop using deprecated target conditional for simulator builds
index 2c99bd50fe6e53368ef6a27291b91ab2eea12c37..6b01b5895c0be0dd4b5973650a941811f2648064 100644 (file)
@@ -51,6 +51,63 @@ struct LogArgument {
     template<size_t length> static String toString(const char (&argument)[length]) { return String(argument); }
 };
 
+struct JSONLogValue {
+    enum class Type { String, JSON };
+    Type type { Type::JSON };
+    String value;
+};
+
+template<class C>
+class HasToJSONString {
+    template <class T> static std::true_type testSignature(String (T::*)() const);
+
+    template <class T> static decltype(testSignature(&T::toJSONString)) test(std::nullptr_t);
+    template <class T> static std::false_type test(...);
+
+public:
+    static const bool value = decltype(test<C>(nullptr))::value;
+};
+
+template<typename Argument, bool hasJSON = HasToJSONString<Argument>::value>
+struct ConsoleLogValueImpl;
+
+template<typename Argument>
+struct ConsoleLogValueImpl<Argument, true> {
+    static JSONLogValue toValue(const Argument& value)
+    {
+        return JSONLogValue { JSONLogValue::Type::JSON, value.toJSONString() };
+    }
+};
+
+template<typename Argument>
+struct ConsoleLogValueImpl<Argument, false> {
+    static JSONLogValue toValue(const Argument& value)
+    {
+        return JSONLogValue { JSONLogValue::Type::String, LogArgument<Argument>::toString(value) };
+    }
+};
+
+template<typename Argument, bool hasJSON = std::is_class<Argument>::value>
+struct ConsoleLogValue;
+
+template<typename Argument>
+struct ConsoleLogValue<Argument, true> {
+    static JSONLogValue toValue(const Argument& value)
+    {
+        return ConsoleLogValueImpl<Argument>::toValue(value);
+    }
+};
+
+// Specialization for non-class types
+template<typename Argument>
+struct ConsoleLogValue<Argument, false> {
+    template<typename T>
+    static JSONLogValue toValue(T value)
+    {
+        return JSONLogValue { JSONLogValue::Type::String, LogArgument<T>::toString(value) };
+    }
+};
+
 class Logger : public RefCounted<Logger> {
     WTF_MAKE_NONCOPYABLE(Logger);
 public:
@@ -58,7 +115,7 @@ public:
     class Observer {
     public:
         virtual ~Observer() = default;
-        virtual void didLogMessage(const WTFLogChannel&, WTFLogLevel, const String&) = 0;
+        virtual void didLogMessage(const WTFLogChannel&, WTFLogLevel, Vector<JSONLogValue>&&) = 0;
     };
 
     static Ref<Logger> create(const void* owner)
@@ -190,7 +247,7 @@ private:
             return;
 
         for (Observer& observer : observers())
-            observer.didLogMessage(channel, level, logMessage);
+            observer.didLogMessage(channel, level, { ConsoleLogValue<Argument>::toValue(arguments)... });
     }
 
     static Vector<std::reference_wrapper<Observer>>& observers()
@@ -214,7 +271,7 @@ struct LogArgument<Logger::LogSiteIdentifier> {
             builder.appendLiteral("::");
         }
         builder.append(value.methodName);
-        builder.appendLiteral("(");
+        builder.append('(');
         appendUnsigned64AsHex(value.objectPtr, builder);
         builder.appendLiteral(") ");
         return builder.toString();
@@ -224,3 +281,4 @@ struct LogArgument<Logger::LogSiteIdentifier> {
 } // namespace WTF
 
 using WTF::Logger;
+using WTF::JSONLogValue;
index f4367c1c30b721a66996b403750fc6f791de64f6..5401ddd6c67cb324edec7cff7ed591e9b986ea5d 100644 (file)
@@ -32,6 +32,7 @@
 #include <algorithm>
 #include <cstdlib>
 #include <wtf/CheckedArithmetic.h>
+#include <wtf/JSONValues.h>
 #include <wtf/MathExtras.h>
 #include <wtf/PrintStream.h>
 #include <wtf/text/StringBuilder.h>
@@ -568,6 +569,30 @@ String MediaTime::toString() const
     return builder.toString();
 }
 
+String MediaTime::toJSONString() const
+{
+    auto object = JSON::Object::create();
+
+    if (hasDoubleValue())
+        object->setDouble(ASCIILiteral("value"), toDouble());
+    else {
+        if (isInvalid() || isIndefinite())
+            object->setString(ASCIILiteral("value"), ASCIILiteral("NaN"));
+        else if (isPositiveInfinite())
+            object->setString(ASCIILiteral("value"), ASCIILiteral("POSITIVE_INFINITY"));
+        else if (isNegativeInfinite())
+            object->setString(ASCIILiteral("value"), ASCIILiteral("NEGATIVE_INFINITY"));
+        else
+            object->setDouble(ASCIILiteral("value"), toDouble());
+
+        object->setInteger(ASCIILiteral("numerator"), static_cast<int>(m_timeValue));
+        object->setInteger(ASCIILiteral("denominator"), m_timeScale);
+        object->setInteger(ASCIILiteral("flags"), m_timeFlags);
+    }
+
+    return object->toJSONString();
+}
+
 MediaTime abs(const MediaTime& rhs)
 {
     if (rhs.isInvalid())
index be38c73777eed6ebbad7f555dbcb6dde4925512e..337fefed9c2f696ace787c189d7365c4a6aec9cc 100644 (file)
@@ -110,6 +110,7 @@ public:
 
     void dump(PrintStream& out) const;
     String toString() const;
+    String toJSONString() const;
 
     // Make the following casts errors:
     operator double() const = delete;
index 0c40b9af7fd7838abc611720ac6f6a0aea33d54f..c31c07115ef3688cee35a3a70099d64477c5a8ae 100644 (file)
@@ -1,3 +1,66 @@
+2017-12-11  Eric Carlson  <eric.carlson@apple.com>
+
+        Web Inspector: Optionally log WebKit log parameters as JSON
+        https://bugs.webkit.org/show_bug.cgi?id=180529
+        <rdar://problem/35909462>
+
+        Reviewed by Joseph Pecoraro.
+
+        * dom/Document.cpp:
+        (WebCore::Document::didLogMessage):Update for API change. Don't check for main thread, that
+        is already done in addConsoleMessage.
+        * dom/Document.h:
+
+        * html/HTMLMediaElement.cpp:
+        (WebCore::HTMLMediaElement::updatePlayState): Cleanup logging.
+
+        * html/track/DataCue.cpp:
+        (WebCore::DataCue::toJSONString const): Serialize to JSON string.
+        (WebCore::DataCue::toString const): Deleted.
+        * html/track/DataCue.h:
+        (WTF::LogArgument<WebCore::DataCue>::toString):
+
+        * html/track/TextTrackCue.cpp:
+        (WebCore::TextTrackCue::toJSON const): Ditto.
+        (WebCore::TextTrackCue::toJSONString const):
+        (WebCore::TextTrackCue::toString const): Deleted.
+        * html/track/TextTrackCue.h:
+        (WTF::LogArgument<WebCore::TextTrackCue>::toString):
+
+        * html/track/TextTrackCueGeneric.cpp:
+        (WebCore::TextTrackCueGeneric::toJSONString const): Ditto.
+        (WebCore::TextTrackCueGeneric::toString const): Deleted.
+        * html/track/TextTrackCueGeneric.h:
+        (WTF::LogArgument<WebCore::TextTrackCueGeneric>::toString):
+
+        * html/track/VTTCue.cpp:
+        (WebCore::VTTCue::toJSONString const): Ditto.
+        (WebCore::VTTCue::toString const): Deleted.
+        * html/track/VTTCue.h:
+        (WTF::LogArgument<WebCore::VTTCue>::toString):
+
+        * platform/graphics/InbandTextTrackPrivateClient.h:
+        (WebCore::GenericCueData::toJSONString const): Ditto.
+        (WTF::LogArgument<WebCore::GenericCueData>::toString):
+        (WebCore::GenericCueData::toString const): Deleted.
+
+        * platform/graphics/avfoundation/InbandTextTrackPrivateAVF.cpp:
+        (WebCore::InbandTextTrackPrivateAVF::processAttributedStrings): Cleanup logging.
+        (WebCore::InbandTextTrackPrivateAVF::removeCompletedCues): Ditto.
+        (WebCore::InbandTextTrackPrivateAVF::processNativeSamples): Log the entire cue.
+        (WebCore::InbandTextTrackPrivateAVF::readNativeSampleBuffer): Cleanup logging.
+
+        * platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.cpp:
+        (WebCore::MediaPlayerPrivateAVFoundation::maxMediaTimeSeekable const): Don't log, it isn't
+        interesting and happens frequently.
+        (WebCore::MediaPlayerPrivateAVFoundation::minMediaTimeSeekable const): Ditto.
+
+        * platform/graphics/iso/ISOVTTCue.cpp:
+        (WebCore::ISOWebVTTCue::toJSONString const): Serialize to JSON string.
+
+        * platform/graphics/iso/ISOVTTCue.h:
+        (WTF::LogArgument<WebCore::ISOWebVTTCue>::toString): Ditto.
+
 2017-12-11  Youenn Fablet  <youenn@apple.com>
 
         Use VCP H264 encoder for platforms supporting it
index bfaac4999a973f7826571b7a565892cfce5b75a0..a0e8d6221ea1cd5c5526f739f0e273bd048150ba 100644 (file)
 #include "ScriptModuleLoader.h"
 #include "ScriptRunner.h"
 #include "ScriptSourceCode.h"
+#include "ScriptState.h"
 #include "ScriptedAnimationController.h"
 #include "ScrollingCoordinator.h"
 #include "SecurityOrigin.h"
@@ -7601,26 +7602,18 @@ static MessageLevel messageLevelFromWTFLogLevel(WTFLogLevel level)
     return MessageLevel::Log;
 }
 
-void Document::didLogMessage(const WTFLogChannel& channel, WTFLogLevel level, const String& logMessage)
+void Document::didLogMessage(const WTFLogChannel& channel, WTFLogLevel level, Vector<JSONLogValue>&& logMessages)
 {
-    if (!this->page())
+    if (!page())
         return;
 
     ASSERT(sessionID().isAlwaysOnLoggingAllowed());
 
     auto messageSource = messageSourceForWTFLogChannel(channel);
     auto messageLevel = messageLevelFromWTFLogLevel(level);
+    auto message = std::make_unique<Inspector::ConsoleMessage>(messageSource, MessageType::Log, messageLevel, WTFMove(logMessages), mainWorldExecState(frame()));
 
-    callOnMainThread([documentReference = m_weakFactory.createWeakPtr(*this), messageSource, messageLevel, logMessage]() mutable {
-        ASSERT(isMainThread());
-
-        Document* document = documentReference.get();
-        if (!document)
-            return;
-
-        auto message = std::make_unique<Inspector::ConsoleMessage>(messageSource, MessageType::Log, messageLevel, logMessage);
-        document->addConsoleMessage(WTFMove(message));
-    });
+    addConsoleMessage(WTFMove(message));
 }
 
 #if ENABLE(SERVICE_WORKER)
index c23348d4911578ad09a86679eb143230495863ae..4cb2e9136dccc373ca78662d10031f9da39d7259 100644 (file)
@@ -1691,7 +1691,7 @@ private:
 
     void notifyMediaCaptureOfVisibilityChanged();
 
-    void didLogMessage(const WTFLogChannel&, WTFLogLevel, const String&) final;
+    void didLogMessage(const WTFLogChannel&, WTFLogLevel, Vector<JSONLogValue>&&) final;
 
 #if ENABLE(DEVICE_ORIENTATION) && PLATFORM(IOS)
     std::unique_ptr<DeviceMotionClient> m_deviceMotionClient;
index 758cf0c3e1d5cb63e2d2f91f14934cbc13b19a38..534aa9ec335fd9d39f43166bd46436f31f4e67fb 100644 (file)
@@ -5250,7 +5250,7 @@ void HTMLMediaElement::updatePlayState(UpdateState updateState)
     bool shouldBePlaying = potentiallyPlaying();
     bool playerPaused = m_player->paused();
 
-    INFO_LOG(LOGIDENTIFIER, "shouldBePlaying = ", shouldBePlaying, " playerPaused = ", playerPaused);
+    INFO_LOG(LOGIDENTIFIER, "shouldBePlaying = ", shouldBePlaying, ", playerPaused = ", playerPaused);
 
     if (shouldBePlaying) {
         scheduleUpdatePlaybackControlsManager();
index 3e4623be816becb50bcd688749ec6f32dfebbecc..20eccb4c85d469219ecafa53bcee82bd4171a807 100644 (file)
@@ -188,16 +188,16 @@ JSValue DataCue::valueOrNull() const
     return jsNull();
 }
 
-String DataCue::toString() const
+String DataCue::toJSONString() const
 {
-    StringBuilder builder;
+    auto object = JSON::Object::create();
 
-    builder.append(TextTrackCue::toString());
+    TextTrackCue::toJSON(object.get());
 
-    builder.appendLiteral(", type = ");
-    builder.append(m_type);
+    if (!m_type.isEmpty())
+        object->setString(ASCIILiteral("type"), m_type);
 
-    return builder.toString();
+    return object->toJSONString();
 }
 
 } // namespace WebCore
index c8edb1a0e7aebb0cb2c1a42f283636417a2bdcb7..42857b905f1bc6544eeca19b3c7e87a655571361 100644 (file)
@@ -87,7 +87,7 @@ public:
     bool cueContentsMatch(const TextTrackCue&) const override;
     bool doesExtendCue(const TextTrackCue&) const override;
 
-    String toString() const override;
+    String toJSONString() const;
 
 private:
     DataCue(ScriptExecutionContext&, const MediaTime& start, const MediaTime& end, ArrayBuffer&, const String&);
@@ -117,7 +117,7 @@ template <>
 struct LogArgument<WebCore::DataCue> {
     static String toString(const WebCore::DataCue& cue)
     {
-        return cue.toString();
+        return cue.toJSONString();
     }
 };
 
index 2522650b3ce4fc4bb1e23fc887ad2bca88ee21c9..cfb67ae398b655bba2811162047fe4129342b422 100644 (file)
@@ -216,16 +216,8 @@ bool TextTrackCue::doesExtendCue(const TextTrackCue& cue) const
     return true;
 }
 
-String TextTrackCue::toString() const
+void TextTrackCue::toJSON(JSON::Object& value) const
 {
-    StringBuilder builder;
-
-    builder.appendLiteral("start = ");
-    builder.append(m_startTime.toString());
-
-    builder.appendLiteral(", end = ");
-    builder.append(m_endTime.toString());
-
     const char* type = "Generic";
     switch (cueType()) {
     case TextTrackCue::Generic:
@@ -239,10 +231,18 @@ String TextTrackCue::toString() const
         break;
     }
 
-    builder.appendLiteral(", type = ");
-    builder.append(type);
+    value.setString(ASCIILiteral("type"), ASCIILiteral(type));
+    value.setDouble(ASCIILiteral("startTime"), startTime());
+    value.setDouble(ASCIILiteral("endTime"), endTime());
+}
+
+String TextTrackCue::toJSONString() const
+{
+    auto object = JSON::Object::create();
+
+    toJSON(object.get());
 
-    return builder.toString();
+    return object->toJSONString();
 }
 
 } // namespace WebCore
index bdb292f6521aa9af8e792cc476c4cca195892693..cfee47d844a47d4fb15ae5436f326717354bd76b 100644 (file)
@@ -34,6 +34,7 @@
 #if ENABLE(VIDEO_TRACK)
 
 #include "Document.h"
+#include <wtf/JSONValues.h>
 #include <wtf/MediaTime.h>
 
 namespace WebCore {
@@ -84,7 +85,7 @@ public:
     void willChange();
     virtual void didChange();
 
-    virtual String toString() const;
+    String toJSONString() const;
 
     using RefCounted::ref;
     using RefCounted::deref;
@@ -94,6 +95,8 @@ protected:
 
     Document& ownerDocument() { return downcast<Document>(m_scriptExecutionContext); }
 
+    virtual void toJSON(JSON::Object&) const;
+
 private:
     void refEventTarget() final { ref(); }
     void derefEventTarget() final { deref(); }
@@ -130,7 +133,7 @@ template <>
 struct LogArgument<WebCore::TextTrackCue> {
     static String toString(const WebCore::TextTrackCue& cue)
     {
-        return cue.toString();
+        return cue.toJSONString();
     }
 };
 
index 1a2fb53270673ff5a98bbca5fa8fee9e00422933..e6d73c9924a9063392582219aeb20e6cb71b05b5 100644 (file)
@@ -266,43 +266,26 @@ bool TextTrackCueGeneric::isPositionedAbove(const TextTrackCue* that) const
     return VTTCue::isOrderedBefore(that);
 }
 
-String TextTrackCueGeneric::toString() const
+String TextTrackCueGeneric::toJSONString() const
 {
-    StringBuilder builder;
-
-    builder.append(VTTCue::toString());
-
-    if (m_foregroundColor.isValid()) {
-        builder.appendLiteral(", foreground color = ");
-        builder.append(m_foregroundColor.serialized());
-    }
-
-    if (m_backgroundColor.isValid()) {
-        builder.appendLiteral(", background color = ");
-        builder.append(m_backgroundColor.serialized());
-    }
-
-    if (m_highlightColor.isValid()) {
-        builder.appendLiteral(", hilight color = ");
-        builder.append(m_highlightColor.serialized());
-    }
-
-    if (m_baseFontSizeRelativeToVideoHeight) {
-        builder.appendLiteral(", base font size relative to video height = ");
-        builder.appendNumber(m_baseFontSizeRelativeToVideoHeight);
-    }
-
-    if (m_fontSizeMultiplier) {
-        builder.appendLiteral(", font size multiplier = ");
-        builder.appendNumber(m_fontSizeMultiplier);
-    }
-
-    if (!m_fontName.isEmpty()) {
-        builder.appendLiteral(", font = ");
-        builder.append(m_fontName);
-    }
-
-    return builder.toString();
+    auto object = JSON::Object::create();
+
+    VTTCue::toJSON(object.get());
+
+    if (m_foregroundColor.isValid())
+        object->setString(ASCIILiteral("foregroundColor"), m_foregroundColor.serialized());
+    if (m_backgroundColor.isValid())
+        object->setString(ASCIILiteral("backgroundColor"), m_backgroundColor.serialized());
+    if (m_highlightColor.isValid())
+        object->setString(ASCIILiteral("highlightColor"), m_highlightColor.serialized());
+    if (m_baseFontSizeRelativeToVideoHeight)
+        object->setDouble(ASCIILiteral("relativeFontSize"), m_baseFontSizeRelativeToVideoHeight);
+    if (m_fontSizeMultiplier)
+        object->setDouble(ASCIILiteral("fontSizeMultiplier"), m_fontSizeMultiplier);
+    if (!m_fontName.isEmpty())
+        object->setString(ASCIILiteral("font"), m_fontName);
+
+    return object->toJSONString();
 }
 
 } // namespace WebCore
index d5dedc4aba914e24da774e5c84c768516a89ff56..21010021c747b9d1239df70719f6026277d7ec45 100644 (file)
@@ -67,7 +67,7 @@ public:
 
     void setFontSize(int, const IntSize&, bool important) final;
 
-    String toString() const final;
+    String toJSONString() const;
 
 private:
     TextTrackCueGeneric(ScriptExecutionContext&, const MediaTime& start, const MediaTime& end, const String&);
@@ -103,7 +103,7 @@ template <>
 struct LogArgument<WebCore::TextTrackCueGeneric> {
     static String toString(const WebCore::TextTrackCueGeneric& cue)
     {
-        return cue.toString();
+        return cue.toJSONString();
     }
 };
 
index 21ea664e5bc46b4d4ee3908e8e8669bbec642326..044096eaf46543b30883112b93abcd5ff4e4c8db 100644 (file)
@@ -1176,16 +1176,22 @@ const VTTCue* toVTTCue(const TextTrackCue* cue)
     return static_cast<const VTTCue*>(cue);
 }
 
-String VTTCue::toString() const
+String VTTCue::toJSONString() const
 {
-    StringBuilder builder;
+    auto object = JSON::Object::create();
 
-    builder.append(TextTrackCue::toString());
+    TextTrackCue::toJSON(object.get());
 
-    builder.appendLiteral(", content = ");
-    builder.append(text());
+    object->setString(ASCIILiteral("vertical"), vertical());
+    object->setBoolean(ASCIILiteral("snapToLines"), snapToLines());
+    object->setDouble(ASCIILiteral("line"), m_linePosition);
+    object->setDouble(ASCIILiteral("position"), position());
+    object->setInteger(ASCIILiteral("size"), m_cueSize);
+    object->setString(ASCIILiteral("align"), align());
+    object->setString(ASCIILiteral("text"), text());
+    object->setString(ASCIILiteral("regionId"), regionId());
 
-    return builder.toString();
+    return object->toJSONString();
 }
 
 } // namespace WebCore
index 52293851a6120fcece7ca76b107d2b75d798b3b3..f3b6d31f45a4eae27f20aae1601ba0d80c64ba38 100644 (file)
@@ -167,7 +167,7 @@ public:
 
     void didChange() override;
 
-    String toString() const override;
+    String toJSONString() const;
 
 protected:
     VTTCue(ScriptExecutionContext&, const MediaTime& start, const MediaTime& end, const String& content);
@@ -238,10 +238,10 @@ template <>
 struct LogArgument<WebCore::VTTCue> {
     static String toString(const WebCore::VTTCue& cue)
     {
-        return cue.toString();
+        return cue.toJSONString();
     }
 };
 
-}
+} // namespace WTF
 
 #endif
index 19ecc59c46ce031a2df2be63c0030b534b801a34..ccbb3d655f93c814be21ed85ddc2e0b9715d1c7e 100644 (file)
@@ -29,6 +29,7 @@
 
 #include "Color.h"
 #include "TrackPrivateBase.h"
+#include <wtf/JSONValues.h>
 #include <wtf/MediaTime.h>
 
 #if ENABLE(DATACUE_VALUE)
@@ -93,7 +94,7 @@ public:
 
     bool doesExtendCueData(const GenericCueData&) const;
 
-    String toString() const;
+    String toJSONString() const;
 
 private:
     GenericCueData() = default;
@@ -115,15 +116,12 @@ private:
     Status m_status { Uninitialized };
 };
 
-inline String GenericCueData::toString() const
+inline String GenericCueData::toJSONString() const
 {
-    StringBuilder builder;
+    auto object = JSON::Object::create();
 
-    builder.appendLiteral("start = ");
-    builder.append(m_startTime.toString());
-
-    builder.appendLiteral(", end = ");
-    builder.append(m_endTime.toString());
+    object->setDouble(ASCIILiteral("start"), m_startTime.toDouble());
+    object->setDouble(ASCIILiteral("end"), m_endTime.toDouble());
 
     const char* status;
     switch (m_status) {
@@ -137,26 +135,19 @@ inline String GenericCueData::toString() const
         status = "Complete";
         break;
     }
-    builder.appendLiteral(", status = ");
-    builder.append(status);
+    object->setString("status", status);
 
-    builder.appendLiteral(", id = ");
-    builder.append(m_id);
+    if (!m_id.isEmpty())
+        object->setString("id", m_id);
 
-    if (m_line > 0) {
-        builder.appendLiteral(", line = ");
-        builder.appendNumber(m_line);
-    }
+    if (m_line > 0)
+        object->setDouble(ASCIILiteral("line"), m_line);
 
-    if (m_size > 0) {
-        builder.appendLiteral(", size = ");
-        builder.appendNumber(m_size);
-    }
+    if (m_size > 0)
+        object->setDouble(ASCIILiteral("size"), m_size);
 
-    if (m_position > 0) {
-        builder.appendLiteral(", position = ");
-        builder.appendNumber(m_position);
-    }
+    if (m_position > 0)
+        object->setDouble(ASCIILiteral("position"), m_position);
 
     if (m_align != None) {
         const char* align;
@@ -174,41 +165,28 @@ inline String GenericCueData::toString() const
             align = "None";
             break;
         }
-        builder.appendLiteral(", align = ");
-        builder.append(align);
+        object->setString(ASCIILiteral("align"), align);
     }
 
-    if (m_foregroundColor.isValid()) {
-        builder.appendLiteral(", foreground color = ");
-        builder.append(m_foregroundColor.serialized());
-    }
+    if (m_foregroundColor.isValid())
+        object->setString(ASCIILiteral("foregroundColor"), m_foregroundColor.serialized());
 
-    if (m_backgroundColor.isValid()) {
-        builder.appendLiteral(", background color = ");
-        builder.append(m_backgroundColor.serialized());
-    }
+    if (m_backgroundColor.isValid())
+        object->setString(ASCIILiteral("backgroundColor"), m_backgroundColor.serialized());
 
-    if (m_highlightColor.isValid()) {
-        builder.appendLiteral(", hilight color = ");
-        builder.append(m_highlightColor.serialized());
-    }
+    if (m_highlightColor.isValid())
+        object->setString(ASCIILiteral("highlightColor"), m_highlightColor.serialized());
 
-    if (m_baseFontSize) {
-        builder.appendLiteral(", base font size = ");
-        builder.appendNumber(m_baseFontSize);
-    }
+    if (m_baseFontSize)
+        object->setDouble(ASCIILiteral("baseFontSize"), m_baseFontSize);
 
-    if (m_relativeFontSize) {
-        builder.appendLiteral(", relative font size = ");
-        builder.appendNumber(m_relativeFontSize);
-    }
+    if (m_relativeFontSize)
+        object->setDouble(ASCIILiteral("relativeFontSize"), m_relativeFontSize);
 
-    if (!m_fontName.isEmpty()) {
-        builder.appendLiteral(", font = ");
-        builder.append(m_fontName);
-    }
+    if (!m_fontName.isEmpty())
+        object->setString(ASCIILiteral("font"), m_fontName);
 
-    return builder.toString();
+    return object->toJSONString();
 }
 
 inline bool GenericCueData::doesExtendCueData(const GenericCueData& other) const
@@ -273,7 +251,7 @@ template <>
 struct LogArgument<WebCore::GenericCueData> {
     static String toString(const WebCore::GenericCueData& cue)
     {
-        return cue.toString();
+        return cue.toJSONString();
     }
 };
 
index 135f8147ceb32658c14cf1d83065a78a5446dc3f..613218be2c8004de52711d4a77df1f541fca1ffa 100644 (file)
@@ -359,7 +359,7 @@ void InbandTextTrackPrivateAVF::processAttributedStrings(CFArrayRef attributedSt
                     if (!arrivingCue->doesExtendCueData(*cueData))
                         nonExtensionCues.append(WTFMove(arrivingCue));
                     else
-                        DEBUG_LOG(LOGIDENTIFIER, "found an extension cue: ", *cueData);
+                        DEBUG_LOG(LOGIDENTIFIER, "found an extension cue ", *cueData);
                 }
 
                 bool currentCueIsExtended = (arrivingCues.size() != nonExtensionCues.size());
@@ -373,17 +373,17 @@ void InbandTextTrackPrivateAVF::processAttributedStrings(CFArrayRef attributedSt
                     cueData->setEndTime(m_currentCueEndTime);
                     cueData->setStatus(GenericCueData::Complete);
 
-                    DEBUG_LOG(LOGIDENTIFIER, "updating cue start = ", cueData->startTime(), ", end = ", cueData->endTime(), ", content = ", cueData->content());
+                    DEBUG_LOG(LOGIDENTIFIER, "updating cue ", *cueData);
 
                     client()->updateGenericCue(*cueData);
                 } else {
                     // We have to assume that the implicit duration is invalid for cues delivered during a seek because the AVF decode pipeline may not
                     // see every cue, so DO NOT update cue duration while seeking.
-                    DEBUG_LOG(LOGIDENTIFIER, "ignoring cue delivered during seek: ", *cueData);
+                    DEBUG_LOG(LOGIDENTIFIER, "ignoring cue delivered during seek ", *cueData);
                 }
             }
         } else
-            ERROR_LOG(LOGIDENTIFIER, "negative length cue(s): start = ", m_currentCueStartTime, ", end = ", m_currentCueEndTime);
+            ERROR_LOG(LOGIDENTIFIER, "negative length cue(s): start ", m_currentCueStartTime, ", end ", m_currentCueEndTime);
 
         removeCompletedCues();
     }
@@ -395,7 +395,7 @@ void InbandTextTrackPrivateAVF::processAttributedStrings(CFArrayRef attributedSt
 
     for (auto& cueData : arrivingCues) {
         m_cues.append(cueData.ptr());
-        DEBUG_LOG(LOGIDENTIFIER, "adding cue: ", cueData.get());
+        DEBUG_LOG(LOGIDENTIFIER, "adding cue ", cueData.get());
         client()->addGenericCue(cueData);
     }
 
@@ -426,7 +426,7 @@ void InbandTextTrackPrivateAVF::removeCompletedCues()
             if (cue->status() != GenericCueData::Complete)
                 continue;
 
-            DEBUG_LOG(LOGIDENTIFIER, "removing cue: ", *cue);
+            DEBUG_LOG(LOGIDENTIFIER, "removing cue ", *cue);
 
             m_cues.remove(currentCue);
         }
@@ -529,7 +529,7 @@ void InbandTextTrackPrivateAVF::processNativeSamples(CFArrayRef nativeSamples, c
             header.append(reinterpret_cast<const unsigned char*>(CFDataGetBytePtr(webvttHeaderData)), length);
             header.append("\n\n");
 
-            DEBUG_LOG(LOGIDENTIFIER, "VTT header ", &header);
+            DEBUG_LOG(LOGIDENTIFIER, "VTT header ", &header);
             client()->parseWebVTTFileHeader(header.toString());
             m_haveReportedVTTHeader = true;
         } while (0);
@@ -537,7 +537,7 @@ void InbandTextTrackPrivateAVF::processNativeSamples(CFArrayRef nativeSamples, c
         if (type == ISOWebVTTCue::boxTypeName()) {
             ISOWebVTTCue cueData = ISOWebVTTCue(presentationTime, duration);
             cueData.read(view);
-            DEBUG_LOG(LOGIDENTIFIER, "sample presentation time = ", cueData.presentationTime(), ", duration = ", cueData.duration(), ", id = '", cueData.id(), "', settings = ", cueData.settings(), ", cue text = ", cueData.cueText(), ", sourceID = ", cueData.sourceID(), ", originalStartTime = ", cueData.originalStartTime());
+            DEBUG_LOG(LOGIDENTIFIER, "VTT cue data ", cueData);
             client()->parseWebVTTCueData(cueData);
         }
 
@@ -567,7 +567,7 @@ bool InbandTextTrackPrivateAVF::readNativeSampleBuffer(CFArrayRef nativeSamples,
     CMBlockBufferRef blockBuffer = CMSampleBufferGetDataBuffer(sampleBuffer);
     size_t bufferLength = CMBlockBufferGetDataLength(blockBuffer);
     if (bufferLength < ISOBox::minimumBoxSize()) {
-        ERROR_LOG(LOGIDENTIFIER, "CMSampleBuffer size length unexpectedly small: ", bufferLength);
+        ERROR_LOG(LOGIDENTIFIER, "CMSampleBuffer size length unexpectedly small ", bufferLength);
         return false;
     }
 
index 798d16d6588003c5c4d9b344120857e6ae75aa93..f6f46ded2d5d4dc351f983174963d787fda51446 100644 (file)
@@ -400,10 +400,8 @@ MediaTime MediaPlayerPrivateAVFoundation::maxMediaTimeSeekable() const
     if (!metaDataAvailable())
         return MediaTime::zeroTime();
 
-    if (!m_cachedMaxTimeSeekable) {
+    if (!m_cachedMaxTimeSeekable)
         m_cachedMaxTimeSeekable = platformMaxTimeSeekable();
-        INFO_LOG(LOGIDENTIFIER, "caching ", m_cachedMaxTimeSeekable);
-    }
 
     return m_cachedMaxTimeSeekable;
 }
@@ -413,10 +411,8 @@ MediaTime MediaPlayerPrivateAVFoundation::minMediaTimeSeekable() const
     if (!metaDataAvailable())
         return MediaTime::zeroTime();
 
-    if (!m_cachedMinTimeSeekable) {
+    if (!m_cachedMinTimeSeekable)
         m_cachedMinTimeSeekable = platformMinTimeSeekable();
-        INFO_LOG(LOGIDENTIFIER, "caching ", m_cachedMinTimeSeekable);
-    }
 
     return m_cachedMinTimeSeekable;
 }
index b920f14e81ac7e0ed412109bdffc679235725dd1..91ad41733cdabd2f89d31c07807c5c132741233c 100644 (file)
@@ -32,6 +32,7 @@
 #include <runtime/Int8Array.h>
 #include <runtime/JSCInlines.h>
 #include <runtime/TypedArrayInlines.h>
+#include <wtf/JSONValues.h>
 #include <wtf/NeverDestroyed.h>
 #include <wtf/text/CString.h>
 #include <wtf/text/StringBuilder.h>
@@ -106,4 +107,21 @@ bool ISOWebVTTCue::parse(DataView& view, unsigned& offset)
     return true;
 }
 
+String ISOWebVTTCue::toJSONString() const
+{
+    auto object = JSON::Object::create();
+
+    object->setString(ASCIILiteral("sourceId"), m_sourceID);
+    object->setString(ASCIILiteral("id"), m_identifier);
+
+    object->setString(ASCIILiteral("originalStartTime"), m_originalStartTime);
+    object->setString(ASCIILiteral("settings"), m_settings);
+    object->setString(ASCIILiteral("cueText"), m_cueText);
+
+    object->setDouble(ASCIILiteral("presentationTime"), m_presentationTime.toDouble());
+    object->setDouble(ASCIILiteral("duration"), m_duration.toDouble());
+
+    return object->toJSONString();
+}
+
 } // namespace WebCore
index eb1e0d6849e62628bebd4b79c28affd386c3b716..eda868fd4e7558a2fbf6712221861f002806bfb3 100644 (file)
@@ -53,6 +53,8 @@ public:
     const String& settings() const { return m_settings; }
     const String& cueText() const { return m_cueText; }
 
+    String toJSONString() const;
+
 protected:
     bool parse(JSC::DataView&, unsigned& offset) override;
 
@@ -66,4 +68,19 @@ protected:
     String m_cueText;
 };
 
-}
+} // namespace WebCore
+
+namespace WTF {
+
+template<typename Type>
+struct LogArgument;
+
+template <>
+struct LogArgument<WebCore::ISOWebVTTCue> {
+    static String toString(const WebCore::ISOWebVTTCue& cue)
+    {
+        return cue.toJSONString();
+    }
+};
+
+} // namespace WTF