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>The SystemInfo domain defines methods and events for querying low-level system information.</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 SystemInfo
034{
035    // ********************************************************************************************
036    // ********************************************************************************************
037    // Class Header Stuff
038    // ********************************************************************************************
039    // ********************************************************************************************
040
041
042    // No Pubic Constructors
043    private SystemInfo () { }
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 : SystemInfo.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("getInfo", EMPTY_VEC_STR);
082
083        v = new Vector<String>(1);
084        parameterNames.put("getFeatureState", v);
085        Collections.addAll(v, new String[]
086        { "featureState", });
087
088        parameterNames.put("getProcessInfo", EMPTY_VEC_STR);
089    }
090
091
092    // ********************************************************************************************
093    // ********************************************************************************************
094    // Types - Static Inner Classes
095    // ********************************************************************************************
096    // ********************************************************************************************
097
098    /** YUV subsampling type of the pixels of a given image. */
099    public static final String[] SubsamplingFormat =
100    { "yuv420", "yuv422", "yuv444", };
101    
102    /** Image format of a given image. */
103    public static final String[] ImageType =
104    { "jpeg", "webp", "unknown", };
105    
106    /** Describes a single graphics processor (GPU). */
107    public static class GPUDevice
108        extends BaseType
109        implements java.io.Serializable
110    {
111        /** For Object Serialization.  java.io.Serializable */
112        protected static final long serialVersionUID = 1;
113        
114        public boolean[] optionals()
115        { return new boolean[] { false, false, true, true, false, false, false, false, }; }
116        
117        /** PCI ID of the GPU vendor, if available; 0 otherwise. */
118        public final Number vendorId;
119        
120        /** PCI ID of the GPU device, if available; 0 otherwise. */
121        public final Number deviceId;
122        
123        /**
124         * Sub sys ID of the GPU, only available on Windows.
125         * <BR /><B CLASS=Opt>OPTIONAL</B>
126         */
127        public final Number subSysId;
128        
129        /**
130         * Revision of the GPU, only available on Windows.
131         * <BR /><B CLASS=Opt>OPTIONAL</B>
132         */
133        public final Number revision;
134        
135        /** String description of the GPU vendor, if the PCI ID is not available. */
136        public final String vendorString;
137        
138        /** String description of the GPU device, if the PCI ID is not available. */
139        public final String deviceString;
140        
141        /** String description of the GPU driver vendor. */
142        public final String driverVendor;
143        
144        /** String description of the GPU driver version. */
145        public final String driverVersion;
146        
147        /**
148         * Constructor
149         *
150         * @param vendorId PCI ID of the GPU vendor, if available; 0 otherwise.
151         * 
152         * @param deviceId PCI ID of the GPU device, if available; 0 otherwise.
153         * 
154         * @param subSysId Sub sys ID of the GPU, only available on Windows.
155         * <BR /><B CLASS=Opt>OPTIONAL</B>
156         * 
157         * @param revision Revision of the GPU, only available on Windows.
158         * <BR /><B CLASS=Opt>OPTIONAL</B>
159         * 
160         * @param vendorString String description of the GPU vendor, if the PCI ID is not available.
161         * 
162         * @param deviceString String description of the GPU device, if the PCI ID is not available.
163         * 
164         * @param driverVendor String description of the GPU driver vendor.
165         * 
166         * @param driverVersion String description of the GPU driver version.
167         */
168        public GPUDevice(
169                Number vendorId, Number deviceId, Number subSysId, Number revision, 
170                String vendorString, String deviceString, String driverVendor, String driverVersion
171            )
172        {
173            // Exception-Check(s) to ensure that if any parameters which are not declared as
174            // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
175            
176            if (vendorId == null)      THROWS.throwNPE("vendorId");
177            if (deviceId == null)      THROWS.throwNPE("deviceId");
178            if (vendorString == null)  THROWS.throwNPE("vendorString");
179            if (deviceString == null)  THROWS.throwNPE("deviceString");
180            if (driverVendor == null)  THROWS.throwNPE("driverVendor");
181            if (driverVersion == null) THROWS.throwNPE("driverVersion");
182            
183            this.vendorId       = vendorId;
184            this.deviceId       = deviceId;
185            this.subSysId       = subSysId;
186            this.revision       = revision;
187            this.vendorString   = vendorString;
188            this.deviceString   = deviceString;
189            this.driverVendor   = driverVendor;
190            this.driverVersion  = driverVersion;
191        }
192        
193        /**
194         * JSON Object Constructor
195         * @param jo A Json-Object having data about an instance of {@code 'GPUDevice'}.
196         */
197        public GPUDevice (JsonObject jo)
198        {
199            this.vendorId       = ReadNumberJSON.get(jo, "vendorId", false, true);
200            this.deviceId       = ReadNumberJSON.get(jo, "deviceId", false, true);
201            this.subSysId       = ReadNumberJSON.get(jo, "subSysId", true, false);
202            this.revision       = ReadNumberJSON.get(jo, "revision", true, false);
203            this.vendorString   = ReadJSON.getString(jo, "vendorString", false, true);
204            this.deviceString   = ReadJSON.getString(jo, "deviceString", false, true);
205            this.driverVendor   = ReadJSON.getString(jo, "driverVendor", false, true);
206            this.driverVersion  = ReadJSON.getString(jo, "driverVersion", false, true);
207        }
208        
209        
210        /** Checks whether {@code 'this'} equals an input Java-{@code Object} */
211        public boolean equals(Object other)
212        {
213            if (this == other)                       return true;
214            if (other == null)                       return false;
215            if (other.getClass() != this.getClass()) return false;
216        
217            GPUDevice o = (GPUDevice) other;
218        
219            return
220                    Objects.equals(this.vendorId, o.vendorId)
221                &&  Objects.equals(this.deviceId, o.deviceId)
222                &&  Objects.equals(this.subSysId, o.subSysId)
223                &&  Objects.equals(this.revision, o.revision)
224                &&  Objects.equals(this.vendorString, o.vendorString)
225                &&  Objects.equals(this.deviceString, o.deviceString)
226                &&  Objects.equals(this.driverVendor, o.driverVendor)
227                &&  Objects.equals(this.driverVersion, o.driverVersion);
228        }
229        
230        /** Generates a Hash-Code for {@code 'this'} instance */
231        public int hashCode()
232        {
233            return
234                    Objects.hashCode(this.vendorId)
235                +   Objects.hashCode(this.deviceId)
236                +   Objects.hashCode(this.subSysId)
237                +   Objects.hashCode(this.revision)
238                +   Objects.hashCode(this.vendorString)
239                +   Objects.hashCode(this.deviceString)
240                +   Objects.hashCode(this.driverVendor)
241                +   Objects.hashCode(this.driverVersion);
242        }
243    }
244    
245    /** Describes the width and height dimensions of an entity. */
246    public static class Size
247        extends BaseType
248        implements java.io.Serializable
249    {
250        /** For Object Serialization.  java.io.Serializable */
251        protected static final long serialVersionUID = 1;
252        
253        public boolean[] optionals()
254        { return new boolean[] { false, false, }; }
255        
256        /** Width in pixels. */
257        public final int width;
258        
259        /** Height in pixels. */
260        public final int height;
261        
262        /**
263         * Constructor
264         *
265         * @param width Width in pixels.
266         * 
267         * @param height Height in pixels.
268         */
269        public Size(int width, int height)
270        {
271            this.width   = width;
272            this.height  = height;
273        }
274        
275        /**
276         * JSON Object Constructor
277         * @param jo A Json-Object having data about an instance of {@code 'Size'}.
278         */
279        public Size (JsonObject jo)
280        {
281            this.width   = ReadPrimJSON.getInt(jo, "width");
282            this.height  = ReadPrimJSON.getInt(jo, "height");
283        }
284        
285        
286        /** Checks whether {@code 'this'} equals an input Java-{@code Object} */
287        public boolean equals(Object other)
288        {
289            if (this == other)                       return true;
290            if (other == null)                       return false;
291            if (other.getClass() != this.getClass()) return false;
292        
293            Size o = (Size) other;
294        
295            return
296                    (this.width == o.width)
297                &&  (this.height == o.height);
298        }
299        
300        /** Generates a Hash-Code for {@code 'this'} instance */
301        public int hashCode()
302        {
303            return
304                    this.width
305                +   this.height;
306        }
307    }
308    
309    /**
310     * Describes a supported video decoding profile with its associated minimum and
311     * maximum resolutions.
312     */
313    public static class VideoDecodeAcceleratorCapability
314        extends BaseType
315        implements java.io.Serializable
316    {
317        /** For Object Serialization.  java.io.Serializable */
318        protected static final long serialVersionUID = 1;
319        
320        public boolean[] optionals()
321        { return new boolean[] { false, false, false, }; }
322        
323        /** Video codec profile that is supported, e.g. VP9 Profile 2. */
324        public final String profile;
325        
326        /** Maximum video dimensions in pixels supported for this |profile|. */
327        public final SystemInfo.Size maxResolution;
328        
329        /** Minimum video dimensions in pixels supported for this |profile|. */
330        public final SystemInfo.Size minResolution;
331        
332        /**
333         * Constructor
334         *
335         * @param profile Video codec profile that is supported, e.g. VP9 Profile 2.
336         * 
337         * @param maxResolution Maximum video dimensions in pixels supported for this |profile|.
338         * 
339         * @param minResolution Minimum video dimensions in pixels supported for this |profile|.
340         */
341        public VideoDecodeAcceleratorCapability
342            (String profile, SystemInfo.Size maxResolution, SystemInfo.Size minResolution)
343        {
344            // Exception-Check(s) to ensure that if any parameters which are not declared as
345            // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
346            
347            if (profile == null)       THROWS.throwNPE("profile");
348            if (maxResolution == null) THROWS.throwNPE("maxResolution");
349            if (minResolution == null) THROWS.throwNPE("minResolution");
350            
351            this.profile        = profile;
352            this.maxResolution  = maxResolution;
353            this.minResolution  = minResolution;
354        }
355        
356        /**
357         * JSON Object Constructor
358         * @param jo A Json-Object having data about an instance of {@code 'VideoDecodeAcceleratorCapability'}.
359         */
360        public VideoDecodeAcceleratorCapability (JsonObject jo)
361        {
362            this.profile        = ReadJSON.getString(jo, "profile", false, true);
363            this.maxResolution  = ReadJSON.getObject(jo, "maxResolution", SystemInfo.Size.class, false, true);
364            this.minResolution  = ReadJSON.getObject(jo, "minResolution", SystemInfo.Size.class, false, true);
365        }
366        
367        
368        /** Checks whether {@code 'this'} equals an input Java-{@code Object} */
369        public boolean equals(Object other)
370        {
371            if (this == other)                       return true;
372            if (other == null)                       return false;
373            if (other.getClass() != this.getClass()) return false;
374        
375            VideoDecodeAcceleratorCapability o = (VideoDecodeAcceleratorCapability) other;
376        
377            return
378                    Objects.equals(this.profile, o.profile)
379                &&  Objects.equals(this.maxResolution, o.maxResolution)
380                &&  Objects.equals(this.minResolution, o.minResolution);
381        }
382        
383        /** Generates a Hash-Code for {@code 'this'} instance */
384        public int hashCode()
385        {
386            return
387                    Objects.hashCode(this.profile)
388                +   this.maxResolution.hashCode()
389                +   this.minResolution.hashCode();
390        }
391    }
392    
393    /**
394     * Describes a supported video encoding profile with its associated maximum
395     * resolution and maximum framerate.
396     */
397    public static class VideoEncodeAcceleratorCapability
398        extends BaseType
399        implements java.io.Serializable
400    {
401        /** For Object Serialization.  java.io.Serializable */
402        protected static final long serialVersionUID = 1;
403        
404        public boolean[] optionals()
405        { return new boolean[] { false, false, false, false, }; }
406        
407        /** Video codec profile that is supported, e.g H264 Main. */
408        public final String profile;
409        
410        /** Maximum video dimensions in pixels supported for this |profile|. */
411        public final SystemInfo.Size maxResolution;
412        
413        /**
414         * Maximum encoding framerate in frames per second supported for this
415         * |profile|, as fraction's numerator and denominator, e.g. 24/1 fps,
416         * 24000/1001 fps, etc.
417         */
418        public final int maxFramerateNumerator;
419        
420        /** <CODE>[No Description Provided by Google]</CODE> */
421        public final int maxFramerateDenominator;
422        
423        /**
424         * Constructor
425         *
426         * @param profile Video codec profile that is supported, e.g H264 Main.
427         * 
428         * @param maxResolution Maximum video dimensions in pixels supported for this |profile|.
429         * 
430         * @param maxFramerateNumerator 
431         * Maximum encoding framerate in frames per second supported for this
432         * |profile|, as fraction's numerator and denominator, e.g. 24/1 fps,
433         * 24000/1001 fps, etc.
434         * 
435         * @param maxFramerateDenominator -
436         */
437        public VideoEncodeAcceleratorCapability(
438                String profile, SystemInfo.Size maxResolution, int maxFramerateNumerator, 
439                int maxFramerateDenominator
440            )
441        {
442            // Exception-Check(s) to ensure that if any parameters which are not declared as
443            // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
444            
445            if (profile == null)       THROWS.throwNPE("profile");
446            if (maxResolution == null) THROWS.throwNPE("maxResolution");
447            
448            this.profile                  = profile;
449            this.maxResolution            = maxResolution;
450            this.maxFramerateNumerator    = maxFramerateNumerator;
451            this.maxFramerateDenominator  = maxFramerateDenominator;
452        }
453        
454        /**
455         * JSON Object Constructor
456         * @param jo A Json-Object having data about an instance of {@code 'VideoEncodeAcceleratorCapability'}.
457         */
458        public VideoEncodeAcceleratorCapability (JsonObject jo)
459        {
460            this.profile                  = ReadJSON.getString(jo, "profile", false, true);
461            this.maxResolution            = ReadJSON.getObject(jo, "maxResolution", SystemInfo.Size.class, false, true);
462            this.maxFramerateNumerator    = ReadPrimJSON.getInt(jo, "maxFramerateNumerator");
463            this.maxFramerateDenominator  = ReadPrimJSON.getInt(jo, "maxFramerateDenominator");
464        }
465        
466        
467        /** Checks whether {@code 'this'} equals an input Java-{@code Object} */
468        public boolean equals(Object other)
469        {
470            if (this == other)                       return true;
471            if (other == null)                       return false;
472            if (other.getClass() != this.getClass()) return false;
473        
474            VideoEncodeAcceleratorCapability o = (VideoEncodeAcceleratorCapability) other;
475        
476            return
477                    Objects.equals(this.profile, o.profile)
478                &&  Objects.equals(this.maxResolution, o.maxResolution)
479                &&  (this.maxFramerateNumerator == o.maxFramerateNumerator)
480                &&  (this.maxFramerateDenominator == o.maxFramerateDenominator);
481        }
482        
483        /** Generates a Hash-Code for {@code 'this'} instance */
484        public int hashCode()
485        {
486            return
487                    Objects.hashCode(this.profile)
488                +   this.maxResolution.hashCode()
489                +   this.maxFramerateNumerator
490                +   this.maxFramerateDenominator;
491        }
492    }
493    
494    /**
495     * Describes a supported image decoding profile with its associated minimum and
496     * maximum resolutions and subsampling.
497     */
498    public static class ImageDecodeAcceleratorCapability
499        extends BaseType
500        implements java.io.Serializable
501    {
502        /** For Object Serialization.  java.io.Serializable */
503        protected static final long serialVersionUID = 1;
504        
505        public boolean[] optionals()
506        { return new boolean[] { false, false, false, false, }; }
507        
508        /** Image coded, e.g. Jpeg. */
509        public final String imageType;
510        
511        /** Maximum supported dimensions of the image in pixels. */
512        public final SystemInfo.Size maxDimensions;
513        
514        /** Minimum supported dimensions of the image in pixels. */
515        public final SystemInfo.Size minDimensions;
516        
517        /** Optional array of supported subsampling formats, e.g. 4:2:0, if known. */
518        public final String[] subsamplings;
519        
520        /**
521         * Constructor
522         *
523         * @param imageType Image coded, e.g. Jpeg.
524         * 
525         * @param maxDimensions Maximum supported dimensions of the image in pixels.
526         * 
527         * @param minDimensions Minimum supported dimensions of the image in pixels.
528         * 
529         * @param subsamplings Optional array of supported subsampling formats, e.g. 4:2:0, if known.
530         */
531        public ImageDecodeAcceleratorCapability(
532                String imageType, SystemInfo.Size maxDimensions, SystemInfo.Size minDimensions, 
533                String[] subsamplings
534            )
535        {
536            // Exception-Check(s) to ensure that if any parameters which are not declared as
537            // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
538            
539            if (imageType == null)     THROWS.throwNPE("imageType");
540            if (maxDimensions == null) THROWS.throwNPE("maxDimensions");
541            if (minDimensions == null) THROWS.throwNPE("minDimensions");
542            if (subsamplings == null)  THROWS.throwNPE("subsamplings");
543            
544            // Exception-Check(s) to ensure that if any parameters which must adhere to a
545            // provided List of Enumerated Values, fails, then IllegalArgumentException shall throw.
546            
547            THROWS.checkIAE("imageType", imageType, "SystemInfo.ImageType", SystemInfo.ImageType);
548            
549            this.imageType      = imageType;
550            this.maxDimensions  = maxDimensions;
551            this.minDimensions  = minDimensions;
552            this.subsamplings   = subsamplings;
553        }
554        
555        /**
556         * JSON Object Constructor
557         * @param jo A Json-Object having data about an instance of {@code 'ImageDecodeAcceleratorCapability'}.
558         */
559        public ImageDecodeAcceleratorCapability (JsonObject jo)
560        {
561            this.imageType      = ReadJSON.getString(jo, "imageType", false, true);
562            this.maxDimensions  = ReadJSON.getObject(jo, "maxDimensions", SystemInfo.Size.class, false, true);
563            this.minDimensions  = ReadJSON.getObject(jo, "minDimensions", SystemInfo.Size.class, false, true);
564            this.subsamplings = (jo.getJsonArray("subsamplings") == null)
565                ? null
566                : RJArrIntoStream.strArr(jo.getJsonArray("subsamplings"), null, 0).toArray(String[]::new);
567        
568        }
569        
570        
571        /** Checks whether {@code 'this'} equals an input Java-{@code Object} */
572        public boolean equals(Object other)
573        {
574            if (this == other)                       return true;
575            if (other == null)                       return false;
576            if (other.getClass() != this.getClass()) return false;
577        
578            ImageDecodeAcceleratorCapability o = (ImageDecodeAcceleratorCapability) other;
579        
580            return
581                    Objects.equals(this.imageType, o.imageType)
582                &&  Objects.equals(this.maxDimensions, o.maxDimensions)
583                &&  Objects.equals(this.minDimensions, o.minDimensions)
584                &&  Arrays.deepEquals(this.subsamplings, o.subsamplings);
585        }
586        
587        /** Generates a Hash-Code for {@code 'this'} instance */
588        public int hashCode()
589        {
590            return
591                    Objects.hashCode(this.imageType)
592                +   this.maxDimensions.hashCode()
593                +   this.minDimensions.hashCode()
594                +   Arrays.deepHashCode(this.subsamplings);
595        }
596    }
597    
598    /** Provides information about the GPU(s) on the system. */
599    public static class GPUInfo
600        extends BaseType
601        implements java.io.Serializable
602    {
603        /** For Object Serialization.  java.io.Serializable */
604        protected static final long serialVersionUID = 1;
605        
606        public boolean[] optionals()
607        { return new boolean[] { false, true, true, false, false, false, false, }; }
608        
609        /** The graphics devices on the system. Element 0 is the primary GPU. */
610        public final SystemInfo.GPUDevice[] devices;
611        
612        /**
613         * An optional dictionary of additional GPU related attributes.
614         * <BR /><B CLASS=Opt>OPTIONAL</B>
615         */
616        public final JsonObject auxAttributes;
617        
618        /**
619         * An optional dictionary of graphics features and their status.
620         * <BR /><B CLASS=Opt>OPTIONAL</B>
621         */
622        public final JsonObject featureStatus;
623        
624        /** An optional array of GPU driver bug workarounds. */
625        public final String[] driverBugWorkarounds;
626        
627        /** Supported accelerated video decoding capabilities. */
628        public final SystemInfo.VideoDecodeAcceleratorCapability[] videoDecoding;
629        
630        /** Supported accelerated video encoding capabilities. */
631        public final SystemInfo.VideoEncodeAcceleratorCapability[] videoEncoding;
632        
633        /** Supported accelerated image decoding capabilities. */
634        public final SystemInfo.ImageDecodeAcceleratorCapability[] imageDecoding;
635        
636        /**
637         * Constructor
638         *
639         * @param devices The graphics devices on the system. Element 0 is the primary GPU.
640         * 
641         * @param auxAttributes An optional dictionary of additional GPU related attributes.
642         * <BR /><B CLASS=Opt>OPTIONAL</B>
643         * 
644         * @param featureStatus An optional dictionary of graphics features and their status.
645         * <BR /><B CLASS=Opt>OPTIONAL</B>
646         * 
647         * @param driverBugWorkarounds An optional array of GPU driver bug workarounds.
648         * 
649         * @param videoDecoding Supported accelerated video decoding capabilities.
650         * 
651         * @param videoEncoding Supported accelerated video encoding capabilities.
652         * 
653         * @param imageDecoding Supported accelerated image decoding capabilities.
654         */
655        public GPUInfo(
656                SystemInfo.GPUDevice[] devices, JsonObject auxAttributes, JsonObject featureStatus, 
657                String[] driverBugWorkarounds, 
658                SystemInfo.VideoDecodeAcceleratorCapability[] videoDecoding, 
659                SystemInfo.VideoEncodeAcceleratorCapability[] videoEncoding, 
660                SystemInfo.ImageDecodeAcceleratorCapability[] imageDecoding
661            )
662        {
663            // Exception-Check(s) to ensure that if any parameters which are not declared as
664            // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
665            
666            if (devices == null)              THROWS.throwNPE("devices");
667            if (driverBugWorkarounds == null) THROWS.throwNPE("driverBugWorkarounds");
668            if (videoDecoding == null)        THROWS.throwNPE("videoDecoding");
669            if (videoEncoding == null)        THROWS.throwNPE("videoEncoding");
670            if (imageDecoding == null)        THROWS.throwNPE("imageDecoding");
671            
672            this.devices               = devices;
673            this.auxAttributes         = auxAttributes;
674            this.featureStatus         = featureStatus;
675            this.driverBugWorkarounds  = driverBugWorkarounds;
676            this.videoDecoding         = videoDecoding;
677            this.videoEncoding         = videoEncoding;
678            this.imageDecoding         = imageDecoding;
679        }
680        
681        /**
682         * JSON Object Constructor
683         * @param jo A Json-Object having data about an instance of {@code 'GPUInfo'}.
684         */
685        public GPUInfo (JsonObject jo)
686        {
687            this.devices = (jo.getJsonArray("devices") == null)
688                ? null
689                : RJArrIntoStream.objArr(jo.getJsonArray("devices"), null, 0, SystemInfo.GPUDevice.class).toArray(SystemInfo.GPUDevice[]::new);
690        
691            this.auxAttributes         = jo.getJsonObject("auxAttributes");
692            this.featureStatus         = jo.getJsonObject("featureStatus");
693            this.driverBugWorkarounds = (jo.getJsonArray("driverBugWorkarounds") == null)
694                ? null
695                : RJArrIntoStream.strArr(jo.getJsonArray("driverBugWorkarounds"), null, 0).toArray(String[]::new);
696        
697            this.videoDecoding = (jo.getJsonArray("videoDecoding") == null)
698                ? null
699                : RJArrIntoStream.objArr(jo.getJsonArray("videoDecoding"), null, 0, SystemInfo.VideoDecodeAcceleratorCapability.class).toArray(SystemInfo.VideoDecodeAcceleratorCapability[]::new);
700        
701            this.videoEncoding = (jo.getJsonArray("videoEncoding") == null)
702                ? null
703                : RJArrIntoStream.objArr(jo.getJsonArray("videoEncoding"), null, 0, SystemInfo.VideoEncodeAcceleratorCapability.class).toArray(SystemInfo.VideoEncodeAcceleratorCapability[]::new);
704        
705            this.imageDecoding = (jo.getJsonArray("imageDecoding") == null)
706                ? null
707                : RJArrIntoStream.objArr(jo.getJsonArray("imageDecoding"), null, 0, SystemInfo.ImageDecodeAcceleratorCapability.class).toArray(SystemInfo.ImageDecodeAcceleratorCapability[]::new);
708        
709        }
710        
711        
712        /** Checks whether {@code 'this'} equals an input Java-{@code Object} */
713        public boolean equals(Object other)
714        {
715            if (this == other)                       return true;
716            if (other == null)                       return false;
717            if (other.getClass() != this.getClass()) return false;
718        
719            GPUInfo o = (GPUInfo) other;
720        
721            return
722                    Arrays.deepEquals(this.devices, o.devices)
723                &&  Objects.equals(this.auxAttributes, o.auxAttributes)
724                &&  Objects.equals(this.featureStatus, o.featureStatus)
725                &&  Arrays.deepEquals(this.driverBugWorkarounds, o.driverBugWorkarounds)
726                &&  Arrays.deepEquals(this.videoDecoding, o.videoDecoding)
727                &&  Arrays.deepEquals(this.videoEncoding, o.videoEncoding)
728                &&  Arrays.deepEquals(this.imageDecoding, o.imageDecoding);
729        }
730        
731        /** Generates a Hash-Code for {@code 'this'} instance */
732        public int hashCode()
733        {
734            return
735                    Arrays.deepHashCode(this.devices)
736                +   Objects.hashCode(this.auxAttributes)
737                +   Objects.hashCode(this.featureStatus)
738                +   Arrays.deepHashCode(this.driverBugWorkarounds)
739                +   Arrays.deepHashCode(this.videoDecoding)
740                +   Arrays.deepHashCode(this.videoEncoding)
741                +   Arrays.deepHashCode(this.imageDecoding);
742        }
743    }
744    
745    /** Represents process info. */
746    public static class ProcessInfo
747        extends BaseType
748        implements java.io.Serializable
749    {
750        /** For Object Serialization.  java.io.Serializable */
751        protected static final long serialVersionUID = 1;
752        
753        public boolean[] optionals()
754        { return new boolean[] { false, false, false, }; }
755        
756        /** Specifies process type. */
757        public final String type;
758        
759        /** Specifies process id. */
760        public final int id;
761        
762        /**
763         * Specifies cumulative CPU usage in seconds across all threads of the
764         * process since the process start.
765         */
766        public final Number cpuTime;
767        
768        /**
769         * Constructor
770         *
771         * @param type Specifies process type.
772         * 
773         * @param id Specifies process id.
774         * 
775         * @param cpuTime 
776         * Specifies cumulative CPU usage in seconds across all threads of the
777         * process since the process start.
778         */
779        public ProcessInfo(String type, int id, Number cpuTime)
780        {
781            // Exception-Check(s) to ensure that if any parameters which are not declared as
782            // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
783            
784            if (type == null)    THROWS.throwNPE("type");
785            if (cpuTime == null) THROWS.throwNPE("cpuTime");
786            
787            this.type     = type;
788            this.id       = id;
789            this.cpuTime  = cpuTime;
790        }
791        
792        /**
793         * JSON Object Constructor
794         * @param jo A Json-Object having data about an instance of {@code 'ProcessInfo'}.
795         */
796        public ProcessInfo (JsonObject jo)
797        {
798            this.type     = ReadJSON.getString(jo, "type", false, true);
799            this.id       = ReadPrimJSON.getInt(jo, "id");
800            this.cpuTime  = ReadNumberJSON.get(jo, "cpuTime", false, true);
801        }
802        
803        
804        /** Checks whether {@code 'this'} equals an input Java-{@code Object} */
805        public boolean equals(Object other)
806        {
807            if (this == other)                       return true;
808            if (other == null)                       return false;
809            if (other.getClass() != this.getClass()) return false;
810        
811            ProcessInfo o = (ProcessInfo) other;
812        
813            return
814                    Objects.equals(this.type, o.type)
815                &&  (this.id == o.id)
816                &&  Objects.equals(this.cpuTime, o.cpuTime);
817        }
818        
819        /** Generates a Hash-Code for {@code 'this'} instance */
820        public int hashCode()
821        {
822            return
823                    Objects.hashCode(this.type)
824                +   this.id
825                +   Objects.hashCode(this.cpuTime);
826        }
827    }
828    
829    
830    // Counter for keeping the WebSocket Request ID's distinct.
831    private static int counter = 1;
832    
833    /**
834     * Returns information about the system.
835     * 
836     * @return An instance of <CODE>{@link Script}&lt;String, {@link JsonObject},
837     * {@link Ret4}&gt;</CODE>
838     *
839     * <BR /><BR />This {@link Script} may be <B STYLE='color:red'>executed</B> (using 
840     * {@link Script#exec()}), and a {@link Promise} returned.
841     *
842     * <BR /><BR />When the {@code Promise} is <B STYLE='color: red'>awaited</B>
843     * (using {@link Promise#await()}), the {@code Ret4} will subsequently
844     * be returned from that call.
845     * 
846     * <BR /><BR />The <B STYLE='color: red'>returned</B> values are encapsulated
847     * in an instance of <B>{@link Ret4}</B>
848     *
849     * <BR /><BR /><UL CLASS=JDUL>
850     * <LI><CODE><B>Ret4.a:</B> {@link SystemInfo.GPUInfo} (<B>gpu</B>)</CODE>
851     *     <BR />Information about the GPUs on the system.
852     *     <BR /><BR /></LI>
853     * <LI><CODE><B>Ret4.b:</B> String (<B>modelName</B>)</CODE>
854     *     <BR />A platform-dependent description of the model of the machine. On Mac OS, this is, for
855     *     example, 'MacBookPro'. Will be the empty string if not supported.
856     *     <BR /><BR /></LI>
857     * <LI><CODE><B>Ret4.c:</B> String (<B>modelVersion</B>)</CODE>
858     *     <BR />A platform-dependent description of the version of the machine. On Mac OS, this is, for
859     *     example, '10.1'. Will be the empty string if not supported.
860     *     <BR /><BR /></LI>
861     * <LI><CODE><B>Ret4.d:</B> String (<B>commandLine</B>)</CODE>
862     *     <BR />The command line string used to launch the browser. Will be the empty string if not
863     *     supported.
864     *     </LI>
865     * </UL>
866     */
867    public static Script<String, JsonObject, Ret4<SystemInfo.GPUInfo, String, String, String>> getInfo()
868    {
869        final int          webSocketID = 41000000 + counter++;
870        final boolean[]    optionals   = new boolean[0];
871        
872        // Convert Method Parameters into JSON.  Build the JSON Request-Object (as a String)
873        String requestJSON = WriteJSON.get(
874            parameterTypes.get("getInfo"),
875            parameterNames.get("getInfo"),
876            optionals, webSocketID,
877            "SystemInfo.getInfo"
878        );
879        
880        // 'JSON Binding' ... Converts Browser Response-JSON into Java-Type 'Ret4'
881        Function<JsonObject, Ret4<SystemInfo.GPUInfo, String, String, String>>
882            responseProcessor = (JsonObject jo) -> new Ret4<>(
883                ReadJSON.getObject(jo, "gpu", SystemInfo.GPUInfo.class, false, true),
884                ReadJSON.getString(jo, "modelName", false, true),
885                ReadJSON.getString(jo, "modelVersion", false, true),
886                ReadJSON.getString(jo, "commandLine", false, true)
887            );
888        
889        return new Script<>(webSocketID, requestJSON, responseProcessor);
890    }
891    
892    /**
893     * Returns information about the feature state.
894     * 
895     * @param featureState -
896     * 
897     * @return An instance of <CODE>{@link Script}&lt;String, {@link JsonObject},
898     * Boolean&gt;</CODE>
899     * 
900     * <BR /><BR />This <B>script</B> may be <B STYLE='color: red'>executed</B>, using
901     * {@link Script#exec()}, and afterwards, a {@link Promise}<CODE>&lt;JsonObject,
902     * Boolean&gt;</CODE> will be returned.
903     *
904     * <BR /><BR />Finally, the <B>{@code Promise}</B> may be <B STYLE='color: red'>awaited</B>,
905     * using {@link Promise#await()}, <I>and the returned result of this Browser Function may
906      * may be retrieved.</I>
907     *
908     * <BR /><BR />This Browser Function <B STYLE='color: red'>returns</B>
909     * <BR /><BR /><UL CLASS=JDUL>
910     * <LI><CODE>Boolean (<B>featureEnabled</B></CODE>)
911     *     <BR />-
912     * </LI>
913     * </UL> */
914    public static Script<String, JsonObject, Boolean> getFeatureState(String featureState)
915    {
916        // Exception-Check(s) to ensure that if any parameters which are not declared as
917        // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
918        
919        if (featureState == null) THROWS.throwNPE("featureState");
920        
921        final int       webSocketID = 41001000 + counter++;
922        final boolean[] optionals   = { false, };
923        
924        // Convert Method Parameters into JSON.  Build the JSON Request-Object (as a String)
925        String requestJSON = WriteJSON.get(
926            parameterTypes.get("getFeatureState"),
927            parameterNames.get("getFeatureState"),
928            optionals, webSocketID,
929            "SystemInfo.getFeatureState",
930            featureState
931        );
932        
933        // 'JSON Binding' ... Converts Browser Response-JSON to 'Boolean'
934        Function<JsonObject, Boolean> responseProcessor = (JsonObject jo) ->
935            ReadPrimJSON.getBoolean(jo, "featureEnabled");
936        
937        return new Script<>(webSocketID, requestJSON, responseProcessor);
938    }
939    
940    /**
941     * Returns information about all running processes.
942     * 
943     * @return An instance of <CODE>{@link Script}&lt;String, {@link JsonObject},
944     * {@link SystemInfo.ProcessInfo}[]&gt;</CODE>
945     * 
946     * <BR /><BR />This <B>script</B> may be <B STYLE='color: red'>executed</B>, using
947     * {@link Script#exec()}, and afterwards, a {@link Promise}<CODE>&lt;JsonObject,
948     * {@link SystemInfo.ProcessInfo}[]&gt;</CODE> will be returned.
949     *
950     * <BR /><BR />Finally, the <B>{@code Promise}</B> may be <B STYLE='color: red'>awaited</B>,
951     * using {@link Promise#await()}, <I>and the returned result of this Browser Function may
952      * may be retrieved.</I>
953     *
954     * <BR /><BR />This Browser Function <B STYLE='color: red'>returns</B>
955     * <BR /><BR /><UL CLASS=JDUL>
956     * <LI><CODE>{@link SystemInfo.ProcessInfo}[] (<B>processInfo</B></CODE>)
957     *     <BR />An array of process info blocks.
958     * </LI>
959     * </UL> */
960    public static Script<String, JsonObject, SystemInfo.ProcessInfo[]> getProcessInfo()
961    {
962        final int          webSocketID = 41002000 + counter++;
963        final boolean[]    optionals   = new boolean[0];
964        
965        // Convert Method Parameters into JSON.  Build the JSON Request-Object (as a String)
966        String requestJSON = WriteJSON.get(
967            parameterTypes.get("getProcessInfo"),
968            parameterNames.get("getProcessInfo"),
969            optionals, webSocketID,
970            "SystemInfo.getProcessInfo"
971        );
972        
973        // 'JSON Binding' ... Converts Browser Response-JSON to 'SystemInfo.ProcessInfo[]'
974        Function<JsonObject, SystemInfo.ProcessInfo[]> responseProcessor = (JsonObject jo) ->
975            (jo.getJsonArray("processInfo") == null)
976                ? null
977                : RJArrIntoStream.objArr(jo.getJsonArray("processInfo"), null, 0, SystemInfo.ProcessInfo.class).toArray(SystemInfo.ProcessInfo[]::new);
978        
979        return new Script<>(webSocketID, requestJSON, responseProcessor);
980    }
981    
982}