001package Torello.Browser.BrowserAPI;
002
003import java.util.*;
004import javax.json.*;
005import javax.json.stream.*;
006import java.io.*;
007
008import java.lang.reflect.Method;
009import java.lang.reflect.Parameter;
010import java.util.function.Function;
011
012import Torello.Browser.BrowserEvent;
013import Torello.Browser.JavaScriptAPI.*;
014import Torello.Browser.helper.*;
015
016import Torello.Java.Additional.*;
017import Torello.Java.JSON.*;
018
019import static Torello.Java.JSON.JFlag.*;
020
021import Torello.Java.StrCmpr;
022import Torello.JavaDoc.StaticFunctional;
023import Torello.JavaDoc.JDHeaderBackgroundImg;
024import Torello.JavaDoc.Excuse;
025
026/**
027 * <SPAN CLASS=COPIEDJDK><B><CODE>[No Description Provided by Google]</CODE></B></SPAN>
028 * 
029 * <EMBED CLASS='external-html' DATA-FILE-ID=CODE_GEN_NOTE>
030 */
031@StaticFunctional(Excused={"counter"}, Excuses={Excuse.CONFIGURATION})
032@JDHeaderBackgroundImg(EmbedTagFileID="WOOD_PLANK_NOTE")
033public class Tracing
034{
035    // ********************************************************************************************
036    // ********************************************************************************************
037    // Class Header Stuff
038    // ********************************************************************************************
039    // ********************************************************************************************
040
041
042    // No Pubic Constructors
043    private Tracing () { }
044
045    // These two Vector's are used by all the "Methods" exported by this class.  java.lang.reflect
046    // is used to generate the JSON String's.  It saves thousands of lines of Auto-Generated Code.
047    private static final Map<String, Vector<String>>    parameterNames = new HashMap<>();
048    private static final Map<String, Vector<Class<?>>>  parameterTypes = new HashMap<>();
049
050    // Some Methods do not take any parameters - for instance all the "enable()" and "disable()"
051    // I simply could not get ride of RAW-TYPES and UNCHECKED warnings... so there are now,
052    // offically, two empty-vectors.  One for String's, and the other for Classes.
053
054    private static final Vector<String>     EMPTY_VEC_STR = new Vector<>();
055    private static final Vector<Class<?>>   EMPTY_VEC_CLASS = new Vector<>();
056
057    static
058    {
059        for (Method m : Tracing.class.getMethods())
060        {
061            // This doesn't work!  The parameter names are all "arg0" ... "argN"
062            // It works for java.lang.reflect.Field, BUT NOT java.lang.reflect.Parameter!
063            //
064            // Vector<String> parameterNamesList = new Vector<>(); -- NOPE!
065
066            Vector<Class<?>> parameterTypesList = new Vector<>();
067        
068            for (Parameter p : m.getParameters()) parameterTypesList.add(p.getType());
069
070            parameterTypes.put(
071                m.getName(),
072                (parameterTypesList.size() > 0) ? parameterTypesList : EMPTY_VEC_CLASS
073            );
074        }
075    }
076
077    static
078    {
079        Vector<String> v = null;
080
081        parameterNames.put("end", EMPTY_VEC_STR);
082
083        parameterNames.put("getCategories", EMPTY_VEC_STR);
084
085        v = new Vector<String>(1);
086        parameterNames.put("recordClockSyncMarker", v);
087        Collections.addAll(v, new String[]
088        { "syncId", });
089
090        v = new Vector<String>(2);
091        parameterNames.put("requestMemoryDump", v);
092        Collections.addAll(v, new String[]
093        { "deterministic", "levelOfDetail", });
094
095        v = new Vector<String>(9);
096        parameterNames.put("start", v);
097        Collections.addAll(v, new String[]
098        { "categories", "options", "bufferUsageReportingInterval", "transferMode", "streamFormat", "streamCompression", "traceConfig", "perfettoConfig", "tracingBackend", });
099    }
100
101
102    // ********************************************************************************************
103    // ********************************************************************************************
104    // Types - Static Inner Classes
105    // ********************************************************************************************
106    // ********************************************************************************************
107
108    // public static class MemoryDumpConfig => JsonObject
109    
110    /**
111     * Data format of a trace. Can be either the legacy JSON format or the
112     * protocol buffer format. Note that the JSON format will be deprecated soon.
113     * <BR /><B CLASS=Exp>EXPERIMENTAL</B>
114     */
115    public static final String[] StreamFormat =
116    { "json", "proto", };
117    
118    /**
119     * Compression type to use for traces returned via streams.
120     * <BR /><B CLASS=Exp>EXPERIMENTAL</B>
121     */
122    public static final String[] StreamCompression =
123    { "none", "gzip", };
124    
125    /**
126     * Details exposed when memory request explicitly declared.
127     * Keep consistent with memory_dump_request_args.h and
128     * memory_instrumentation.mojom
129     * <BR /><B CLASS=Exp>EXPERIMENTAL</B>
130     */
131    public static final String[] MemoryDumpLevelOfDetail =
132    { "background", "light", "detailed", };
133    
134    /**
135     * Backend type to use for tracing. {@code chrome} uses the Chrome-integrated
136     * tracing service and is supported on all platforms. {@code system} is only
137     * supported on Chrome OS and uses the Perfetto system tracing service.
138     * {@code auto} chooses {@code system} when the perfettoConfig provided to Tracing.start
139     * specifies at least one non-Chrome data source; otherwise uses {@code chrome}.
140     * <BR /><B CLASS=Exp>EXPERIMENTAL</B>
141     */
142    public static final String[] TracingBackend =
143    { "auto", "chrome", "system", };
144    
145    /** <CODE>[No Description Provided by Google]</CODE> */
146    public static class TraceConfig
147        extends BaseType
148        implements java.io.Serializable
149    {
150        /** For Object Serialization.  java.io.Serializable */
151        protected static final long serialVersionUID = 1;
152        
153        public boolean[] optionals()
154        { return new boolean[] { true, true, true, true, true, true, true, true, true, }; }
155        
156        /**
157         * Controls how the trace buffer stores data. The default is {@code recordUntilFull}.
158         * <BR /><B CLASS=Opt>OPTIONAL</B>
159        <B CLASS=Exp>EXPERIMENTAL</B>
160         */
161        public final String recordMode;
162        
163        /**
164         * Size of the trace buffer in kilobytes. If not specified or zero is passed, a default value
165         * of 200 MB would be used.
166         * <BR /><B CLASS=Opt>OPTIONAL</B>
167        <B CLASS=Exp>EXPERIMENTAL</B>
168         */
169        public final Number traceBufferSizeInKb;
170        
171        /**
172         * Turns on JavaScript stack sampling.
173         * <BR /><B CLASS=Opt>OPTIONAL</B>
174        <B CLASS=Exp>EXPERIMENTAL</B>
175         */
176        public final Boolean enableSampling;
177        
178        /**
179         * Turns on system tracing.
180         * <BR /><B CLASS=Opt>OPTIONAL</B>
181        <B CLASS=Exp>EXPERIMENTAL</B>
182         */
183        public final Boolean enableSystrace;
184        
185        /**
186         * Turns on argument filter.
187         * <BR /><B CLASS=Opt>OPTIONAL</B>
188        <B CLASS=Exp>EXPERIMENTAL</B>
189         */
190        public final Boolean enableArgumentFilter;
191        
192        /**
193         * Included category filters.
194         * <BR /><B CLASS=Opt>OPTIONAL</B>
195         */
196        public final String[] includedCategories;
197        
198        /**
199         * Excluded category filters.
200         * <BR /><B CLASS=Opt>OPTIONAL</B>
201         */
202        public final String[] excludedCategories;
203        
204        /**
205         * Configuration to synthesize the delays in tracing.
206         * <BR /><B CLASS=Opt>OPTIONAL</B>
207        <B CLASS=Exp>EXPERIMENTAL</B>
208         */
209        public final String[] syntheticDelays;
210        
211        /**
212         * Configuration for memory dump triggers. Used only when "memory-infra" category is enabled.
213         * <BR /><B CLASS=Opt>OPTIONAL</B>
214        <B CLASS=Exp>EXPERIMENTAL</B>
215         */
216        public final JsonObject memoryDumpConfig;
217        
218        /**
219         * Constructor
220         *
221         * @param recordMode Controls how the trace buffer stores data. The default is {@code recordUntilFull}.
222         * <BR />Acceptable Values: ["recordUntilFull", "recordContinuously", "recordAsMuchAsPossible", "echoToConsole"]
223         * <BR /><B CLASS=Opt>OPTIONAL</B><B CLASS=Exp>EXPERIMENTAL</B>
224         * 
225         * @param traceBufferSizeInKb 
226         * Size of the trace buffer in kilobytes. If not specified or zero is passed, a default value
227         * of 200 MB would be used.
228         * <BR /><B CLASS=Opt>OPTIONAL</B><B CLASS=Exp>EXPERIMENTAL</B>
229         * 
230         * @param enableSampling Turns on JavaScript stack sampling.
231         * <BR /><B CLASS=Opt>OPTIONAL</B><B CLASS=Exp>EXPERIMENTAL</B>
232         * 
233         * @param enableSystrace Turns on system tracing.
234         * <BR /><B CLASS=Opt>OPTIONAL</B><B CLASS=Exp>EXPERIMENTAL</B>
235         * 
236         * @param enableArgumentFilter Turns on argument filter.
237         * <BR /><B CLASS=Opt>OPTIONAL</B><B CLASS=Exp>EXPERIMENTAL</B>
238         * 
239         * @param includedCategories Included category filters.
240         * <BR /><B CLASS=Opt>OPTIONAL</B>
241         * 
242         * @param excludedCategories Excluded category filters.
243         * <BR /><B CLASS=Opt>OPTIONAL</B>
244         * 
245         * @param syntheticDelays Configuration to synthesize the delays in tracing.
246         * <BR /><B CLASS=Opt>OPTIONAL</B><B CLASS=Exp>EXPERIMENTAL</B>
247         * 
248         * @param memoryDumpConfig Configuration for memory dump triggers. Used only when "memory-infra" category is enabled.
249         * <BR /><B CLASS=Opt>OPTIONAL</B><B CLASS=Exp>EXPERIMENTAL</B>
250         */
251        public TraceConfig(
252                String recordMode, Number traceBufferSizeInKb, Boolean enableSampling, 
253                Boolean enableSystrace, Boolean enableArgumentFilter, String[] includedCategories, 
254                String[] excludedCategories, String[] syntheticDelays, JsonObject memoryDumpConfig
255            )
256        {
257            // Exception-Check(s) to ensure that if any parameters which must adhere to a
258            // provided List of Enumerated Values, fails, then IllegalArgumentException shall throw.
259            
260            THROWS.checkIAE(
261                "recordMode", recordMode,
262                "recordUntilFull", "recordContinuously", "recordAsMuchAsPossible", "echoToConsole"
263            );
264            
265            this.recordMode            = recordMode;
266            this.traceBufferSizeInKb   = traceBufferSizeInKb;
267            this.enableSampling        = enableSampling;
268            this.enableSystrace        = enableSystrace;
269            this.enableArgumentFilter  = enableArgumentFilter;
270            this.includedCategories    = includedCategories;
271            this.excludedCategories    = excludedCategories;
272            this.syntheticDelays       = syntheticDelays;
273            this.memoryDumpConfig      = memoryDumpConfig;
274        }
275        
276        /**
277         * JSON Object Constructor
278         * @param jo A Json-Object having data about an instance of {@code 'TraceConfig'}.
279         */
280        public TraceConfig (JsonObject jo)
281        {
282            this.recordMode            = ReadJSON.getString(jo, "recordMode", true, false);
283            this.traceBufferSizeInKb   = ReadNumberJSON.get(jo, "traceBufferSizeInKb", true, false);
284            this.enableSampling        = ReadBoxedJSON.getBoolean(jo, "enableSampling", true);
285            this.enableSystrace        = ReadBoxedJSON.getBoolean(jo, "enableSystrace", true);
286            this.enableArgumentFilter  = ReadBoxedJSON.getBoolean(jo, "enableArgumentFilter", true);
287            this.includedCategories = (jo.getJsonArray("includedCategories") == null)
288                ? null
289                : RJArrIntoStream.strArr(jo.getJsonArray("includedCategories"), null, 0).toArray(String[]::new);
290        
291            this.excludedCategories = (jo.getJsonArray("excludedCategories") == null)
292                ? null
293                : RJArrIntoStream.strArr(jo.getJsonArray("excludedCategories"), null, 0).toArray(String[]::new);
294        
295            this.syntheticDelays = (jo.getJsonArray("syntheticDelays") == null)
296                ? null
297                : RJArrIntoStream.strArr(jo.getJsonArray("syntheticDelays"), null, 0).toArray(String[]::new);
298        
299            this.memoryDumpConfig      = jo.getJsonObject("memoryDumpConfig");
300        }
301        
302        
303        /** Checks whether {@code 'this'} equals an input Java-{@code Object} */
304        public boolean equals(Object other)
305        {
306            if (this == other)                       return true;
307            if (other == null)                       return false;
308            if (other.getClass() != this.getClass()) return false;
309        
310            TraceConfig o = (TraceConfig) other;
311        
312            return
313                    Objects.equals(this.recordMode, o.recordMode)
314                &&  Objects.equals(this.traceBufferSizeInKb, o.traceBufferSizeInKb)
315                &&  Objects.equals(this.enableSampling, o.enableSampling)
316                &&  Objects.equals(this.enableSystrace, o.enableSystrace)
317                &&  Objects.equals(this.enableArgumentFilter, o.enableArgumentFilter)
318                &&  Arrays.deepEquals(this.includedCategories, o.includedCategories)
319                &&  Arrays.deepEquals(this.excludedCategories, o.excludedCategories)
320                &&  Arrays.deepEquals(this.syntheticDelays, o.syntheticDelays)
321                &&  Objects.equals(this.memoryDumpConfig, o.memoryDumpConfig);
322        }
323        
324        /** Generates a Hash-Code for {@code 'this'} instance */
325        public int hashCode()
326        {
327            return
328                    Objects.hashCode(this.recordMode)
329                +   Objects.hashCode(this.traceBufferSizeInKb)
330                +   Objects.hashCode(this.enableSampling)
331                +   Objects.hashCode(this.enableSystrace)
332                +   Objects.hashCode(this.enableArgumentFilter)
333                +   Arrays.deepHashCode(this.includedCategories)
334                +   Arrays.deepHashCode(this.excludedCategories)
335                +   Arrays.deepHashCode(this.syntheticDelays)
336                +   this.memoryDumpConfig.hashCode();
337        }
338    }
339    
340    /**
341     * <CODE>[No Description Provided by Google]</CODE>
342     * <BR /><B CLASS=Exp>EXPERIMENTAL</B>
343     */
344    public static class bufferUsage
345        extends BrowserEvent
346        implements java.io.Serializable
347    {
348        /** For Object Serialization.  java.io.Serializable */
349        protected static final long serialVersionUID = 1;
350        
351        public boolean[] optionals()
352        { return new boolean[] { true, true, true, }; }
353        
354        /**
355         * A number in range [0..1] that indicates the used size of event buffer as a fraction of its
356         * total size.
357         * <BR /><B CLASS=Opt>OPTIONAL</B>
358         */
359        public final Number percentFull;
360        
361        /**
362         * An approximate number of events in the trace log.
363         * <BR /><B CLASS=Opt>OPTIONAL</B>
364         */
365        public final Number eventCount;
366        
367        /**
368         * A number in range [0..1] that indicates the used size of event buffer as a fraction of its
369         * total size.
370         * <BR /><B CLASS=Opt>OPTIONAL</B>
371         */
372        public final Number value;
373        
374        /**
375         * Constructor
376         *
377         * @param percentFull 
378         * A number in range [0..1] that indicates the used size of event buffer as a fraction of its
379         * total size.
380         * <BR /><B CLASS=Opt>OPTIONAL</B>
381         * 
382         * @param eventCount An approximate number of events in the trace log.
383         * <BR /><B CLASS=Opt>OPTIONAL</B>
384         * 
385         * @param value 
386         * A number in range [0..1] that indicates the used size of event buffer as a fraction of its
387         * total size.
388         * <BR /><B CLASS=Opt>OPTIONAL</B>
389         */
390        public bufferUsage(Number percentFull, Number eventCount, Number value)
391        {
392            super("Tracing", "bufferUsage", 3);
393            
394            this.percentFull  = percentFull;
395            this.eventCount   = eventCount;
396            this.value        = value;
397        }
398        
399        /**
400         * JSON Object Constructor
401         * @param jo A Json-Object having data about an instance of {@code 'bufferUsage'}.
402         */
403        public bufferUsage (JsonObject jo)
404        {
405            super("Tracing", "bufferUsage", 3);
406        
407            this.percentFull  = ReadNumberJSON.get(jo, "percentFull", true, false);
408            this.eventCount   = ReadNumberJSON.get(jo, "eventCount", true, false);
409            this.value        = ReadNumberJSON.get(jo, "value", true, false);
410        }
411        
412        
413        /** Checks whether {@code 'this'} equals an input Java-{@code Object} */
414        public boolean equals(Object other)
415        {
416            if (this == other)                       return true;
417            if (other == null)                       return false;
418            if (other.getClass() != this.getClass()) return false;
419        
420            bufferUsage o = (bufferUsage) other;
421        
422            return
423                    Objects.equals(this.percentFull, o.percentFull)
424                &&  Objects.equals(this.eventCount, o.eventCount)
425                &&  Objects.equals(this.value, o.value);
426        }
427        
428        /** Generates a Hash-Code for {@code 'this'} instance */
429        public int hashCode()
430        {
431            return
432                    Objects.hashCode(this.percentFull)
433                +   Objects.hashCode(this.eventCount)
434                +   Objects.hashCode(this.value);
435        }
436    }
437    
438    /**
439     * Contains a bucket of collected trace events. When tracing is stopped collected events will be
440     * sent as a sequence of dataCollected events followed by tracingComplete event.
441     * <BR /><B CLASS=Exp>EXPERIMENTAL</B>
442     */
443    public static class dataCollected
444        extends BrowserEvent
445        implements java.io.Serializable
446    {
447        /** For Object Serialization.  java.io.Serializable */
448        protected static final long serialVersionUID = 1;
449        
450        public boolean[] optionals()
451        { return new boolean[] { false, }; }
452        
453        /** <CODE>[No Description Provided by Google]</CODE> */
454        public final JsonArray value;
455        
456        /**
457         * Constructor
458         *
459         * @param value -
460         */
461        public dataCollected(JsonArray value)
462        {
463            super("Tracing", "dataCollected", 1);
464            
465            // Exception-Check(s) to ensure that if any parameters which are not declared as
466            // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
467            
468            if (value == null) THROWS.throwNPE("value");
469            
470            this.value  = value;
471        }
472        
473        /**
474         * JSON Object Constructor
475         * @param jo A Json-Object having data about an instance of {@code 'dataCollected'}.
476         */
477        public dataCollected (JsonObject jo)
478        {
479            super("Tracing", "dataCollected", 1);
480        
481            this.value  = jo.getJsonArray("value");
482        }
483        
484        
485        /** Checks whether {@code 'this'} equals an input Java-{@code Object} */
486        public boolean equals(Object other)
487        {
488            if (this == other)                       return true;
489            if (other == null)                       return false;
490            if (other.getClass() != this.getClass()) return false;
491        
492            dataCollected o = (dataCollected) other;
493        
494            return
495                    Objects.equals(this.value, o.value);
496        }
497        
498        /** Generates a Hash-Code for {@code 'this'} instance */
499        public int hashCode()
500        {
501            return
502                    Objects.hashCode(this.value);
503        }
504    }
505    
506    /**
507     * Signals that tracing is stopped and there is no trace buffers pending flush, all data were
508     * delivered via dataCollected events.
509     */
510    public static class tracingComplete
511        extends BrowserEvent
512        implements java.io.Serializable
513    {
514        /** For Object Serialization.  java.io.Serializable */
515        protected static final long serialVersionUID = 1;
516        
517        public boolean[] optionals()
518        { return new boolean[] { false, true, true, true, }; }
519        
520        /**
521         * Indicates whether some trace data is known to have been lost, e.g. because the trace ring
522         * buffer wrapped around.
523         */
524        public final boolean dataLossOccurred;
525        
526        /**
527         * A handle of the stream that holds resulting trace data.
528         * <BR /><B CLASS=Opt>OPTIONAL</B>
529         */
530        public final String stream;
531        
532        /**
533         * Trace data format of returned stream.
534         * <BR /><B CLASS=Opt>OPTIONAL</B>
535         */
536        public final String traceFormat;
537        
538        /**
539         * Compression format of returned stream.
540         * <BR /><B CLASS=Opt>OPTIONAL</B>
541         */
542        public final String streamCompression;
543        
544        /**
545         * Constructor
546         *
547         * @param dataLossOccurred 
548         * Indicates whether some trace data is known to have been lost, e.g. because the trace ring
549         * buffer wrapped around.
550         * 
551         * @param stream A handle of the stream that holds resulting trace data.
552         * <BR /><B CLASS=Opt>OPTIONAL</B>
553         * 
554         * @param traceFormat Trace data format of returned stream.
555         * <BR /><B CLASS=Opt>OPTIONAL</B>
556         * 
557         * @param streamCompression Compression format of returned stream.
558         * <BR /><B CLASS=Opt>OPTIONAL</B>
559         */
560        public tracingComplete
561            (boolean dataLossOccurred, String stream, String traceFormat, String streamCompression)
562        {
563            super("Tracing", "tracingComplete", 4);
564            
565            // Exception-Check(s) to ensure that if any parameters which must adhere to a
566            // provided List of Enumerated Values, fails, then IllegalArgumentException shall throw.
567            
568            THROWS.checkIAE("traceFormat", traceFormat, "Tracing.StreamFormat", Tracing.StreamFormat);
569            THROWS.checkIAE("streamCompression", streamCompression, "Tracing.StreamCompression", Tracing.StreamCompression);
570            
571            this.dataLossOccurred   = dataLossOccurred;
572            this.stream             = stream;
573            this.traceFormat        = traceFormat;
574            this.streamCompression  = streamCompression;
575        }
576        
577        /**
578         * JSON Object Constructor
579         * @param jo A Json-Object having data about an instance of {@code 'tracingComplete'}.
580         */
581        public tracingComplete (JsonObject jo)
582        {
583            super("Tracing", "tracingComplete", 4);
584        
585            this.dataLossOccurred   = ReadPrimJSON.getBoolean(jo, "dataLossOccurred");
586            this.stream             = ReadJSON.getString(jo, "stream", true, false);
587            this.traceFormat        = ReadJSON.getString(jo, "traceFormat", true, false);
588            this.streamCompression  = ReadJSON.getString(jo, "streamCompression", true, false);
589        }
590        
591        
592        /** Checks whether {@code 'this'} equals an input Java-{@code Object} */
593        public boolean equals(Object other)
594        {
595            if (this == other)                       return true;
596            if (other == null)                       return false;
597            if (other.getClass() != this.getClass()) return false;
598        
599            tracingComplete o = (tracingComplete) other;
600        
601            return
602                    (this.dataLossOccurred == o.dataLossOccurred)
603                &&  Objects.equals(this.stream, o.stream)
604                &&  Objects.equals(this.traceFormat, o.traceFormat)
605                &&  Objects.equals(this.streamCompression, o.streamCompression);
606        }
607        
608        /** Generates a Hash-Code for {@code 'this'} instance */
609        public int hashCode()
610        {
611            return
612                    (this.dataLossOccurred ? 1 : 0)
613                +   Objects.hashCode(this.stream)
614                +   Objects.hashCode(this.traceFormat)
615                +   Objects.hashCode(this.streamCompression);
616        }
617    }
618    
619    
620    // Counter for keeping the WebSocket Request ID's distinct.
621    private static int counter = 1;
622    
623    /**
624     * Stop trace events collection.
625     * 
626     * @return An instance of <CODE>{@link Script}&lt;String, {@link JsonObject},
627     * {@link Ret0}&gt;</CODE>
628     *
629     * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the
630     * browser receives the invocation-request.
631     *
632     * <BR /><BR />This Browser-Function <I>does not have</I> a return-value.  You may choose to
633     * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0}
634     * {@code >} to ensure the Browser Function has run to completion.
635     */
636    public static Script<String, JsonObject, Ret0> end()
637    {
638        final int          webSocketID = 44000000 + counter++;
639        final boolean[]    optionals   = new boolean[0];
640        
641        // Convert Method Parameters into JSON.  Build the JSON Request-Object (as a String)
642        String requestJSON = WriteJSON.get(
643            parameterTypes.get("end"),
644            parameterNames.get("end"),
645            optionals, webSocketID,
646            "Tracing.end"
647        );
648        
649        // This Remote Command does not have a Return-Value.
650        return new Script<>
651            (webSocketID, requestJSON, VOID_RETURN.NoReturnValues);
652    }
653    
654    /**
655     * Gets supported tracing categories.
656     * <BR /><B CLASS=Exp-Top>EXPERIMENTAL</B>
657     * 
658     * @return An instance of <CODE>{@link Script}&lt;String, {@link JsonObject},
659     * String[]&gt;</CODE>
660     * 
661     * <BR /><BR />This <B>script</B> may be <B STYLE='color: red'>executed</B>, using
662     * {@link Script#exec()}, and afterwards, a {@link Promise}<CODE>&lt;JsonObject,
663     * String[]&gt;</CODE> will be returned.
664     *
665     * <BR /><BR />Finally, the <B>{@code Promise}</B> may be <B STYLE='color: red'>awaited</B>,
666     * using {@link Promise#await()}, <I>and the returned result of this Browser Function may
667      * may be retrieved.</I>
668     *
669     * <BR /><BR />This Browser Function <B STYLE='color: red'>returns</B>
670     * <BR /><BR /><UL CLASS=JDUL>
671     * <LI><CODE>String[] (<B>categories</B></CODE>)
672     *     <BR />A list of supported tracing categories.
673     * </LI>
674     * </UL> */
675    public static Script<String, JsonObject, String[]> getCategories()
676    {
677        final int          webSocketID = 44001000 + counter++;
678        final boolean[]    optionals   = new boolean[0];
679        
680        // Convert Method Parameters into JSON.  Build the JSON Request-Object (as a String)
681        String requestJSON = WriteJSON.get(
682            parameterTypes.get("getCategories"),
683            parameterNames.get("getCategories"),
684            optionals, webSocketID,
685            "Tracing.getCategories"
686        );
687        
688        // 'JSON Binding' ... Converts Browser Response-JSON to 'String[]'
689        Function<JsonObject, String[]> responseProcessor = (JsonObject jo) ->
690            (jo.getJsonArray("categories") == null)
691                ? null
692                : RJArrIntoStream.strArr(jo.getJsonArray("categories"), null, 0).toArray(String[]::new);
693        
694        return new Script<>(webSocketID, requestJSON, responseProcessor);
695    }
696    
697    /**
698     * Record a clock sync marker in the trace.
699     * <BR /><B CLASS=Exp-Top>EXPERIMENTAL</B>
700     * 
701     * @param syncId The ID of this clock sync marker
702     * 
703     * @return An instance of <CODE>{@link Script}&lt;String, {@link JsonObject},
704     * {@link Ret0}&gt;</CODE>
705     *
706     * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the
707     * browser receives the invocation-request.
708     *
709     * <BR /><BR />This Browser-Function <I>does not have</I> a return-value.  You may choose to
710     * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0}
711     * {@code >} to ensure the Browser Function has run to completion.
712     */
713    public static Script<String, JsonObject, Ret0> recordClockSyncMarker(String syncId)
714    {
715        // Exception-Check(s) to ensure that if any parameters which are not declared as
716        // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
717        
718        if (syncId == null) THROWS.throwNPE("syncId");
719        
720        final int       webSocketID = 44002000 + counter++;
721        final boolean[] optionals   = { false, };
722        
723        // Convert Method Parameters into JSON.  Build the JSON Request-Object (as a String)
724        String requestJSON = WriteJSON.get(
725            parameterTypes.get("recordClockSyncMarker"),
726            parameterNames.get("recordClockSyncMarker"),
727            optionals, webSocketID,
728            "Tracing.recordClockSyncMarker",
729            syncId
730        );
731        
732        // This Remote Command does not have a Return-Value.
733        return new Script<>
734            (webSocketID, requestJSON, VOID_RETURN.NoReturnValues);
735    }
736    
737    /**
738     * Request a global memory dump.
739     * <BR /><B CLASS=Exp-Top>EXPERIMENTAL</B>
740     * 
741     * @param deterministic Enables more deterministic results by forcing garbage collection
742     * <BR /><B CLASS=Opt>OPTIONAL</B>
743     * 
744     * @param levelOfDetail Specifies level of details in memory dump. Defaults to "detailed".
745     * <BR /><B CLASS=Opt>OPTIONAL</B>
746     * 
747     * @return An instance of <CODE>{@link Script}&lt;String, {@link JsonObject},
748     * {@link Ret2}&gt;</CODE>
749     *
750     * <BR /><BR />This {@link Script} may be <B STYLE='color:red'>executed</B> (using 
751     * {@link Script#exec()}), and a {@link Promise} returned.
752     *
753     * <BR /><BR />When the {@code Promise} is <B STYLE='color: red'>awaited</B>
754     * (using {@link Promise#await()}), the {@code Ret2} will subsequently
755     * be returned from that call.
756     * 
757     * <BR /><BR />The <B STYLE='color: red'>returned</B> values are encapsulated
758     * in an instance of <B>{@link Ret2}</B>
759     *
760     * <BR /><BR /><UL CLASS=JDUL>
761     * <LI><CODE><B>Ret2.a:</B> String (<B>dumpGuid</B>)</CODE>
762     *     <BR />GUID of the resulting global memory dump.
763     *     <BR /><BR /></LI>
764     * <LI><CODE><B>Ret2.b:</B> Boolean (<B>success</B>)</CODE>
765     *     <BR />True iff the global memory dump succeeded.
766     *     </LI>
767     * </UL>
768     */
769    public static Script<String, JsonObject, Ret2<String, Boolean>> requestMemoryDump
770        (Boolean deterministic, String levelOfDetail)
771    {
772        // Exception-Check(s) to ensure that if any parameters which must adhere to a
773        // provided List of Enumerated Values, fails, then IllegalArgumentException shall throw.
774        
775        THROWS.checkIAE("levelOfDetail", levelOfDetail, "Tracing.MemoryDumpLevelOfDetail", Tracing.MemoryDumpLevelOfDetail);
776        
777        final int       webSocketID = 44003000 + counter++;
778        final boolean[] optionals   = { true, true, };
779        
780        // Convert Method Parameters into JSON.  Build the JSON Request-Object (as a String)
781        String requestJSON = WriteJSON.get(
782            parameterTypes.get("requestMemoryDump"),
783            parameterNames.get("requestMemoryDump"),
784            optionals, webSocketID,
785            "Tracing.requestMemoryDump",
786            deterministic, levelOfDetail
787        );
788        
789        // 'JSON Binding' ... Converts Browser Response-JSON into Java-Type 'Ret2'
790        Function<JsonObject, Ret2<String, Boolean>>
791            responseProcessor = (JsonObject jo) -> new Ret2<>(
792                ReadJSON.getString(jo, "dumpGuid", false, true),
793                ReadBoxedJSON.getBoolean(jo, "success", true)
794            );
795        
796        return new Script<>(webSocketID, requestJSON, responseProcessor);
797    }
798    
799    /**
800     * Start trace events collection.
801     * 
802     * @param categories Category/tag filter
803     * <BR /><B CLASS=Opt>OPTIONAL</B><B CLASS=Exp>EXPERIMENTAL</B><B CLASS=Dep>DEPRECATED</B>
804     * 
805     * @param options Tracing options
806     * <BR /><B CLASS=Opt>OPTIONAL</B><B CLASS=Exp>EXPERIMENTAL</B><B CLASS=Dep>DEPRECATED</B>
807     * 
808     * @param bufferUsageReportingInterval If set, the agent will issue bufferUsage events at this interval, specified in milliseconds
809     * <BR /><B CLASS=Opt>OPTIONAL</B><B CLASS=Exp>EXPERIMENTAL</B>
810     * 
811     * @param transferMode 
812     * Whether to report trace events as series of dataCollected events or to save trace to a
813     * stream (defaults to {@code ReportEvents}).
814     * <BR />Acceptable Values: ["ReportEvents", "ReturnAsStream"]
815     * <BR /><B CLASS=Opt>OPTIONAL</B>
816     * 
817     * @param streamFormat 
818     * Trace data format to use. This only applies when using {@code ReturnAsStream}
819     * transfer mode (defaults to {@code json}).
820     * <BR /><B CLASS=Opt>OPTIONAL</B>
821     * 
822     * @param streamCompression 
823     * Compression format to use. This only applies when using {@code ReturnAsStream}
824     * transfer mode (defaults to {@code none})
825     * <BR /><B CLASS=Opt>OPTIONAL</B><B CLASS=Exp>EXPERIMENTAL</B>
826     * 
827     * @param traceConfig -
828     * <BR /><B CLASS=Opt>OPTIONAL</B>
829     * 
830     * @param perfettoConfig 
831     * Base64-encoded serialized perfetto.protos.TraceConfig protobuf message
832     * When specified, the parameters {@code categories}, {@code options}, {@code traceConfig}
833     * are ignored. (Encoded as a base64 string when passed over JSON)
834     * <BR /><B CLASS=Opt>OPTIONAL</B><B CLASS=Exp>EXPERIMENTAL</B>
835     * 
836     * @param tracingBackend Backend type (defaults to {@code auto})
837     * <BR /><B CLASS=Opt>OPTIONAL</B><B CLASS=Exp>EXPERIMENTAL</B>
838     * 
839     * @return An instance of <CODE>{@link Script}&lt;String, {@link JsonObject},
840     * {@link Ret0}&gt;</CODE>
841     *
842     * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the
843     * browser receives the invocation-request.
844     *
845     * <BR /><BR />This Browser-Function <I>does not have</I> a return-value.  You may choose to
846     * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0}
847     * {@code >} to ensure the Browser Function has run to completion.
848     */
849    public static Script<String, JsonObject, Ret0> start(
850            String categories, String options, Number bufferUsageReportingInterval, 
851            String transferMode, String streamFormat, String streamCompression, 
852            Tracing.TraceConfig traceConfig, String perfettoConfig, String tracingBackend
853        )
854    {
855        // Exception-Check(s) to ensure that if any parameters which must adhere to a
856        // provided List of Enumerated Values, fails, then IllegalArgumentException shall throw.
857        
858        THROWS.checkIAE(
859            "transferMode", transferMode,
860            "ReportEvents", "ReturnAsStream"
861        );
862        THROWS.checkIAE("streamFormat", streamFormat, "Tracing.StreamFormat", Tracing.StreamFormat);
863        THROWS.checkIAE("streamCompression", streamCompression, "Tracing.StreamCompression", Tracing.StreamCompression);
864        THROWS.checkIAE("tracingBackend", tracingBackend, "Tracing.TracingBackend", Tracing.TracingBackend);
865        
866        final int       webSocketID = 44004000 + counter++;
867        final boolean[] optionals   = { true, true, true, true, true, true, true, true, true, };
868        
869        // Convert Method Parameters into JSON.  Build the JSON Request-Object (as a String)
870        String requestJSON = WriteJSON.get(
871            parameterTypes.get("start"),
872            parameterNames.get("start"),
873            optionals, webSocketID,
874            "Tracing.start",
875            categories, options, bufferUsageReportingInterval, transferMode, streamFormat,
876            streamCompression, traceConfig, perfettoConfig, tracingBackend
877        );
878        
879        // This Remote Command does not have a Return-Value.
880        return new Script<>
881            (webSocketID, requestJSON, VOID_RETURN.NoReturnValues);
882    }
883    
884}