001package Torello.Browser;
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.Java.Additional.*;
013
014import static Torello.Java.Additional.JFlag.*;
015
016import Torello.Java.StrCmpr;
017import Torello.JavaDoc.StaticFunctional;
018import Torello.JavaDoc.JDHeaderBackgroundImg;
019import Torello.JavaDoc.Excuse;
020
021/**
022 * <SPAN CLASS=CopiedJDK><B>This domain allows detailed inspection of media elements</B></SPAN>
023 * 
024 * <EMBED CLASS='external-html' DATA-FILE-ID=CODE_GEN_NOTE>
025 */
026@StaticFunctional(Excused={"counter"}, Excuses={Excuse.CONFIGURATION})
027@JDHeaderBackgroundImg(EmbedTagFileID="WOOD_PLANK_NOTE")
028public class Media
029{
030    // ********************************************************************************************
031    // ********************************************************************************************
032    // Class Header Stuff
033    // ********************************************************************************************
034    // ********************************************************************************************
035
036
037    // No Pubic Constructors
038    private Media () { }
039
040    // These two Vector's are used by all the "Methods" exported by this class.  java.lang.reflect
041    // is used to generate the JSON String's.  It saves thousands of lines of Auto-Generated Code.
042    private static final Map<String, Vector<String>>    parameterNames = new HashMap<>();
043    private static final Map<String, Vector<Class<?>>>  parameterTypes = new HashMap<>();
044
045    // Some Methods do not take any parameters - for instance all the "enable()" and "disable()"
046    // I simply could not get ride of RAW-TYPES and UNCHECKED warnings... so there are now,
047    // offically, two empty-vectors.  One for String's, and the other for Classes.
048
049    private static final Vector<String>     EMPTY_VEC_STR = new Vector<>();
050    private static final Vector<Class<?>>   EMPTY_VEC_CLASS = new Vector<>();
051
052    static
053    {
054        for (Method m : Media.class.getMethods())
055        {
056            // This doesn't work!  The parameter names are all "arg0" ... "argN"
057            // It works for java.lang.reflect.Field, BUT NOT java.lang.reflect.Parameter!
058            //
059            // Vector<String> parameterNamesList = new Vector<>(); -- NOPE!
060
061            Vector<Class<?>> parameterTypesList = new Vector<>();
062        
063            for (Parameter p : m.getParameters()) parameterTypesList.add(p.getType());
064
065            parameterTypes.put(
066                m.getName(),
067                (parameterTypesList.size() > 0) ? parameterTypesList : EMPTY_VEC_CLASS
068            );
069        }
070    }
071
072    static
073    {
074        Vector<String> v = null;
075
076        parameterNames.put("enable", EMPTY_VEC_STR);
077
078        parameterNames.put("disable", EMPTY_VEC_STR);
079    }
080
081
082    // ********************************************************************************************
083    // ********************************************************************************************
084    // Types - Static Inner Classes
085    // ********************************************************************************************
086    // ********************************************************************************************
087
088    // public static class PlayerId => String
089    
090    // public static class Timestamp => Number
091    
092    /**
093     * Have one type per entry in MediaLogRecord::Type
094     * Corresponds to kMessage
095     */
096    public static class PlayerMessage extends BaseType
097    {
098        /** For Object Serialization.  java.io.Serializable */
099        protected static final long serialVersionUID = 1;
100        
101        public boolean[] optionals()
102        { return new boolean[] { false, false, }; }
103        
104        /**
105         * Keep in sync with MediaLogMessageLevel
106         * We are currently keeping the message level 'error' separate from the
107         * PlayerError type because right now they represent different things,
108         * this one being a DVLOG(ERROR) style log message that gets printed
109         * based on what log level is selected in the UI, and the other is a
110         * representation of a media::PipelineStatus object. Soon however we're
111         * going to be moving away from using PipelineStatus for errors and
112         * introducing a new error type which should hopefully let us integrate
113         * the error log level into the PlayerError type.
114         */
115        public final String level;
116        
117        /** <CODE>[No Description Provided by Google]</CODE> */
118        public final String message;
119        
120        /**
121         * Constructor
122         *
123         * @param level 
124         * Keep in sync with MediaLogMessageLevel
125         * We are currently keeping the message level 'error' separate from the
126         * PlayerError type because right now they represent different things,
127         * this one being a DVLOG(ERROR) style log message that gets printed
128         * based on what log level is selected in the UI, and the other is a
129         * representation of a media::PipelineStatus object. Soon however we're
130         * going to be moving away from using PipelineStatus for errors and
131         * introducing a new error type which should hopefully let us integrate
132         * the error log level into the PlayerError type.
133         * <BR />Acceptable Values: ["error", "warning", "info", "debug"]
134         * 
135         * @param message -
136         */
137        public PlayerMessage(String level, String message)
138        {
139            // Exception-Check(s) to ensure that if any parameters which are not declared as
140            // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
141            
142            if (level == null)   BRDPC.throwNPE("level");
143            if (message == null) BRDPC.throwNPE("message");
144            
145            // Exception-Check(s) to ensure that if any parameters which must adhere to a
146            // provided List of Enumerated Values, fails, then IllegalArgumentException shall throw.
147            
148            BRDPC.checkIAE(
149                "level", level,
150                "error", "warning", "info", "debug"
151            );
152            
153            this.level    = level;
154            this.message  = message;
155        }
156        
157        /**
158         * JSON Object Constructor
159         * @param jo A Json-Object having data about an instance of {@code 'PlayerMessage'}.
160         */
161        public PlayerMessage (JsonObject jo)
162        {
163            this.level    = ReadJSON.getString(jo, "level", false, true);
164            this.message  = ReadJSON.getString(jo, "message", false, true);
165        }
166        
167    }
168    
169    /** Corresponds to kMediaPropertyChange */
170    public static class PlayerProperty extends BaseType
171    {
172        /** For Object Serialization.  java.io.Serializable */
173        protected static final long serialVersionUID = 1;
174        
175        public boolean[] optionals()
176        { return new boolean[] { false, false, }; }
177        
178        /** <CODE>[No Description Provided by Google]</CODE> */
179        public final String name;
180        
181        /** <CODE>[No Description Provided by Google]</CODE> */
182        public final String value;
183        
184        /**
185         * Constructor
186         *
187         * @param name -
188         * 
189         * @param value -
190         */
191        public PlayerProperty(String name, String value)
192        {
193            // Exception-Check(s) to ensure that if any parameters which are not declared as
194            // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
195            
196            if (name == null)  BRDPC.throwNPE("name");
197            if (value == null) BRDPC.throwNPE("value");
198            
199            this.name   = name;
200            this.value  = value;
201        }
202        
203        /**
204         * JSON Object Constructor
205         * @param jo A Json-Object having data about an instance of {@code 'PlayerProperty'}.
206         */
207        public PlayerProperty (JsonObject jo)
208        {
209            this.name   = ReadJSON.getString(jo, "name", false, true);
210            this.value  = ReadJSON.getString(jo, "value", false, true);
211        }
212        
213    }
214    
215    /** Corresponds to kMediaEventTriggered */
216    public static class PlayerEvent extends BaseType
217    {
218        /** For Object Serialization.  java.io.Serializable */
219        protected static final long serialVersionUID = 1;
220        
221        public boolean[] optionals()
222        { return new boolean[] { false, false, }; }
223        
224        /** <CODE>[No Description Provided by Google]</CODE> */
225        public final Number timestamp;
226        
227        /** <CODE>[No Description Provided by Google]</CODE> */
228        public final String value;
229        
230        /**
231         * Constructor
232         *
233         * @param timestamp -
234         * 
235         * @param value -
236         */
237        public PlayerEvent(Number timestamp, String value)
238        {
239            // Exception-Check(s) to ensure that if any parameters which are not declared as
240            // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
241            
242            if (timestamp == null) BRDPC.throwNPE("timestamp");
243            if (value == null)     BRDPC.throwNPE("value");
244            
245            this.timestamp  = timestamp;
246            this.value      = value;
247        }
248        
249        /**
250         * JSON Object Constructor
251         * @param jo A Json-Object having data about an instance of {@code 'PlayerEvent'}.
252         */
253        public PlayerEvent (JsonObject jo)
254        {
255            this.timestamp  = ReadJSON.getNUMBER(jo, "timestamp", false, true);
256            this.value      = ReadJSON.getString(jo, "value", false, true);
257        }
258        
259    }
260    
261    /** Corresponds to kMediaError */
262    public static class PlayerError extends BaseType
263    {
264        /** For Object Serialization.  java.io.Serializable */
265        protected static final long serialVersionUID = 1;
266        
267        public boolean[] optionals()
268        { return new boolean[] { false, false, }; }
269        
270        /** <CODE>[No Description Provided by Google]</CODE> */
271        public final String type;
272        
273        /**
274         * When this switches to using media::Status instead of PipelineStatus
275         * we can remove "errorCode" and replace it with the fields from
276         * a Status instance. This also seems like a duplicate of the error
277         * level enum - there is a todo bug to have that level removed and
278         * use this instead. (crbug.com/1068454)
279         */
280        public final String errorCode;
281        
282        /**
283         * Constructor
284         *
285         * @param type -
286         * <BR />Acceptable Values: ["pipeline_error", "media_error"]
287         * 
288         * @param errorCode 
289         * When this switches to using media::Status instead of PipelineStatus
290         * we can remove "errorCode" and replace it with the fields from
291         * a Status instance. This also seems like a duplicate of the error
292         * level enum - there is a todo bug to have that level removed and
293         * use this instead. (crbug.com/1068454)
294         */
295        public PlayerError(String type, String errorCode)
296        {
297            // Exception-Check(s) to ensure that if any parameters which are not declared as
298            // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
299            
300            if (type == null)      BRDPC.throwNPE("type");
301            if (errorCode == null) BRDPC.throwNPE("errorCode");
302            
303            // Exception-Check(s) to ensure that if any parameters which must adhere to a
304            // provided List of Enumerated Values, fails, then IllegalArgumentException shall throw.
305            
306            BRDPC.checkIAE(
307                "type", type,
308                "pipeline_error", "media_error"
309            );
310            
311            this.type       = type;
312            this.errorCode  = errorCode;
313        }
314        
315        /**
316         * JSON Object Constructor
317         * @param jo A Json-Object having data about an instance of {@code 'PlayerError'}.
318         */
319        public PlayerError (JsonObject jo)
320        {
321            this.type       = ReadJSON.getString(jo, "type", false, true);
322            this.errorCode  = ReadJSON.getString(jo, "errorCode", false, true);
323        }
324        
325    }
326    
327    /**
328     * This can be called multiple times, and can be used to set / override /
329     * remove player properties. A null propValue indicates removal.
330     */
331    public static class playerPropertiesChanged extends BrowserEvent
332    {
333        /** For Object Serialization.  java.io.Serializable */
334        protected static final long serialVersionUID = 1;
335        
336        public boolean[] optionals()
337        { return new boolean[] { false, false, }; }
338        
339        /** <CODE>[No Description Provided by Google]</CODE> */
340        public final String playerId;
341        
342        /** <CODE>[No Description Provided by Google]</CODE> */
343        public final Media.PlayerProperty[] properties;
344        
345        /**
346         * Constructor
347         *
348         * @param playerId -
349         * 
350         * @param properties -
351         */
352        public playerPropertiesChanged(String playerId, Media.PlayerProperty[] properties)
353        {
354            super("Media", "playerPropertiesChanged", 2);
355            
356            // Exception-Check(s) to ensure that if any parameters which are not declared as
357            // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
358            
359            if (playerId == null)   BRDPC.throwNPE("playerId");
360            if (properties == null) BRDPC.throwNPE("properties");
361            
362            this.playerId    = playerId;
363            this.properties  = properties;
364        }
365        
366        /**
367         * JSON Object Constructor
368         * @param jo A Json-Object having data about an instance of {@code 'playerPropertiesChanged'}.
369         */
370        public playerPropertiesChanged (JsonObject jo)
371        {
372            super("Media", "playerPropertiesChanged", 2);
373        
374            this.playerId    = ReadJSON.getString(jo, "playerId", false, true);
375            this.properties  = (jo.getJsonArray("properties") == null)
376            ? null
377            : ReadArrJSON.DimN.objArr(jo.getJsonArray("properties"), null, 0, Media.PlayerProperty[].class);
378        }
379        
380    }
381    
382    /**
383     * Send events as a list, allowing them to be batched on the browser for less
384     * congestion. If batched, events must ALWAYS be in chronological order.
385     */
386    public static class playerEventsAdded extends BrowserEvent
387    {
388        /** For Object Serialization.  java.io.Serializable */
389        protected static final long serialVersionUID = 1;
390        
391        public boolean[] optionals()
392        { return new boolean[] { false, false, }; }
393        
394        /** <CODE>[No Description Provided by Google]</CODE> */
395        public final String playerId;
396        
397        /** <CODE>[No Description Provided by Google]</CODE> */
398        public final Media.PlayerEvent[] events;
399        
400        /**
401         * Constructor
402         *
403         * @param playerId -
404         * 
405         * @param events -
406         */
407        public playerEventsAdded(String playerId, Media.PlayerEvent[] events)
408        {
409            super("Media", "playerEventsAdded", 2);
410            
411            // Exception-Check(s) to ensure that if any parameters which are not declared as
412            // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
413            
414            if (playerId == null) BRDPC.throwNPE("playerId");
415            if (events == null)   BRDPC.throwNPE("events");
416            
417            this.playerId  = playerId;
418            this.events    = events;
419        }
420        
421        /**
422         * JSON Object Constructor
423         * @param jo A Json-Object having data about an instance of {@code 'playerEventsAdded'}.
424         */
425        public playerEventsAdded (JsonObject jo)
426        {
427            super("Media", "playerEventsAdded", 2);
428        
429            this.playerId  = ReadJSON.getString(jo, "playerId", false, true);
430            this.events    = (jo.getJsonArray("events") == null)
431            ? null
432            : ReadArrJSON.DimN.objArr(jo.getJsonArray("events"), null, 0, Media.PlayerEvent[].class);
433        }
434        
435    }
436    
437    /** Send a list of any messages that need to be delivered. */
438    public static class playerMessagesLogged extends BrowserEvent
439    {
440        /** For Object Serialization.  java.io.Serializable */
441        protected static final long serialVersionUID = 1;
442        
443        public boolean[] optionals()
444        { return new boolean[] { false, false, }; }
445        
446        /** <CODE>[No Description Provided by Google]</CODE> */
447        public final String playerId;
448        
449        /** <CODE>[No Description Provided by Google]</CODE> */
450        public final Media.PlayerMessage[] messages;
451        
452        /**
453         * Constructor
454         *
455         * @param playerId -
456         * 
457         * @param messages -
458         */
459        public playerMessagesLogged(String playerId, Media.PlayerMessage[] messages)
460        {
461            super("Media", "playerMessagesLogged", 2);
462            
463            // Exception-Check(s) to ensure that if any parameters which are not declared as
464            // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
465            
466            if (playerId == null) BRDPC.throwNPE("playerId");
467            if (messages == null) BRDPC.throwNPE("messages");
468            
469            this.playerId  = playerId;
470            this.messages  = messages;
471        }
472        
473        /**
474         * JSON Object Constructor
475         * @param jo A Json-Object having data about an instance of {@code 'playerMessagesLogged'}.
476         */
477        public playerMessagesLogged (JsonObject jo)
478        {
479            super("Media", "playerMessagesLogged", 2);
480        
481            this.playerId  = ReadJSON.getString(jo, "playerId", false, true);
482            this.messages  = (jo.getJsonArray("messages") == null)
483            ? null
484            : ReadArrJSON.DimN.objArr(jo.getJsonArray("messages"), null, 0, Media.PlayerMessage[].class);
485        }
486        
487    }
488    
489    /** Send a list of any errors that need to be delivered. */
490    public static class playerErrorsRaised extends BrowserEvent
491    {
492        /** For Object Serialization.  java.io.Serializable */
493        protected static final long serialVersionUID = 1;
494        
495        public boolean[] optionals()
496        { return new boolean[] { false, false, }; }
497        
498        /** <CODE>[No Description Provided by Google]</CODE> */
499        public final String playerId;
500        
501        /** <CODE>[No Description Provided by Google]</CODE> */
502        public final Media.PlayerError[] errors;
503        
504        /**
505         * Constructor
506         *
507         * @param playerId -
508         * 
509         * @param errors -
510         */
511        public playerErrorsRaised(String playerId, Media.PlayerError[] errors)
512        {
513            super("Media", "playerErrorsRaised", 2);
514            
515            // Exception-Check(s) to ensure that if any parameters which are not declared as
516            // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
517            
518            if (playerId == null) BRDPC.throwNPE("playerId");
519            if (errors == null)   BRDPC.throwNPE("errors");
520            
521            this.playerId  = playerId;
522            this.errors    = errors;
523        }
524        
525        /**
526         * JSON Object Constructor
527         * @param jo A Json-Object having data about an instance of {@code 'playerErrorsRaised'}.
528         */
529        public playerErrorsRaised (JsonObject jo)
530        {
531            super("Media", "playerErrorsRaised", 2);
532        
533            this.playerId  = ReadJSON.getString(jo, "playerId", false, true);
534            this.errors    = (jo.getJsonArray("errors") == null)
535            ? null
536            : ReadArrJSON.DimN.objArr(jo.getJsonArray("errors"), null, 0, Media.PlayerError[].class);
537        }
538        
539    }
540    
541    /**
542     * Called whenever a player is created, or when a new agent joins and receives
543     * a list of active players. If an agent is restored, it will receive the full
544     * list of player ids and all events again.
545     */
546    public static class playersCreated extends BrowserEvent
547    {
548        /** For Object Serialization.  java.io.Serializable */
549        protected static final long serialVersionUID = 1;
550        
551        public boolean[] optionals()
552        { return new boolean[] { false, }; }
553        
554        /** <CODE>[No Description Provided by Google]</CODE> */
555        public final String[] players;
556        
557        /**
558         * Constructor
559         *
560         * @param players -
561         */
562        public playersCreated(String[] players)
563        {
564            super("Media", "playersCreated", 1);
565            
566            // Exception-Check(s) to ensure that if any parameters which are not declared as
567            // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
568            
569            if (players == null) BRDPC.throwNPE("players");
570            
571            this.players  = players;
572        }
573        
574        /**
575         * JSON Object Constructor
576         * @param jo A Json-Object having data about an instance of {@code 'playersCreated'}.
577         */
578        public playersCreated (JsonObject jo)
579        {
580            super("Media", "playersCreated", 1);
581        
582            this.players  = (jo.getJsonArray("players") == null)
583            ? null
584            : ReadArrJSON.DimN.strArr(jo.getJsonArray("players"), null, 0, String[].class);
585        }
586        
587    }
588    
589    
590    // Counter for keeping the WebSocket Request ID's distinct.
591    private static int counter = 1;
592    
593    /**
594     * Enables the Media domain
595     * 
596     * @return An instance of <CODE>{@link Script}&lt;String, {@link JsonObject},
597     * {@link Ret0}&gt;</CODE>
598     *
599     * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the
600     * browser receives the invocation-request.
601     *
602     * <BR /><BR />This Browser-Function <I>does not have</I> a return-value.  You may choose to
603     * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0}
604     * {@code >} to ensure the Browser Function has run to completion.
605     */
606    public static Script<String, JsonObject, Ret0> enable()
607    {
608        final int          webSocketID = 45000000 + counter++;
609        final boolean[]    optionals   = new boolean[0];
610        
611        // Convert Method Parameters into JSON.  Build the JSON Request-Object (as a String)
612        String requestJSON = WriteJSON.get(
613            parameterTypes.get("enable"),
614            parameterNames.get("enable"),
615            optionals, webSocketID,
616            "Media.enable"
617        );
618        
619        // This Remote Command does not have a Return-Value.
620        return new Script<>
621            (BRDPC.defaultSender, webSocketID, requestJSON, BRDPC.NoReturnValues);
622    }
623    
624    /**
625     * Disables the Media domain.
626     * 
627     * @return An instance of <CODE>{@link Script}&lt;String, {@link JsonObject},
628     * {@link Ret0}&gt;</CODE>
629     *
630     * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the
631     * browser receives the invocation-request.
632     *
633     * <BR /><BR />This Browser-Function <I>does not have</I> a return-value.  You may choose to
634     * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0}
635     * {@code >} to ensure the Browser Function has run to completion.
636     */
637    public static Script<String, JsonObject, Ret0> disable()
638    {
639        final int          webSocketID = 45001000 + counter++;
640        final boolean[]    optionals   = new boolean[0];
641        
642        // Convert Method Parameters into JSON.  Build the JSON Request-Object (as a String)
643        String requestJSON = WriteJSON.get(
644            parameterTypes.get("disable"),
645            parameterNames.get("disable"),
646            optionals, webSocketID,
647            "Media.disable"
648        );
649        
650        // This Remote Command does not have a Return-Value.
651        return new Script<>
652            (BRDPC.defaultSender, webSocketID, requestJSON, BRDPC.NoReturnValues);
653    }
654    
655}