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