2.71.77 (06/05/2026) SUMMARY BY AREA --------------- Build / tooling - Android Gradle Plugin 9.1.1 -> 9.2.1 (working tree; 9.2.0 in b00). - Gradle wrapper 9.3.1 -> 9.4.1. LegalDoc UI A coordinated reshape of the LegalDoc native container, driven by signage-fleet feedback: - Icon-only root tiles - new thumbnailType field on TVLegalDocNode, parsed from the thumbnailType BDD column (default 1). When thumbnailType == 0 on root tiles, the icon fills the tile (MATCH_PARENT, FIT_CENTER); the title, metadata and panel background are hidden and padding is zeroed. - Vector nav icons - Home/Back buttons no longer render the words "Home"/"Back"; instead createHomeIcon() / createBackIcon() draw scalable Path-based glyphs onto an ImageView. - Configurable root tile size - new LEGAL_TILE_SIZE script var (format "WxH", parsed from the legal config's param1). When set, root spanCount is computed from available width / tile width, tiles use the fixed size, and the grid is vertically centered when shorter than the RecyclerView. - Centered partial last row - effective spanCount is doubled in the GridLayoutManager; real items take span 2 and null placeholder cells take span 1, allowing the trailing row to be centered even with an odd number of empty cells. Adapter renders null items as INVISIBLE placeholders sized to match the row height. - Optional search bar (working tree) - new "// SEARCHBAR = false;" script-comment parameter on the container script. When false, the search field and breadcrumb are not added to the nav bar; if neither Home nor Back is applicable in that mode, the nav bar collapses entirely and the grid reclaims the height. Web / Gecko - TVGeckoView.loadUrl() - authorizeHost() is now called with the full URL instead of just the host (so URL-derived rules normalize correctly), and the resolved authorized host list is logged. XML / data layer - TVXMLReader.cacheUnitChildren() - multi-valued fields are now preserved instead of dropped. Repeated child tags are joined as "v1?v2,v3,..." (the same ?/, convention used by getNodesIgnoreCase), which is what ELDesign relies on to detect a multi-valued field and expand a single record into multiple rows. Previously the cache only kept the first occurrence. - TVXMLReader - extensive Javadoc added to all public constructors, accessors, mutators and helpers (no behavior change). ELDesign / ELDynamicPlayList / ELMasterDB - ELDesign.calcPageConditions() (working tree) - page-condition values containing '#' are now run through TVStringParser.parseBDDFilterVar(), so dynamic placeholders inside container page conditions resolve at compare time. - ELDynamicPlayList - comprehensive Javadoc on PlaylistParams, the constructor, the lifecycle hooks (generatePlayList, validatePlayList, addFileToPlayList, prepareView) and helpers. No behavior change. - ELMasterDB - Javadoc on Field / ObjectParams inner classes, including the ORIGIN_MDB / ORIGIN_BDD semantics. No behavior change. Code hygiene - Generic-type cleanups in TVUtils (Class -> Class for SystemProperties, closeAndroidPDialog, getFirmwareVersion). - @SuppressWarnings("unchecked") annotations on the unavoidable raw casts in DesignPDFView.PageBitmaps and ELDesign keyframe-list reflection. 2.71.76 (28/04/2026) -------------------------------------------------------------------------------- 1. SSL/TLS CERTIFICATE PINNING -------------------------------------------------------------------------------- New pinning infrastructure replacing the old SslInitializer. * PinsController (ssl/PinsController.kt) Central orchestrator for pin management. * DynamicPinningInterceptor (ssl/DynamicPinningInterceptor.kt) OkHttp interceptor for runtime pin enforcement. * TofuPinLearner (ssl/TofuPinLearner.kt) Trust-On-First-Use pin learning for new servers. * PinsStore (ssl/PinsStore.kt) Persistent storage for learned pins. * LearnedPins (ssl/LearnedPins.kt) Data model for learned pin entries. * PinsConfigLoader Updated for the new architecture. * Removed SslInitializer.kt * ApiClient (ApiClient.kt) Major refactoring to integrate new SSL pinning (195 lines changed). * Updated bundled pin JSON files for all servers (cloud5, ikea, prod5/6/7/8/12, visiosoft). * Documentation: docs/TODO_PINS_MANIFEST.md. -------------------------------------------------------------------------------- 2. TVSST BROADCAST RECEIVER API -------------------------------------------------------------------------------- New Kotlin package com.wildcopper.tvslide4droid.tvsst -- broadcast-based API for the TVSST companion app (18 new files, 667 lines). * TvsstReceiver Manifest-registered receiver (*.action.TVSST), responds even when TVSlide hasn't started. * TvsstDispatcher / TvsstCommandRegistry Command routing and registration with mutex for write operations. * TvsstRequest / TvsstResponse / TvsstProtocol Structured request/response model. * Commands: version, listCommands, ping, getIni, setIni (atomic write with verify + rollback), configure, getStorageInfo. * Responses via setResultData() so `adb shell am broadcast` receives JSON on stdout. -------------------------------------------------------------------------------- 3. REMOTE DEVICE SETUP VIA BROADCAST -------------------------------------------------------------------------------- New setup/ package for headless fleet provisioning (3 new files, 116 lines). * SetupBroadcastReceiver (*.action.CONFIGURE) Configures device name + license via ADB broadcast without user interaction. * AppSetupRepository Reads/writes INI configuration. * DeviceConfigurator Orchestrates the setup flow. -------------------------------------------------------------------------------- 4. LEGALDOC NATIVE CONTAINER -------------------------------------------------------------------------------- New native rendering for LegalDoc content -- container mode 100 (4 new files, 1,494 lines). * TVLegalDocView (720 lines) Custom view rendering legal document tree. * TVLegalDocTree (337 lines) Tree structure parser/builder for document hierarchy. * TVLegalDocNode (76 lines) Tree node data model. * TVLegalDocAdapter (361 lines) Adapter bridging design data to the document view. * classes.jar added (1.5MB) for LegalDoc support. -------------------------------------------------------------------------------- 5. GECKOVIEW CONSOLE LOGGER WEBEXTENSION -------------------------------------------------------------------------------- Built-in WebExtension (assets/console-logger/) forwarding web console.* output to TVLog (2 new files). * Content script (content.js) intercepts console.log/warn/error/info/debug. * Uses browser.runtime.sendNativeMessage() with nativeMessagingFromContent permission. * manifest.json with nativeMessaging, nativeMessagingFromContent, geckoViewAddons permissions. -------------------------------------------------------------------------------- 6. TEXT RENDERING IMPROVEMENTS -------------------------------------------------------------------------------- Significant work on matching Windows DirectWrite rendering on Android. * FakeBoldSpan (new, 30 lines) FILL_AND_STROKE with stroke width textSize * 1/45 -- workaround for Android's StyleSpan(BOLD) failing silently with custom typefaces. * CustomTypefaceSpan Reset paint to FILL style to cancel leaked FakeBoldSpan stroke. * DesignTextView Added Paint.HINTING_OFF + SUBPIXEL_TEXT_FLAG + LINEAR_TEXT_FLAG to reduce glyph thickness. * TVString (66 lines changed) applyFontVariant() now loads actual bold/italic .ttf files via TVDesignFont.getFontfile(style), with FakeBoldSpan fallback. * TVDesignFont New getFontfile(style) method for bold/italic/bold-italic font file lookup. * FontManager (254 lines changed) Major refactoring of font scanning with TTFAnalyzer and directory fingerprint caching (font_cache.txt). -------------------------------------------------------------------------------- 7. GECKOVIEW ENHANCEMENTS -------------------------------------------------------------------------------- * TVGeckoUtils (135 lines added): - Dynamic config rewriting when GeckoConfig.yaml content changes. - print.print_resolution: 300 for high-quality PDF printing. - Debug overlay mode with gfx.webrender.debug.profiler. - Added network.auth prefs (non-web-content HTTP auth allow, subresource auth). - Added Service Worker prefs (dom.serviceWorkers.enabled, dom.caches.enabled, dom.push.enabled). - Console output and debug logging enabled on the runtime. - Autocomplete storage delegate now active -- provides encrypted HTTP login/password from TVPrefs via TVCrypto.decrypt() for automatic web authentication (was previously commented out with hardcoded credentials). - WebExtension lifecycle: ensureBuiltIn() for console-logger, retroactive session registration via onConsoleLoggerReady() / registerConsoleDelegate(). * TVGeckoView: - isAuthorized() fix: strips query parameters (?...) from the host before matching against authorizedHosts -- unauthorized hosts could be incorrectly accepted if an authorized host appeared in their query string (e.g. facebook.com/?caller=thing.com matched when only thing.com was whitelisted). - Console delegate registration on new sessions via TVGeckoUtils.registerConsoleDelegate(session). * TVGeckoViewPrompt: fix. --- 7.1 Web Login Credential Persistence (2.71.76b10-b12) --- Round-trip persistence of form-login credentials across app restarts and reboots. Previously the autocomplete delegate only provided the single TVPrefs.httpLogin/httpPassword credential for serverRoot; there was no capture-on-save for arbitrary sites, and session cookies (without Max-Age) died with the process. * TVLoginStore.java (new, ~200 lines) Encrypted, deduped, file-backed store for GeckoView Autocomplete.LoginEntry records at TVSlideActivity.prefsFilePath + "LoginEntries.xml". - Public API: save(LoginEntry), loadAll(), loadForOrigin(domain). - Dedup on the functional identity (origin, formActionOrigin ?? httpRealm, username) -- same triple Firefox uses internally in logins.json. Matching triple -> password updated in place with guid preserved. New triple -> appended with a freshly-minted UUID.randomUUID().toString() if Gecko sends guid=null. - All value fields (origin, formActionOrigin, httpRealm, username, password) encrypted via TVCrypto.encrypt/decrypt. Only the plaintext UUID guid lives in the XML as an attribute. - All I/O guarded by a static monitor (loginsLock); returns empty and logs a warning if TVSlideActivity.prefsFilePath isn't set yet. * TVGeckoUtils autocomplete delegate: - onLoginSave now persists via TVLoginStore.save(loginEntry) (was a no-op super.onLoginSave(...) stub). - onLoginFetch consults TVLoginStore.loadForOrigin(domain) first and returns any matches; falls back to the existing TVPrefs single-credential path (now guarded by serverRoot.toLowerCase().contains(domain.toLowerCase())). * login-autosubmit WebExtension (new assets/login-autosubmit/ directory, 2 files) Submits login forms automatically after Gecko autofill so the user doesn't have to click "Log in" on every cold start. - manifest.json: matches , run_at: "document_idle", all_frames: false. Same permission set as console-logger (nativeMessaging, nativeMessagingFromContent, geckoViewAddons). - content.js: locates the login form via input[type="password"] -> closest('form') -> sibling username input; MutationObserver on value attribute changes + 100 ms poll (5 s ceiling); when both fields are non-empty, dispatches input/change events (for React/Vue/Angular state), clicks button[type="submit"] / input[type="submit"] or falls back to form.submit(). A keydown listener sets userInteracted=true and disables auto-submit while the user is typing -- protects first-time logins and credential rotations. - Emits submitted/timeout diagnostic events via browser.runtime.sendNativeMessage("loginAutoSubmit", ...). Native-side delegate not wired in this release; events are /dev/null'd silently. - Registered via a second ensureBuiltIn("resource://android/assets/login-autosubmit/", ...) call alongside console-logger. * TVGeckoView: - loadUrl(String) / loadUrl(String, boolean clearData) signature split: new loadUrl(String pUrl, boolean clearData, boolean clearHistory) decouples "clear cookies/storage" from "clear navigation history". History clearing now gated on its own clearHistory parameter; the single-arg shim delegates to (pUrl, true, true) to preserve existing behavior. - thisView field retyped from generic View to TVGeckoView so session-state callbacks can pass a typed reference through. * TVGeckoScript: - onSessionStateChange(...) signature gained a TVGeckoView view parameter. - Added alreadyInState reentrancy guard -- prevents recursion when JS run inside scriptEngine.execute(...) triggers another state-change callback while the current handler is still in flight. -------------------------------------------------------------------------------- 8. ELDESIGN REFACTORING -------------------------------------------------------------------------------- * ~530 lines of insertions/changes across ELDesign.java (b09-b12). * Continued rendering refactor from 2.71.75. * Container page rebuilding improvements. * Widget playlist download: added logging for download and validation steps. * loadDesign() fix: if a .tmp design file doesn't exist (already loaded into a dynamic design's playlist box), falls back to the non-tmp filename via TVUtils.removeTmp(). * Code formatting cleanup in rebuildContainerPages() (timing/profiling lines split for readability). * BDD field-index caching bug fix (XMLDesignBDD inside masterDB.update(...), ELDesign.java:~2725 in 2.71.76b10-b12) - The cached indices fieldIndex_validate / _id / _tvtcond / _level are consumed downstream (ELDesign.java:2050, 2056, 2086, 2111, 2144) as lookups into the REMAPPED item.fields[...] array. The previous cacheFieldIndices() helper stored the RAW position f from dE.fieldInfo[f], which did not match the remapped fieldOrder layout produced by the preceding parse loop. - Symptom: whenever the XML reorders fields relative to their declaration, isValidated(), shouldBeDisplayedNow(), and the id / level readers looked up the wrong column -- records were accepted/rejected or ordered against the wrong field values. - Fix: cacheFieldIndices() removed entirely; the caching is now inlined into the existing XML field-parse loop and stores fIndex = TVUtils.getIndexFromArrayList(fieldOrder, i) rather than the raw loop index. Single pass, always consistent with the remap. * Anim URL `|`-suffix parsing disabled (2.71.76b09, ANIM_TYPE_HTML branches around ELDesign.java:16467 + :16493) - Both the WebView path and the TVGeckoView path previously split animation URLs at the first `|`, treated everything before as the URL and everything after as an option string, then passed only the prefix to loadUrl(). - On the WebView path, a restricted=1 token in that suffix also toggled webViewClient.setRestricted(true). - Both blocks are now commented out -- URLs are passed through verbatim to loadUrl(), and the restricted=1 flag no longer has any effect. Designs that embed `|restricted=1` (or any `|...` tail) in anim URLs will behave differently. - Also added a TVLog.i("DEBUG", objg.nomAnim + "\n" + finalURL) trace on the WebView branch for anim URL diagnostics. -------------------------------------------------------------------------------- 9. TVUTILS EXPANSION -------------------------------------------------------------------------------- Major expansion of TVUtils (377 lines changed): * New utility functions for storage, ADB, and display management. * TVDebugView expanded (51 lines) with additional debug information. * TVCalendar updates (43 lines) for off-day / bank holiday handling. * TVOffDays adjustments. -------------------------------------------------------------------------------- 10. ELMULTIZONE -- BACKGROUND MULTIZONE (isMZB) -------------------------------------------------------------------------------- * Re-enabled the isMZB playlist swap in init(): when a multizone has a background (isMZB), playLists[0] and playLists[1] are swapped so the background playlist renders behind the foreground. * Added logging of playlist zone positions during init (x, y, w x h). -------------------------------------------------------------------------------- 11. TVSLIDEACTIVITY UPDATES -------------------------------------------------------------------------------- 148 lines changed across the main activity: * Activity lifecycle improvements. * Integration with new subsystems (TVSST, setup, SSL). -------------------------------------------------------------------------------- 12. PLAYLIST CHANGES -------------------------------------------------------------------------------- * TVPlayList (29 lines changed) Adjustments to playback flow. * ELDynamicPlayList (16 lines) Dynamic playlist refinements. * TVPlayListManager Fixed shouldCheckContent() conditional -- the content verification log now runs even when files are equal (was only logging when content differed due to short-circuit &&). * TVPrefs Minor config change. * TVPlayList playNextElement cooperative-bailout race fix (2.71.76b10-b12, TVPlayList.java:1866 and 2478) - Observed crash: IndexOutOfBoundsException: Index: 4, Size: 0 at TVPlayList.java:2478 when running with R8 obfuscation-only release builds. Root cause: stopPage(isSelf=false) busy-waits for inPlayNext to clear with a 10-second escape hatch (TVPlayList.java:823-826) and returns anyway on timeout; callers then proceeded to clearElements() while the in-flight playNextElement still held a stale startIndex from before the clear. - Fix: added if ((!playing) || (TVUtils.isQuitting)) { inPlayNext = false; return; } at the top of each do-while iteration in playNextElement -- both the first loop (line ~1866, before elementList.get(index)) and the second loop (line ~2478, before the crashing elementList.get(ind)). The second checkpoint also includes a `ind >= elementList.size()` bounds guard as belt-and-suspenders. - playing and inPlayNext are already volatile (TVPlayList.java:59), so the writes from stopPage on one thread are observed on the next checkpoint read in the Timer thread; no synchronization or field changes needed. Stop is now cooperative: the in-flight playNextElement notices playing = false and bails cleanly, stopPage's busy-wait exits quickly, and callers can safely proceed to clearElements()/swap without crashing even if the 10-second timeout fires. -------------------------------------------------------------------------------- 13. PROGUARD RULES UPDATE -------------------------------------------------------------------------------- * Major update to app/proguard-rules.txt (431 lines changed). * Keep rules for all new classes (TVSST, setup, SSL, LegalDoc). -------------------------------------------------------------------------------- 14. GPU OPTIMIZATION (TVCPUUtils) -------------------------------------------------------------------------------- * New optimizeGpu() method: scans /sys/class/devfreq/ for GPU entries (mali, valhall, panfrost, bifrost, midgard keywords), sets governor to performance mode. * Called from both root and non-root CPU optimization paths. * TVSlideActivity and TVUtils adjustments to integrate GPU optimization. -------------------------------------------------------------------------------- 15. BUILD & INFRASTRUCTURE -------------------------------------------------------------------------------- * build.gradle: plugin version update. * app/build.gradle (2.71.76b09): - BuildConfig.TIMESTAMP: wrapped System.currentTimeMillis() in a BuildTimestamp ValueSource so the build-time constant is compatible with the Gradle configuration cache. - Minification trial reverted in b09: release minifyEnabled was briefly flipped to true (obfuscation-only, shrinkResources false) and reverted in the same build cycle. The timing shift surfaced a latent race in TVPlayList.playNextElement() -> IndexOutOfBoundsException at TVPlayList.java:2478 (elementList.get(startIndex) after clearElements() ran on another thread). Shipping b09 with minification disabled; app/proguard-rules.txt obfuscation-only keep rules remain in place for a future retry. - Race now addressed in b10-b12 via cooperative playing checkpoints in playNextElement (see Section 12). Re-enabling release minification is lower-risk now but still warrants extended field testing before being trialed again. * CLAUDE.md: extensive documentation additions (232 lines). * STORAGE_MIGRATION.md + .html: scoped-storage migration guide. -------------------------------------------------------------------------------- 16. OTHER CHANGES -------------------------------------------------------------------------------- * AdbClient: improvements (85 lines changed). * ControlVestel: Vestel TV control updates (37 lines). * TVXMLReader: XML parsing fixes (47 lines). * TVLog: logging additions (5 lines). * TVService: minor additions (5 lines). * DesignDecoder: 2 lines added. * Render4KTestActivity: 1 line fix. 2.71.75 (18/03/2026) 1. FTP Security (TVUtils.java) - FTP credentials encryption: ftpPrintHost, ftpPrintLogin, ftpPrintPassword, ftpPrintDirectory are now encrypted/decrypted via TVCrypto.encrypt()/TVCrypto.decrypt() - Removed hardcoded credentials: the fallback has been removed from all 3 functions (printStreamFTP, printFileFtp, printScreenFtp). If parameters are empty, functions now return immediately - TLS support with fallback: all 3 FTP functions now attempt FTPSClient("TLS") first, then fall back to plain FTPClient if the server doesn't support SSL. Added PBSZ(0) and PROT("P") commands for encrypted data channel - New Android command setftp: allows configuring FTP parameters from the command line (setftp host,dir,login,pass), with automatic encryption. Without arguments, clears all parameters 2. PDF to Image Conversion (TVUtils.java) - New pdfFileToImages() function: converts a PDF file to JPEG images (x4 scale) using PdfiumCore. Returns an array of paths to the generated images 3. GeckoView Print to FTP (TVGeckoView.java) - New sendPagePDFtoFTP() function: saves the current GeckoView page as PDF via session.saveAsPdf(), converts it to JPEG images via pdfFileToImages(), uploads each page via FTP, then cleans up temporary files 4. 4K Display via VirtualDisplay (TVSlideActivity, TV4KDisplay, Render4KTestActivity) - Complete 4K rendering overhaul: replaced the old system (which divided coordinates by 2 in TVSurfacePlayer) with a VirtualDisplay + Presentation approach - TV4KDisplay (new): manages creation of a VirtualDisplay with MediaProjection, a SurfaceView for rendering, and a Presentation containing the baseLayout - Render4KTestActivity (new): test activity for 4K rendering (declared in Manifest) - TVSlideActivity: onStart() is now split with continueAfterBaseLayout() as a callback. In 4K mode, the Activity's baseLayout is hidden and replaced by the Presentation's layout - TVSurfacePlayer: removed all coordinate division-by-2 logic (setLayoutParams, setX, setY) which is no longer needed - TVUtils.renderContext: new static field allowing the rendering context to switch to the VirtualDisplay's context 5. ELMultiZone Overhaul - ELMultiZone is now isController = true (changed from false) - New createView() method: creates a TVContainerView that holds all zone layouts - New overrides: startView() (starts all zones), stopView(), removeView() (calls stopPlayBack() before super), loopView(), startMedia() - stopPlayBack() rewritten: uses a CountDownLatch to synchronize view removal (UI thread) with playlist stopping (background thread). Now loops from zones-1 down to 0 inclusive (fixed bug that skipped zone 0) - Improved logging in isFirstPageReady() to trace which zone is ready or not 6. TVPlayList Changes - Thread-safety: several fields made volatile (actualElementView, actualElement, playing, inPlayNext, active, stopNextLoop, syncGroupName, socketUser) - New setBaseLayout() setter and setMZEndOwner() made public - Slave sync: before calling playNextElement in sync slave mode, now waits for inPlayNext to finish (with 10s timeout) - Commented out multizone handling in playNextElement(): multizone sub-playlist startup is now managed directly by ELMultiZone.startView() instead of being scattered in TVPlayList - Commented out multizone stopPlayBack in removeOldView() and removeAllViews() — responsibility transferred to ELMultiZone.removeView() - Fixed isController order in findController(): now checks multizone sub-playlists before testing isController - Added playing condition in the isFirstPageReady wait loop 7. AdbClient Overhaul - Fixed RSA signing: switched from SHA1withRSA to NONEwithRSA with manual SHA-1 DigestInfo construction (the old code was double-hashing, incompatible with adbd) - Android ADB public key format: replaced OpenSSH format (ssh-rsa) with Android's native ADB binary struct format (with n0inv, little-endian uint32 modulus, R^2 mod n). The old format was rejected by devices - Removed PublicKey reconstruction: only the private key is needed for signing; the public key is read directly from the .pub file - Migrated java.util.Base64 to android.util.Base64 - Automatic old format detection: if the existing .pub file isn't in ADB struct format, the key pair is regenerated 8. Automatic Wi-Fi Re-enabling (WifiWatchdogReceiver/Service) - handleWifiDisabled() (new): when Android disables Wi-Fi (rare event, ~every 3 weeks), checks for Ethernet connection and saved SSID. If no Ethernet and known SSID exists, automatically re-enables Wi-Fi - isEthernetConnected() (new in Service): checks Ethernet state via ConnectivityManager - Same logic duplicated in WifiWatchdogService during periodic tick 9. Bluetooth (BluetoothStatus.java — new) - Full utility class to retrieve Bluetooth state and list of connected devices (HFP and A2DP profiles) - Returns JSON: {"bt":1,"devices":[{"cn":"JBL Flip 6","cp":"A2DP"}]} - Handles BLUETOOTH_CONNECT permission on Android 12+ - Uses BluetoothProfile.ServiceListener with CountDownLatch and 2s timeout - Integrated into sendState3(): Bluetooth status is now sent to the TVTools server in monitoring - BLUETOOTH_CONNECT permission added to the auto-grant list 10. GeckoView Config (TVGeckoUtils.java) - Dynamic Gecko config: GeckoConfig.yaml is now rewritten if its content changes (instead of only being written if it doesn't exist) - Added print.print_resolution: 300 for high-quality PDF printing - Debug overlay mode: if TVPrefs.webDebugOverlay is active, enables gfx.webrender.debug.profiler 11. ELDesign (major refactoring) - WebAccess widget support: reads widget JSON (var9) to extract background color (type solid) and applies it as forcedBGColor on design objects - The rest of the diff is a massive rendering refactor (~2275 lines) 12. Miscellaneous - FpsTracker (new): FPS tracker for performance monitoring - ADB command self: eadb self:5555 is now an alias for 127.0.0.1 - executeADB() / adbReboot() (TVUtils): new functions to execute local ADB commands. adbReboot is used as a fallback in the reboot chain - APK installation via ADB: if the device is not rooted, attempts installation via ADB (pm install) - Storage display: the storage command now shows total space in addition to free space - EVENTLOOP_OPTIMIZATION_ANALYSIS.md: analysis document for event loop optimization 2.71.74 (05/01/2026) - Fixed a crash with whitelists and scripts for GeckoView - New Android command : "webwhitelist" or "wwl" to set the whitelist for accepted web sites on the device. 2.71.73 (27/01/2026) - Fixed crash due to unsupported function on older Android devices. - Implemented dynamic designs with multiple pages created in the WebAccess. - Added .INI parameter "MaxVideos", which defines the maximum number of videos that can be played at the same time by a device. Defaults to 4. - Video objects now also support animations since the parameter is available in WebAccess designs. - Added a delay before starting the application, 60s on most devices, 90s on "marconi" style LED bars. - Added TLS support to the FTP client. 2.71.72 (15/01/2026) - Fixed multizones in schedule levels that were stopping after the first loop. - Added 13BDL4150 Philips devices to supported EINK displays. 2.71.71 (12/01/2026) - Implemented advanced WIFI Watchdog to try to counter random disconnections (Max). - Fixed rare crash for PDF files where the info from the .xml is wrong for page numbers. - Fixed a crash in justified text in design textboxes. - Added dynamic data to elements in prevision for WebAccess designs implementation. - Added public boolean isFirstPageReady() to elements which should return true if the first page of the element is ready to be displayed. - ELMultiZone is now considered a valid first element of a playlist. - Fixed self looping when a web page is the only elements of a playlist and would block the update of the MasterDB by being displayed forever. - Implemented multi media playlist entries which are displayed in a multizone. - Added a logcat warning when a MasterDB doesn't have an ID. - Reworked multizones so that there's no black screen between two multizones or a multizone and another element. - Some changes to GeckoView scripts to get rid of illegal characters in the sessionstate. - Changed bank holidays so that when the end time is before the start time, it's moved to the next day. - Added script function "getLanguage()" which returns the actual language of the application. - Improved JSON management in TVXMLReader. 2.71.70 (06/11/2025) - Application restart now uses a broadcast receiver for the alarm manager signal. - Added special management for Ikea sites, schedule levels and playlists for elements that must only play on specific sites. The sites will be updated from the server after a publication of the schedule level or after a device restart. - Implemented PowerBI pages display in GeckoView. - Implemented scripts for GeckoView to react to onSessionStateChange events, to be able to automatically log into web sites for instance. - Implemented the option to also download playlist elements that aren't marked as displayed in the WebAcccess. - Fixed the display of designs in overlay over another element so it works even if the conditions contain other elements than the "ov:" tag. - Some improvements to GeckoView's management of invalid certificates. - Scripts : added TVTools.adbConnect(host, port), TVTools.adbShell(command) and TVTools.adbClose() to be able to send ADB commands with scripts. - SMS provider 1 is now SMS through the TVTools server, OVH is now provider 4. - The "resetposition" Android command now also resets Z axis rotations and offsets, screenOrientation,rotateScreen and videoRotateTexture. - "listplaylists" will no longer crash if there's a design with an illegal .xml file. Also added info about schedule level white and black lists. - If a device loses connection with the TVTools server, a small semi transparent icon will be displayed on the bottom right of the screen. - Now displaying the screen resolution in addition to the IP address in the "info" column. If there's a virtual resolution different from the native resolution, it's also displayed. - Weather conditions also now translated to Spanish. - Added a fix to avoid the launcher of the Marconi type LED displays to interfere with the TVLauncher and make TVSlide freeze and crash. 2.71.69 (01/10/2025) Kotlin : - DialogRegistry : now running addObserver and removeObserver on the UI thread to avoid crashes when called from a script. - Fixed License file reading. Java : - Class AdbClient: Added an ADB client to the application. The "eadb" android command allows to execute shell commands on a device on the same network if the client has been approved on the device. - Fixed the schedule level whitelist test. - Until we have alpha channel support in the WebAccess, a design with a background color of 0xFF000000 coming from a database will be converted to 0x00000000 (transparent background). - Fixed root of the XML file selection for special type 17 playlists. - Rewrote the code of off days (bank holidays). Now it's working. - Duplicating the "DocViewer" playlist into a "WebDocViewer" automatically. - Scripts : modalPlayList methods now return a boolean to report of the opening of the playlist was successful or not. - Screenshots/monitoring : Fixed the retrieval of the surface bitmap for GeckoView (special case). 2.71.68 (02/09/2025) - Now correctly getting all fonts for text objects added with the WebAccess. - End animations no longer use the offset used for start animations, since they are immediate. - Improved buffering time for video streams played with LibVLC. - Started breaking down big classes into smaller specialized ones (Max). 2.71.67 (07/08/2025) - Using a Throwable instead of an Exception when to get an instance of the IIYAMA API to avoid a crash on more recent devices. - DesignPDFView : added reflection code to free pages after each rendering to avoid PDFiumCore to saturate bitmap memory. - DesignPlaylistView : changed names of the view and the playlist to use an unique ID. - Added two spelling "clignotant" and "clignottant" for the constant blinking animation to fix different spelling in the designer and the webaccess. - Design which contain only playlist boxes now check the playlists to see if one of them isn't empty, or they will not play at all. - Secured code to recover the NTP server with try/catch to avoid crashes on some devices. - Scripts: New Function "TVTools.getTemperatures" to return all hardware temperatures so they can be displayed in a design. Also added the "#CPUTEMP" tag for text fields. - Added security to moveBaseLayout for when the application is closing and quitting. - Added special root based application scheduled restart code for the "G10X5" new players since alarms don't work on them. - Removed invisibility code for videos before they start playing to avoid black screens between two videos or a video and other elements. - Added code to unlock true portrait mode on G10X5. - Requesting various authorizations automatically at application start on rooted devices. - Added code to get the right MAC address from system files on GX10X5 devices. - Added design playlists to the "listplaylists" Android command. - Removed "mMediaPlayer.setScale" from the VLC player (TVVLCPlayer) as it seems to cause crashes on some devices. 2.71.66 (18/06/2025) - Major API modernization with support for new REST API (Maxence): New .INI parameter "useNewApi" in [System] section to enable the new API system. Complete bridge system (ApiBridge) for transparent migration from SOAP to REST endpoints. Maintains full backward compatibility with existing TVToolsResponse format. - New device registration system replacing the configuration dialog: Configuration is now a full Activity instead of a dialog, providing better adaptation to different resolutions. Two-step registration process: configuration entry followed by registration code generation. Support for both Android ID and Serial Number as device identifiers. Automatic device model detection (e.g., PJ-X28I uses Serial Number by default). Private server configuration support with automatic URL formatting. Real-time validation monitoring with automatic retry logic. - New reactive programming framework: Custom RxFlow implementation built on Kotlin coroutines for asynchronous operations. Disposable pattern for proper resource management. Thread management with dedicated dispatchers (IO, MAIN, COMPUTATION). - Advanced logging system: Multi-level logging (0-5) with LogLevel support. Multiple logger implementations: LogcatLogger, TvLogger, UILogger. Configurable formatters: PrefixFormatter, ThreadFormatter, TimestampFormatter. Composite logger support for simultaneous output to multiple destinations. - New preference management system: Centralized preference keys management. Type-safe preference access with default values. Seamless integration with existing .INI configuration. - API features implemented: Device management: findDevice, findAndroid, getIPTVConfig. State management: sendState1, sendState2, sendState3. Session management: StartAdminSession, StopSession1. Command execution: sendCommand1, sendCommandPPCDebut1. Generic methods: genericMethod, genericMethod1. License validation and registration code generation. - Network enhancements: Modern HTTP client using Ktor with OkHttp engine. Comprehensive error handling with retry mechanisms. Support for both cloud and private server endpoints. - Architecture improvements: Clean architecture with clear separation between data, domain, and core layers. Extensive use of Kotlin features: data classes, coroutines, extension functions. Mapper pattern for converting between API DTOs and legacy formats. Custom serializers for handling null values (NullToEmptyStringSerializer, NullToIntSerializer). 2.71.65 (12/06/2025) - New config dialog when you first run the application on a new device, adapts better to different resolutions (Maxence). - Support for sound volume for medias directly in the media section of the WebAccess. - Limited logging in designs to logLevel >= 2 to speed up designs when needed. - Background color of playlists inside designs is now transparent by default. - Added a .INI entry "InteractiveVideos" to make videos interactive. Turned off by default (0), set to 1 to make videos interactive. - Scripts: New command "setObjectVolume" to set the volume of a media object. If it's a playlist, sets the volume of the whole playlist. Support for "OVH" SMS provider. New provider list for TVTools.sendSMS : 0 = octopush, 1 = OVH, 2 = Mobile API, 3 = SMS Alert. New parameters for text boxes : "FIRST_WORD_CAPS" and "ALL_CAPS" to respectively automatically put the first letter or the whole content in caps. - Support for interactive playlists in designs : New box script parameter "INTERACTIVE = true" for playlist boxes. Script commands "TVTools.playNextContainerPage" and "TVTools.playPreviousContainerPage" now also support playlist boxes. Script commands "TVTools.getObjectPages" and "TVTools.getObjectActualPage" now also support playlist boxes. - URL View : Added script callback for page end - onWebPageFinished(String url). - If the internal storage is inaccessible on some devices, the application will now use the application storage. 2.71.64 (05/05/2025) - Intermediate release with some of the changes of the 2.71.65. 2.71.63 (08/03/2025) - Secured modal playlists so that they can't be opened twice or crash if the user presses a button very quickly. - Added .INI parameter "LogLevel", which takes values from 0 to 5, to set the amount of logcat output from the player (limited to ELDesign for now). A value of 5 (default) means full output, a value of 0 no output at all. Set to a value of 1 (only Errors and Warnings) in order to speed up designs. 2.71.62 (03/03/2025) - No longer setting playlist volume if the corresponding flag is not set. - Fixed a rare crash that could happen when the filename of a design object is empty. 2.71.61 (27/03/2025) - Percentage playlists now also take element conditions into account. - Fixed more filename issues for sound files when a design is edited locally on the server. - No longer trying to download images with empty filenames. - Planning : colors for categories are now in a recordset editable with the WebAccess. - Playlist global volume is now taken into account, and applied respecting the playlist elements individual volumes. - Geckoview : now auto connecting to a web page placed on the secure TVTools server. - Reverted network reset to old code which doesn't try to also reset the WIFI driver. 2.71.60 (14/03/2025) - Auto container mode 2 implemented for IKEA array containers which adjust in height depending if there are two or three rows. - Changed "Camille" to "Pierrick" for the Tecsoft Planning display. - Implemented global volume for playlists. Elements with independent volumes will be adjusted according to the global volume (element volume * global volume). - .INI version updated to 2.25: New .INI parameter "ResetNetwork" in minutes, which defines the period of time after which a WIFI connexion will be restarted. A value of 0 means no reset. - Scripts: SendSMS : Implementation of provider 2 for "SMSMobileAPI". - Fixed a crash on older Philips devices during the check for power saving and doze. - Daytime saving tests are now independent of the device system time. 2.71.59 (07/03/2025) - Camera use permission on API level 23 or higher will now only be asked if the .INI System/UseCamera parameter is set to 1. - .INI version updated to 2.24 for the new "UseCamera" parameter. - If the connexion with the server is lost, the WIFI connexion reset now includes a complete restart of the WIFI driver. 2.71.58 (04/03/2025) - Implementation of percentage based sub playlists. Waiting for finalization in the WebAccess UI to implement the final values. - Fixed sound paths in designs if the design was edited on the server rather than remotely. - Scripts: new "numbers" type for input fields that should only accept numbers. - Fixed a crash on older devices (Philips) that could happen when clearing an element's display list. - Camera permission will now be asked on installation if necessary (for motion tracking). - The watchdog log will now notify if a device enters power saving mode or doze mode. 2.71.57 (07/02/2025) - Added requests for the MANAGE OVERLAYS permission for devices with Android Q or newer, if the TVLauncher is not installed. - Added randomness to the WebService request delay so that all the devices of a server won't send their requests at the same time after a server reboot. 2.71.56 (06/02/2025) - MasterDB special type 17 : Now managing element whitelists and blacklists depending on which schedule level is playing. - Added permission "ACTION_MANAGE_OVERLAY_PERMISSION" for start on boot and restart on some devices with Android 10 or more recent. - GeckoView modified so it can directly open PDF files inside the browser window if the URL directly points on one. - Script functions : changeSoftKeyboardStatus(boolean status) show or hides the soft keyboard depending on if status is true or false. setMinReloadDelay(int delay) permits to change the minimum delay after which a recordset is reloaded by a new request. - Changed a rare issue when parsing a #VAR could get stuck because the #VAR format is not complete. - Fixes to port number in server : - Changed TVTools root directory detection so it's not based on "C:" but can be on any server disk. - Fixed sound file management so that the right file name is returned by script functions. - Added support for number only text entry fields in designs. The command to erase such a field via scripts is "0000000000"(10x0). - No longer selecting a container element automatically if there's a field in the main design that can be selected. - "BootMode" will now keep it's value in the .INI after a .INI version change. - Fixed autoscroll for containers so that it now displays all the elements. - If contact to the webservice is lost, and the player is also unable to reach Internet, after 2 minutes the network connection (WIFI or ETHERNET) will be restarted. - Now managing WebAccess designs playing in an overlay. 2.71.55 (07/01/2025) - Another fix for the ":" problem for servers with special ports. - Improved the reset of the connection on WIFI connection loss. 2.71.54 (19/12/2024) - Hotfix to .53 for the ":" problem which was making playlists in designs and other special filenames no longer work. 2.71.53 (19/12/2024) - Implementation of the diffusion of elements a single time at specific hours. - Implementation of automatic scrolling of web pages in GeckoView. - Implementation of custom multizones with a background. - Servers can now be on specific ports. - Correction of auto-scrolling containers which were only scrolling to the second last element. - New INI parameter "WebEngine/DensityOverride", which permits to override the default display density to adjust to "exotic" web pages. - New script function "TVTools.sendSMS(int provider, String phone_number, String sender, String purpose, String text)" to send a SMS through a third party provider. "provider" can be 0 or 1. 0 = Octopush, 1 = SMSAlert. 1 is the fastest. "phone_number" is the destination number. "sender" is the description of the sender (you). "purpose" serves only for Octopush and can be "alert" or "wholesale", "alert" being supposed to be faster and meant for fast single target messages. "text" is the text of the SMS. - If a WIFI connection fails (disconnected) and can't reconnect within 2 minutes, it will be stopped and restarted. Only works on rooted devices. - Fixed the function recovering the "base" of an URL in order to also take an eventual port number into account. Also changed the conversion of an URL to a unix file name to suppress ":" and replace it with "_". - Small fix of the "WakeOnLan" wake function, which could crash the software if provided with a bad MAC or IP format. - Booking files "timeZone" parameter is no longer used if the player and the server are in the same time zone. 2.71.52 (29/10/2024) - More fixes to transparency of added boxes in designs... - Updated to GeckoView 131.0.20241011205646. - New Android command "clearwebdata" to remove all stored cookies and other data for GeckoView. - Now sending fatal application crashes to the server with a stack trace. - New price format for text boxes. - Some more improvements to the cache system. 2.71.51 (03/10/2024) - TVCache : accessing an element less than 5000ms after it has been last accessed doesn't force the reload of the element. This can be changed in the .INI with "System/MinReloadDelay". - Cache for recordsets of a same design is now common to all recordsets of that design. - New number format for prices, formattedSubType=5. - TVTexturePlayer / ExoPlayer: fixed a very rare issue when the PosGrabber timer could be null. 2.71.50 (26/09/2024) - onInactivity callback now resets last activity status. - Support for the "always reload HTTP files" option for design images. - Iiyama control now also checks for "XBH" brand monitors. - Replaced JJ with Camille for the planning. May JJ rest in peace. - ELDynamicPlaylist : Fixed a potential crash in validateToPlayElements if the playlist is changed during the execution of the function. Fixed a potential endless loop in validateToPlayElements if the playlist doesn't contain any playable elements but is not empty. - Removed scrollbar on autoscroll containers. - A badly formatted URL in downloadFileSys will now stop the download function and return a "NO FILE" error. Additionally, files on the device will be set to the same "last modified" time than on the server. - Fixed mac address inquiry to not automatically get the "eth0" interface if that one isn't connected. 2.71.49 (22/08/2024) - Scripts: changeBDDField no longer automatically calls updateBDD. - Wayfinding : Now drawing the walls after the room masks. - TVTexturePlayer : Fixed crash when the position grabber's thread is restarted. 2.71.48 (08/08/2024) - Scripts: New function "void setBDDContentCheck(String recordsetName, boolean value)" to disable the content check for specific recordsets. "onFocus" callback now has the object's active key as parameter. - New text box parameter "ALL_CAPS" to enter text only in caps. - New command string for editable text boxes "#clear", to clear the whole entered text. - Now dispatching incoming key events to all zones of a multizone. - Exoplayer on a texture now tracks playback position. - Some optimizations to WayFinding. Now paths drawed in pure RED (FF0000) can not be exited even if they are the closest to the destination. - Element's shouldPlayNow now also answers simple inquiries without playing the element afterwards. - Android command "listplaylists" now includes conditions info. - Managing LEDs on IIYAMA tablets. - Playlists will now be checked for duplicates after loading is finished. If an anomaly is detected, the device will reload the content in the next download cycle. Anomalies will also be reported in the error log. 2.71.47 (21/06/2024) - Changed to TargetSDK 23 for new device models. - New parameter "AUTOSCROLL" to allow automatic scrolling of scrollable containers. - Fixed a crash in script function TVTools.changeObjectImage. - Changed the conditional playlist in playlist playback to fit the customer requests. - GeckoView edit mode now uses another command to upload the result to the server. - TVUtils.downloadBitmap will attempt to download and create a Bitmap even if the file doesn't have an image extension. - New .INI parameters : System/DisablePhilipsSICP to disable all philips device commands except the tablet LED commands. System/DisableCEC, which will disable any call to HDMI CEC if set to 1. System/CECSource, to set on which source the screen should be switched when turned on. -1 means no switching. - MasterDB will now check their content after each reboot. - Fixed a problem with Philips screens which could potentially lead to backlight never turning (back) on. 2.71.46 (23/05/2024) - Now also dealing with "DonneesFirst == 3" (get next records) when getting valid database records. - Forcing design duration in emergency playlists. - shouldPlayNow now makes the difference between a simple inquiry and a playback inquiry. - Implemented conditional broadcasting for playlists in playlists. - GeckoView now has an edit mode which can send modified web page .xml to the server: The view has a density of 2.0, and is rendered double the width of the playlist containing it, and if edit mode is used, the height is set to 8000 so the zoom won't be blurry. Android command "edit" starts the editor. Values will be displayed top left of your Android device screen. Move around with the left mouse button, and zoom in/out with the center mouse button. Android command "save " will send a modified file with the new pan and zoom values to the server, in the same directory than the original file, with the specified name. - Added versioncode to the debug dev view. - HTML views (WebView and GeckoView) will now use the "WebDocViewer" playlist when trying to display PDF files instead of the "DocViewer" playlist, to avoid interferences with LegalDoc doc viewers. - New script functions, for developper use only, so undocumented. - Philips : fixed a crash for when SICP was disabled and some Philips devices where no longer able to start the application. - Added some new ways to add nodes or modify existing ones to the XMLReader. 2.71.45 (02/05/2024) - Any Philips command is disabled until further notice (screen on/off, leds, etc...). You can enable them with the new .INI parameter DisablePhilipsSICP set to 0. - PDF will now adapt their bitmap resolution if the virtual resolution of a wall is too big. - First page durations for widgets will now be forced even if the default value is 0 and they have no container. Individual designs with a page 0 duration of 0 will still keep their duration. Yeah, I also have a headache reading this. Ask the indians. - Enhanced focus management in interactive designs with a keyboard so that there's no more risk of the keyboard disapearing and not coming back. - Support for inverted landscape, portrait and inverted portrait for Philips EINK displays. - Fixed a rare occurrence where views weren't removed when finished. Now using a custom method to remove views. - Philips EINK devices will now be detected to matter the Build.MODEL string. - New Android Command setposition w h x y to manually set a virtual resolution and pan position. 2.71.44 (22/04/2024) - Same as .43 but with screen on/off/luminosity enabled. 2.71.43 (22/04/2024) - Changed sound volume functions for LibVLC. - Changed background color code again because of the undocumented changes in the WebAccess. - Restored Async mode for background/synchronized playlists. - Fixed a rare case where the vertical scrollbar wouldn't appear on interactive scrollable vertical containers. - Emergency playlists will now be centered according to the virtual screen resolution. - Invalid bitmaps (bad format/impossible to load) will be displayed as red rectangles now. - New script functions: - "TVTools.roomBookingSetPlayNext(boolean playNext)" to be able to disable the "mustReloadBooking" Web Service command if needed. - "public String roomBookingEndEventByID(String id)" to end an event at the present time based on it's ID only. - Made the keepAlive http transport permanent for the WebService. - Completely ignoring any screen on/off/luminosity commands in this version. 2.71.42 (26/03/2024) - Some fixes for IPTV: GalleryView and EPG get key strokes again, and IPTV doesn't wait for buffering. 2.71.41 (20/03/2024) - Hotfix for crash on user interaction due to the modifications of the motion detection code. 2.71.40 (20/03/2024) - Designs with no containers and with a first page duration of 0 will now ignore different page durations from the WebAccess. - Improved download of additional files. - Reverted to old method for background color of text boxes. - New script commands, reserved for developers (no description available). - Greatly improved motion detection start reaction speed when you have a long idle delay time. 2.71.39 (08/03/2024) - Roulettes now get their colors from each entry of the database. - Designs: Even invisible views now have their dynamic content updated to avoid old data blinking shortly when the view becomes visible again. - Now always downloading additional files attached to playlist elements even if they don't have a main file. 2.71.38 (21/02/2024) - Fixed once again the management of transparency/opacity in designs because of the indians changing their rules as they see fit without warning. - Updated the HMDI CEC code so it also works on OHM devices. - Image elements can now also contain several images that have to be assembled side by side before being displayed. - MasterDB Implemented screenType=9 for devices with render several images side by side. - Debug developer View is now displaying the script variables sorted. I was tired of ruining my eyes finding a variable. - Scripts: new function "setObjectTextColor" to change a text object's text color on the fly in a script. "updateBDD" now returns the boolean "true" if the database has changed. - Support for VLC video volume control in MasterDBs. - Now closing the philips network socket each time its used. - Small fix to database color decoding for the "vosgian" format. 2.71.37 (30/01/2024) - Increased prefs version from 2.17 to 2.18. - Scripts: shouldPlayNow is now called without arguments. shouldPlay is now shouldPlayPage because of a conflict with shouldPlayNow which was generating unneeded errors in the log. new callback "onObjectsCreated(numPage)" which is called after all object views of a page are created, but before they are displayed. new function "getRawBDDField", which gets the raw value of a BDD field, before it is formatted. - Screenshots are now captured with the full virtual resolution. - Support for Philips EInk displays, for fixed images and designs. - Dynamic playlists are now always downloading Sync. - Support for more models of Techfive tablets. - MasterDB: Support for media volume control: For videos, only with ExoPlayer. For audio and videos in designs. - Databases/Formats: Support for decimal modes 3, 4 and 5, which will display numbers with smaller text for the decimal separator and fractional part, with 1, 2 or 3 digits precision. - Roulette containers: new "PARAMS" parameter which permits to get parameters like colors and background image from a recordset. - New .INI parameters "WebEngine/EnableWatchdog" and "WebEngine/WatchdogHosts", to define hosts to check for network sanity in GeckoView. When "EnableWatchdog=1", if "WatchdogHosts" is empty, the URL's hosts will be checked on port 80. Otherwise, you can add a list of hosts to check in "WatchdogHosts", like "host:port" (default port 80), separated by a ",". Only one pf the hosts needs to be reachable to validate the connection to the URL. - Updated GeckoView to 122.0.20240118164516. 2.71.36 (19/12/2023) - EMPTY recordsets now still create a file cache. - Designs: Enhanced non interactive PDF page display so that it doesn't flicker. PDF pages will now correctly be updated from the cache when in a container. - Support for GFA token recordsets : Name the recordset "#GFA_TOKEN". Mode "xml/json". The url should be the url of the token file, then ";", then the url of the data source. 2.71.35 (12/12/2023) - Added an "animated" parameter to pie charts so they can be used for real charts and for roulettes. - Recordsets named "EMPTY" or "#EMPTY" are now totally ignored by updates. - Now using EXIF to rotate photos from stupid mobile phones. - Optimized LoadText which is now much faster. - Now dispatching key events to "Roulette" style containers. 2.71.34 (05/12/2023) - Implemented circular containers displaying their elements in a pie chart style graphic. - New container type "CONT_MODE = 667", for "roulette" style animated circular containers. Additional parameters are "COLOR0=aarrggbb", "COLOR1=aarrggbb", etc... to define the colors of the sections of the roulette. The result of the spinning will be in variable "PIE_RESULT", which will be the index of the database entry. The main page script function "onSpin()" will be called when spinning starts, and "onPieResult(int num)" at the end of the spinning. - Rewrote formats properly so that they also work on text strings. The function now also properly loads the files in "Windows-1252" encoding, so that accents work, and gets the file directly from medias an no longer from tvtslide/.publish. Now just replaces the #BDD tag and not the whole string and its formatting. - The default YouTube browser in new installations is not GeckoView. - New .INI parameter "MuteVideos" in the "Video" section. If at 1, all videos (files, streams and youtube) will play without the sound. 2.71.33 (21/11/2023) - Implemented NPI-3411D printer natively. - New script function "printObjectToUSB(int objectID)" to print a graphical design object on a NPI-3411D USB printer. - Upgraded to GeckoView 120.0.20231113165053. - New script function "transferImage(int sourceID, int destinationID)" which renders an object into a destination image object. - Checklists are now updating properly. - getAlternateText now also contains the name of the calling database : function getAlternateText(index, bddName) 2.71.32 (14/11/2023) - Android 4.4 is no longer supported, MinSDK is now 21 (Android 5.0). - Upgraded GeckoView to 119.0.20231106151204 which requires Android 21. - Implemented the "use next records" option in recordsets. - The playlist randomization parameter is now ignored when synchro is active. - The "HiSenseShutdown" command no longer requires à wake up time. - New script commands: "printTextToUSB(String text)" prints a text on a compatible USB printer. "printBigNumberToUSB(int number)" prints a big number on a compatible USB printer. - Changed alpha channel recovery function after a modification in the compiler behavior. 2.71.31 (24/10/2023) - Upgraded to ExoPlayer v2.19.1. - Upgraded to LibVLC 4.00-dev Otto Chriek - LibVLC can now also play in designs. - The developer debug view will now have the right font size on true 4K displays. - WebSocket client: Disabled the automatic connection lost detection if the server is not another Android device with the right server code. - The default user agent for GeckoView is now "mobile". - New Android command "changewallschedulelevel", for internal use only. - Fixed a crash in the audio visualizer. - MasterDB: Now also displaying non youtube .xml stream files. 2.71.30 (28/09/2023) - Render4K: Full screen Videos will automatically play in a surface, and design videos in a texture. - Removed the unreliable "SERVER UNREACHABLE" info that was in the "get information" result. - GeckoView: Added "onWebPageStopped" callback, called when a web page has finished loading. Added "onWebSession" callback, called when a new session is required, permitting to open it in a different window for instance. - Connecting to LV5 in https now at installation. - New script function "hasWebPage" which returns true if the actual display includes a GeckoView. - Android command "screenorientation" now rotates the screen immediately. - New way to get the MAC address on devices which block the "getHardwareAddress" function. - Updated GeckoView to 118.0.20230927232528 2.71.29 (07/09/2023) - Dev info window now wraps content and displays native stack size. - Rewritten hasNetworkConnection to use new method after API 23 and to optionally also check if the server is reachable. - Fixed a random crash in image slideshows when the design containing them ended or looped. - New .INI parameter "System/Render4K". If at 1, all views will be rendered in a 4K hardware surface. Side effect is that videos in designs will automatically be rendered in a Texture for now. - Fixed an issue were the software would search for a file that is on the old server after a server change with the developper list on the device. - The Android command "screenorientation" now attempts to apply the new orientation immediately in order to make multiple wall configuration commands working properly. 2.71.28 (10/08/2023) - GeckoView will now automatically accept all security certificates. - Now taking 10 variables from the schedule level parameters sent by the WebService instead of only 3. 2.71.27 (07/08/2023) - Fixed a resource leak on image/bitmap download that was added when SVG files were implemented. - Dev debug: Displaying widget variables also in modal playlists. - Downgraded some error messages when the web services returns empty values to info instead of warning. - Fixed some potential crashes in LED control functions for devices without LEDs. 2.71.26 (01/08/2023) - Fixed duration for clock widgets. - RootSetDate modified to work on the newer devices with root. 2.71.25 (25/07/2023) - Fixed a crash when an element's condition string ended being null. 2.71.24 (25/07/2023) - New container box parameter "ALWAYS_REBUILD", which will force a container to be rebuilt even if it's assigned recordset has not changed. - Broadcasting conditions for a playlist within a playlist will now always be overwritten by the parent playlist parameters. - Added a security for when the MasterDB update counter in the message sent by the WebService is different from the one in the MDB file (WebAccess bug). - Added a specific message in the WebService answer for when a playlist is stopped because it's waiting for the next synchronisation signal. - Increased maximum number of records in databases to 5000 instead of 2500. 2.71.23 (13/07/2023) - New script function TVTools.roomBookingCheckConfirmation(). 2.71.22 (11/07/2023) - Full support of container build page filters. 2.71.21 (10/07/2023) - New syntax for websocketconfig [port=] [master]: enables the websocket on a specific server or url. The port is optional. The optional master parameter forces the server player to also always be the master of a sync group 2.71.20 (03/07/2023) - Fixed a rare crash with the blink timer for LEDs. - GeckoView now accepts sound playback even without having the focus. - Restored ability to change to the intern's version. No support at all will be done on that version. 2.71.19 (26/06/2023) - Fixed a crash cause by the context being null for the scrollbars in some cases in TVDesignView. 2.71.18 (13/06/2023) - Implemented "TVTWidgetDivers :" widgets for sports. 2.71.17 (13/06/2023) - If a media in a design is changed server side with the same name, it will now be refreshed after the next publication of the levels containing it. - New class "AppRequestReceiver", to receive TVLauncher Intent requests and answer to them. - PrefsFilePath is now initialized in the application constructor instead of the activity constructor. - Fixed the loading of zipped web pages. - Fixed VLC player not sending MediaReady to the playlist. - No longer transmitting key pressed to input commands when the played element is a multi stream (IPTV). - IPTV and IPRADIO commands are now controller elements. - Reduced VLC network cache to 256 when playing IPTV to reduce buffering time after a channel change with the new LibVLC. - Small modifications to VLC surface size changes to avoid some log spam. - GeckoView now asks for focus after being attached to the parent layout and after finishing loading a webpage. 2.71.16 (30/05/2023) - When a background color or image is selected in the WebAccess, and the design is broken because the construction page has an opaque color as background, automatically make that background transparent. 2.71.15 (30/05/2023) - No longer returning gibberish if SU is not supported when requesting CPU frequencies. - TVTools.updateObject now forces a container reconstruction. - DesignRecyclerAdapter now also supports horizontally and vertically centered text. - Sending media duration to the web service even if the media is in a playlist within another playlist. - Simplified the string returned to the WebService about the actual media when monitoring is disabled. - Added a vertical scrollbar to scrolling containers. 2.71.14 (22/05/2023) - Command "storageinfo" returns more detailed information. - Command "screenorientation" now displays the actual screen configuration in the "server" column of the monitoring if called without arguments. - Command "videoinfo" returns more detailed information. - Fixed a capacity calculation problem in vertically centered grid containers. 2.71.13 (15/05/2023) - If a licence file is present on a device, it will be automatically configured with a name like "AUTOyymmddhhmmss". - Stabilized the recycler adapter so that it doesn't crash when you remove an item from the list. - Increased WebService timeout to 20s instead of 10. 2.71.12 (09/05/2023) - HiSense: implemented UPDATE APK and POWER OFF TIME. poweroff