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}<String, {@link JsonObject}, 597 * {@link Ret0}></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}<String, {@link JsonObject}, 628 * {@link Ret0}></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}