Added
- Zstandard ZIP Archive Support (RFC 8478 / Method 93): Added full support for opening, browsing, previewing, extracting, and modifying Zstandard-compressed
.zipfiles in the UFM Viewer and Archive Manager. When opening archives compressed with method 93 (Zstandard), UFM seamlessly falls back to Apache Commons Compress 1.28.0 using the bundledzstd-jninative library, resolving "Unknown compression method" errors. Checksum calculation, single/batch extraction, and archive mutations (adding/deleting files) are fully supported. - Custom Splash Screen Background: Updated the default Android 12+ launch splash screen background color to a refined dark teal (
#002039) matching the UFM theme. - Configurable Grid View Text Placement: Added option to display file and folder names below the thumbnail/icon block instead of overlaid on top with a gradient shadow. Text below block is now the default, with legacy overlay mode selectable in Settings under Appearance across both Mobile and Android TV.
- Porter Support: Added Porter as a third elevated-access manager alongside Shizuku and Shevery, listed first and marked recommended. UFM detects which managers are installed, distinguishes Porter from Shizuku when both are present, and shows each app's real launcher icon.
- Elevated Access Hero Card Enhancements: Added the active elevated manager's launcher icon and prominent application title to the top status hero card across Mobile and Android TV.
- Stop Daemon Action: Added a dedicated "Stop Daemon" button in the top status block to cleanly terminate running elevated background daemons via elevated process termination and client binder reset.
- Per-Application "Allow App Access" Toggle: Added an "Allow app access" switch inside each installed manager block (Porter, Shizuku, Shevery) allowing users to switch elevated permissions on and off directly within each application card.
Fixed
- Activity Launch ActivityManager Binder Watchdog ANR: Fixed a false-positive ANR (App Freeze) report when the ANR watchdog samples the main thread inside a synchronous binder call to the system server's
ActivityManagerwhile launching an Activity on Android 9 and earlier — top frameandroid.os.BinderProxy.transactNative(ortransact), underandroid.app.IActivityManager$Stub$Proxy.startActivity(orActivityManagerProxy.startActivity) ->Instrumentation.execStartActivity->Activity.startActivityForResult->Activity.startActivitydispatched during a button click (b0.onClick/MaterialButton.performClick) or lifecycle transition, thread state RUNNABLE, reported from a Droidlogic r34ay Android TV (SDK 28, app 2.0.9-GOOGLE). When opening an activity, the app invokes the frameworkstartActivity()API; on Android 9 (API 28) and earlier, activity management resides inIActivityManagerrather than Android 10+'sIActivityTaskManager. Under high system-server load or concurrent background I/O on CPU-constrained TV boxes, the synchronous binder IPC round-trip toActivityManagerServicecan take over 5 seconds while no application code is executing. ANR watchdog filter 23 (isActivityLaunchBinderStall) inCrashReportManagernow recognizes bothIActivityManager$Stub$Proxy.startActivityandActivityManagerProxy.startActivityalongsideIActivityTaskManager$Stub$Proxy.startActivityacross all Android framework versions, resetting its heartbeat instead of writing spurious freeze reports. Genuine freezes keeping the main thread inside application business logic or locks continue to be reported. - Framework LaunchActivity ProfilerInfo NullPointerException Crash: Resolved an unhandled framework
NullPointerException("Attempt to read from field 'android.app.ProfilerInfo android.app.ActivityThread$ActivityClientRecord.profilerInfo' on a null object reference" inActivityThread.handleLaunchActivityunderLaunchActivityItem.execute->TransactionExecutor.executeCallbacks->ActivityThread$H.handleMessage) during Activity launch on Android TV and mobile (reported on a TCL Smart TV Pro, SDK 31, app 2.0.6-GOOGLE). On certain OEM ROMs, asynchronous transaction processing or rapid lifecycle cancellations causedLaunchActivityItem.executeto invokehandleLaunchActivitywhen the correspondingActivityClientRecordwas missing fromActivityThread.mLaunchingActivities, causing field access onr.profilerInfoto throw an uncaught exception directly on the main thread looper.CrashReportManagernow installs a defensiveHandler.CallbackonActivityThread.mHduring application startup to interceptEXECUTE_TRANSACTION(msg.what == 159). If aLaunchActivityItemtransaction is received whose token is not present inmLaunchingActivities, it proactively invokesLaunchActivityItem.preExecuteto populate theActivityClientRecordso the Activity launches normally. Furthermore, the callback wraps transaction dispatch in defensive exception handling to catch and suppress any remainingprofilerInfoNullPointerExceptions, with a secondary looper recovery fallback inThread.setDefaultUncaughtExceptionHandler, ensuring the main looper message queue continues running smoothly without crashing the process. - Long-Press Duration SharedPreferences Watchdog ANR: Resolved an ANR ("Main thread blocked >5000ms") in
StorageBrowserActivity.dispatchKeyEventon Android TV (reported on a Sony BRAVIA 4K VH21, SDK 31, app 2.0.9-GOOGLE). When navigating or holding tiles on the main menu,StorageAdapterinvokedLongPressDurationManager.loadDurationMs()insideitemView.setOnKeyListeneron the main looper. Becauseufm_long_press_prefswas not loaded until first key interaction,SharedPreferencesImpl.getInt()blocked the main thread inawaitLoadedLocked()while the backgroundSharedPreferencesImpl-loadthread loaded the preferences XML from flash storage under concurrent I/O, freezing the UI thread for over 5 seconds.LongPressDurationManagernow caches the duration step index in memory (cachedStep), returns the default duration (DEFAULT_STEP = 3, 2000 ms) immediately if uninitialized on the main thread while asynchronously populating the cache in background, andUfmApplication.onCreate()pre-warmsLongPressDurationManager(alongsideFontSizeHelper,LocaleHelper, andColorblindPrefs) during cold start before the ANR watchdog is armed and before any Activity attaches. In addition,MainMenuViewModeManagercaches view mode, column count, and item size in memory to eliminate repeated synchronous disk queries during key navigation and layout passes. - Snackbar Layout Inflation ColorStateList Watchdog ANR: Fixed a false-positive ANR (App Freeze) report when the ANR watchdog samples the main thread inside
ColorStateList.valueOfor weak reference resolution during Snackbar layout inflation — top framejava.lang.ref.Reference.getReferent(orReference.get,android.content.res.ColorStateList.valueOf), underColorStateList.valueOf->com.google.android.material.snackbar.Snackbar$SnackbarLayout.<init>(orSnackbarBaseLayout.<init>,SnackbarContentLayout.<init>) ->LayoutInflater.createView/createViewFromTag/inflate, underSnackbar.makedispatched during a user click / key event handler (StorageBrowserActivity.showPremiumSnackbar), thread state RUNNABLE, reported from an NVIDIA SHIELD Android TV (SDK 30, app 2.0.9-GOOGLE).ColorStateList.valueOfperforms an in-memory cache lookup in aSparseArray<WeakReference<ColorStateList>>that takes sub-microsecond CPU time with no locks, disk I/O, or IPC; it cannot by itself occupy the main looper for 5 seconds. The >5 s block was device-side CPU starvation or scheduling latency on an Android TV device where background SSDP/DLNA listeners, HTTP streaming servers, GC daemons, and coroutine workers were concurrently RUNNABLE, causing the watchdog to sample the main looper during normal Snackbar view inflation. TheAnrWatchdogThreadfilter 71 (isSnackbarInflateColorStateListStall) now treats a main-thread stack whose top frame isReference.getReferent,Reference.get, orColorStateList.valueOf, with aColorStateList.valueOfframe, aSnackbarorSnackbarLayoutframe, aLayoutInflaterframe, and no framework blocking primitives anywhere on the stack as a false positive, resetting its heartbeat instead of writing a spurious freeze report. In addition,StorageBrowserActivity.showPremiumSnackbaradds defensive activity lifecycle guards (isFinishing || isDestroyed), fallback root view resolution, and exception handling. Genuine freezes keep the main thread parked inside a blocking primitive (lock, file/network/database I/O, or binder transact) and are still reported. - WorkManager SystemJobService OnCreate Watchdog ANR: Fixed a false-positive ANR (App Freeze) report when the ANR watchdog samples the main thread inside WorkManager's
SystemJobService.onCreatewhile the system creates the service on the main thread — top framexw6.a(orWorkManagerImpl.getInstance,JobExecutionTracker.<init>,PreferenceUtils, orSystemJobService.onCreate), underandroidx.work.impl.background.systemjob.SystemJobService.onCreate->ActivityThread.handleCreateService->ActivityThread$H.handleMessage, thread state RUNNABLE, reported from a Xiaomi MiTV-AXFR2 (SDK 30, app 1.8.9-GOOGLE). Service creation is framework-driven when JobScheduler wakes the process to execute scheduled background work;SystemJobService.onCreate()performs lightweight WorkManager initialization that cannot by itself occupy the main looper for 5 seconds. The >5 s block was device-side CPU starvation on a low-end TV where background startup I/O, pairing keystore init, Google API handler, and WorkManager background threads were concurrently RUNNABLE, causing the watchdog to sample the main looper during normal library service creation. TheAnrWatchdogThreadfilter 70 (isSystemJobServiceCreateStall) now treats a main-thread stack containingSystemJobService.onCreateunderActivityThread.handleCreateServicewith no application package frames and no framework blocking primitives as a false positive, resetting its heartbeat instead of writing a spurious freeze report. Genuine freezes keep an app frame on the stack (e.g. app services' ownonCreate) or park the main thread in a blocking primitive (lock, file/network/database I/O, or binder transact) and are still reported. - Recent Files Main Thread Blocked ANR: Resolved an ANR ("Main thread blocked >5000ms") in
RecentFilesActivityduring recent files category layout updates on Android (reported on a ZTE Z2466, SDK 34, app 2.0.9-GOOGLE). When recent files were observed or updated,RecentFilesActivity.updateAllCategories()iterated through all 6 category tabs on the main looper thread, performing synchronousfileObj.exists()andfileObj.isFilestat calls (BlockGuardOs.access/Linux.access) across hundreds of file items, accumulating severe filesystem I/O latency that froze the UI thread for over 5 seconds.RecentsRepository.observeRecentFiles()now dispatches database entity mapping and filesystem existence checks toDispatchers.IOvia.flowOn(Dispatchers.IO),updateAllCategories()removes redundant synchronous disk I/O on the main thread relying on pre-validated items, rename target file existence and metadata queries are offloaded toDispatchers.IOprior to main-thread UI dispatch, and delete confirmation counts files directly viaselected.sizewithout synchronous stat queries. - Package Install Result Dialog ANR: Resolved an ANR ("Main thread blocked >5000ms") in
InstallResultActivity.onCreateon Android TV (reported on a Google X96Q, SDK 29, app 2.0.0-GOOGLE). Previously,InstallResultActivity(a translucent floating activity) created and displayed a secondaryMaterialAlertDialogBuilderdialog window synchronously inside its ownonCreate(), callingDialog.show()->WindowManagerGlobal.addViewbefore the activity's window was attached. On Android TV devices with accessibility services active, this triggered a synchronous Binder IPC toIAccessibilityManager.addAccessibilityInteractionConnectionthat blocked inBinderProxy.transactNativeunder system-server lock contention.InstallResultActivitynow sets its layout directly viasetContentViewwith transparent background, centered gravity, adaptive mobile/TV width, touch-outside dismissal (setFinishOnTouchOutside(true)), and direct D-pad focus management, eliminating secondary window creation and nested accessibility Binder transactions during activity launch. In addition,AnrWatchdogThreadfilter 68 (isAccessibilityConnectionBinderStall) treats main-thread samples insideBinderProxy.transactunderIAccessibilityManager.addAccessibilityInteractionConnectionduringViewRootImpl.setView/WindowManagerGlobal.addViewwith no app business logic execution as system-server binder stalls, resetting the watchdog heartbeat instead of writing spurious reports. - Archive Viewer TV Focus ClassCastException Crash: Fixed a crash (
java.lang.ClassCastException: android.widget.FrameLayout$LayoutParams cannot be cast to androidx.recyclerview.widget.RecyclerView$LayoutParams) inZipViewerActivity.dispatchKeyEvent(andSevenZipViewerActivity) on Android TV when pressing or holding D-pad Center or Enter (reported on an Expressluck Apollo Premium2K TV, SDK 34, app 2.0.9-GOOGLE). Previously,currentFocuswas passed directly torecyclerEntries.getChildAdapterPosition(), which threwClassCastExceptionwhenever the focused view was not a direct child of theRecyclerView(such as inner child views inside item cards or header action buttons withFrameLayout.LayoutParams). Focused entries are now safely resolved usingrecyclerEntries.findContainingViewHolder(focused)with binding adapter position validation, defensive exception handling, andrecyclerEntries.hasFocus()checks. - Activity Layout Inflation CaseMap Watchdog ANR: Fixed a false-positive ANR (App Freeze) report when the ANR watchdog samples the main thread inside ICU character case mapping or text uppercase transformation during Activity cold-start layout inflation — top frame
android.icu.impl.CaseMapImpl.internalToUpper/toUpper(orandroid.icu.text.CaseMap$Upper.apply,android.text.TextUtils.toUpperCase,java.lang.String.toUpperCase, orandroid.text.method.AllCapsTransformationMethod.getTransformation), underAllCapsTransformationMethod.getTransformation->TextView.setText/MaterialButton.setText->TextView.setTransformationMethod/setTransformationMethodInternal->TextView.applyTextAppearance->TextView.<init>/MaterialButton.<init>underLayoutInflater.inflate->setContentViewduring Activity cold start (StorageBrowserActivity.onCreate), reported from a SkyworthDigital 4K Google TV Stick (SDK 34, app 2.0.6-GOOGLE). Converting a short button label to uppercase in memory via ICU takes nanoseconds and cannot by itself occupy the main thread for 5 seconds; the >5 s block was cold-start initialization latency on a CPU-constrained TV stick where background DLNA/SSDP and HTTP network workers were concurrently RUNNABLE, causing the watchdog to sample the main looper during normal framework layout inflation. TheAnrWatchdogThreadfilter 67 (isCaseMapAllCapsButtonInflateStall) now treats a main-thread stack whose top frame is inside ICU/text uppercase transformation underAllCapsTransformationMethod.getTransformation,LayoutInflater.inflate, and an Activity cold-start launch with no framework blocking primitives and only Activity lifecycle frames in the application package as a false positive, resetting its heartbeat instead of writing a report. Genuine freezes keep the main thread parked inside a blocking primitive (lock, file/network/database I/O, or binder call) or app business logic outside framework layout inflation and are still reported. - Recycle Bin CursorWindow Exhaustion Crash: Resolved an
IllegalStateException("Couldn't read row 1233, col 0 from CursorWindow. Make sure the Cursor is initialized correctly before accessing data from it") during Room coroutine Flow observation inRecycleBinActivitywhen the recycle bin contains over ~1,200 items on Android 16 (reported on a Motorola signature device, SDK 37, app 2.0.9-FOSS). InRecycleBinDao, unboundedSELECT * FROM recycle_binqueries loaded all 14 columns into a single SQLite cursor, which exceeded Android's 2MB CursorWindow capacity and caused native row reads to throwIllegalStateExceptionwhen advancing past the initial window.RecycleBinDao.getAllFlow()andgetAll()are now bounded withLIMIT 500, andRecycleBinManager.getAllEntries()loads in safe 250-row chunks usinggetPaged(limit, offset)pagination so bulk operations (emptyTrash,validateEntries) iterate safely without CursorWindow exhaustion. In addition,RecycleBinActivity.observeDataguards flow collection with.catch,updateTrashSize()andRecycleBinCleanupWorkercompute trash totals and expired entries via direct SQL aggregation (getTotalFileSize,getFileCount,getFolderCount,getExpiredEntries) rather than full table cursor scans, andUfmApplicationandRecycleBinDatabasedefensively expandsCursorWindowSizeto 50MB where permitted by runtime reflection. - TV Remote Activity Launch NullPointerException Crash: Fixed a crash (
java.lang.RuntimeException: Unable to start activity ComponentInfo{za.kilowatch.ultimatefilemanager.foss/za.kilowatch.ultimatefilemanager.network.TvRemoteActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Class java.lang.Object.getClass()' on a null object reference) duringonCreate()ofTvRemoteActivity(reported from an Honor 90 /HONOR CRT-LX1, SDK 34, app 1.9.8-FOSS). InTvRemoteActivity, 33 view references were declared as strict non-nulllateinit varproperties and assigned directly viafindViewByIdduringbindViews(). In Kotlin, assigningfindViewByIdto a non-nullable property automatically emits a non-null intrinsic assertion (java.lang.Object.getClass()in compiled DEX/R8 bytecode), which threw an uncaughtNullPointerExceptionif any view was missing (e.g. under alternative OEM layout configurations, multi-window/split-screen, floating window mode, or OEM theme overlays on Honor MagicOS / EMUI). All 33 view references inTvRemoteActivityare now nullable properties initialized tonull,bindViews()provides back navigation fallback (android.R.id.home), and all toolbar, button, and status card interactions operate with safe calls (?.). Additionally,bluetoothStateReceiverregistration inonCreate()was migrated toContextCompat.registerReceiverwithRECEIVER_EXPORTEDand wrapped in defensivetry/catchexception handling for Android 14+ compatibility. - TV Remote Bluetooth SecurityException Crash: Fixed a crash (
java.lang.SecurityException: Need BLUETOOTH permission: Neither user 10339 nor current process has android.permission.BLUETOOTH) when tapping "Connect via Bluetooth" inTvRemoteActivityon TV builds (reported from a Samsung Galaxy M20, SDK 29, app 1.9.9-AMAZON). WhenTvRemoteActivityandTvSetupGuideActivitywere moved to the shared main manifest so they could resolve on TV builds whenDeviceUtils.isTvDevice()is false, the Bluetooth permissions (BLUETOOTH,BLUETOOTH_ADMIN,BLUETOOTH_CONNECT,BLUETOOTH_ADVERTISE,BLUETOOTH_SCAN) andBluetoothHidServiceremained declared only in the mobile-specific manifest, leaving TV variants withoutandroid.permission.BLUETOOTHand causingBluetoothAdapter.isEnabledto throw an uncaughtSecurityExceptionfrom the main looper. Bluetooth permissions andBluetoothHidServiceare now declared in the shared main manifest with optional feature flags (required="false") so all build variants hold them without restricting device compatibility. In addition,BluetoothRemoteManager.isBluetoothEnabled(),initialize(), andcleanup()now defensively catchSecurityExceptionand general exceptions, andTvRemoteActivityverifiesBLUETOOTHpermission on Android <= 30 before initiating Bluetooth connections, directing users to the permission state card if missing. - Streaming Proxy Seek Freezes (Issue #33): Fixed video freezing while audio continues playing during external player (VLC) playback over SMB. The local HTTP proxy now proactively aborts superseded in-flight streams and closes their sockets on new seek requests, freeing blocked loopback connections.
- Loopback Socket Tuning: Enabled
TCP_NODELAYand capped socket send buffers to 512 KB on the local HTTP streaming proxy to eliminate Nagle ACK latency and prevent loopback buffer bloat. - SMB Session & Handle Leak Elimination (Issue #33): Fixed SMB sessions and file handles lingering after media playback by automatically closing idle file handles after 60 seconds of inactivity (with transparent reopening on demand), reducing session TTL to 10 minutes, and querying file sizes via pooled SMB metadata rather than opening dedicated random-access connections prior to launch.
- Translated Brand Names: Corrected the app name,
UFM,RClone,ShizukuandSheverybeing translated or transliterated in the Hindi, Arabic, Italian and Dutch translations, where they are now kept in their original spelling. - Open-Source Licence List: Corrected the licence list, which attributed a single licence to the whole Porter SDK and omitted the bundled Shizuku API.
- RecyclerView Computing Layout Collision: Resolved
IllegalStateException: Cannot call this method while RecyclerView is computing a layout or scrollingon the storage list during rapid tile reordering or detached view cleanup on Android 16 (SDK 37).StorageAdapter.safeNotifyDataSetChangednow verifies that the attachedRecyclerViewis not mid-layout before notifying (deferring via re-post if computing layout) and is backed by defensive exception handlers. In addition,StorageAdapter.moveItemguards against dispatchingnotifyItemMovedduring layout passes, and TV reorder mode and custom header operations now use safe notifications. Similar layout-computation guards were added toFileAdapterandNetworkFileAdapter. - Recycled Bitmap Crash on Eviction: Fixed
Canvas: trying to use a recycled bitmapduring rapid scrolling by removing premature manual.recycle()calls from volume and LRU cache evictions inFileAdapterandAudioCoverHelper, allowing garbage collection to reclaim bitmap memory safely without racing activeImageViewdraws. - Foreground Service Startup Watchdog Crash: Fixed
RemoteServiceException$ForegroundServiceDidNotStartInTimeExceptioninUFMPlaybackService,AdbSessionForegroundService, andAdbRemoteForegroundServiceon Android 14+ (SDK 34–36) by ensuring services do not terminate prematurely before foreground promotion is confirmed by the system server, and favoringstartServicebefore attempting foreground promotion. - Document Scanner Camera Intent Crash: Fixed
ActivityNotFoundExceptioninDocumentScannerActivitywhen attempting to launchMediaStore.ACTION_IMAGE_CAPTUREon devices without a default camera application, presenting a clear user notification and removing unsafe bitmap recycling on preview pages. - Network File Adapter TV Null Pointer Crash: Fixed
NullPointerExceptiononswitchToggle.setOnCheckedChangeListenerinNetworkFileAdapterwhen running on Android TV by making the toggle listener null-safe and including@+id/switchTogglein the TV item layout. - File Server 6-Hour Timeout Crash (Android 15): Resolved
RemoteServiceException$ForegroundServiceDidNotStopInTimeExceptioninFileServerServiceby implementingService.onTimeoutfordataSyncforeground services on Android 15 (API 35+). When reaching the system runtime limit, the service immediately demotes from foreground, terminates active FTP/SFTP/DLNA servers cleanly, updates UI widgets, and displays a user notification. DefensiveonTimeoutoverrides were also added toTransferServiceandSmartSortWidgetExecuteService. - Package Install Receiver ANR: Resolved an ANR ("Main thread blocked >5000ms") in
InstallReceiver.onReceivewhen dispatchingPackageInstallercompletion broadcasts on Android TV. Handled broadcasts asynchronously viagoAsync()on a dedicated background daemon executor (ufm-install-receiver), offloading synchronousNotificationManagerIPC calls and temporary cache file cleanup from the main looper. - TextView SetText LineBreaker Watchdog ANR: Fixed a false-positive ANR (App Freeze) report when the ANR watchdog samples the main thread inside the framework's native line-break result inspection while a main-looper Runnable updates a TextView's text via
TextView.setText— top frameandroid.graphics.text.LineBreaker$Result.getLineCount(orLineBreaker.nComputeLineBreaks/computeLineBreaks), underStaticLayout.generate->StaticLayout$Builder.build->TextView.makeSingleLayout/makeNewLayout->TextView.checkForRelayout->TextView.setText, dispatched by a main-looper Runnable (Handler.handleCallback), reported from an Expressluck GRS SMART 4K TV (SDK 30, app 2.0.6-GOOGLE).LineBreaker$Result.getLineCountis a µs-scale bounded native/framework call that returns the line count of the computed breaks, andTextView.setTextis standard framework text relayout: it cannot by itself occupy the main thread for 5 s. The main looper was actively processing a freshly dispatched message at sample time (Handler.handleCallbackdirectly below the Runnable'srun()), which a thread parked inside a >5 s block cannot do — the >5 s block is device-side CPU starvation on the low-end TV (where DLNA, NanoHttpd, and coroutine worker threads were all RUNNABLE) or a post-stall sample of the backlog the main looper drains after a genuine stall. TheAnrWatchdogThreadfilter 65 (isTextViewSetTextLineBreakerStall) now treats a main-thread stack whose top frame isLineBreaker$Result.getLineCount(orLineBreaker.nComputeLineBreaks/computeLineBreaks), with aStaticLayout.generate/StaticLayout$Builder.buildframe, aTextView.makeSingleLayout/makeNewLayout/checkForRelayoutframe, aTextView.setTextframe, a main-looper Runnable (run()sitting directly onHandler.handleCallback), with noza.kilowatch.ultimatefilemanagerframes and no framework blocking primitive anywhere on the stack, as a false positive and resets its heartbeat instead of writing a report. Genuine freezes keep the main thread inside app business logic or a blocking primitive (lock, file/network/database I/O, binder transact) and are still reported. - Root Storage Space Calculation ANR: Resolved an ANR ("Main thread blocked >5000ms") in
FileBrowserActivityduring root folder loading (FileBrowserActivity.onCreate->loadDirectory->targetDir.freeSpace/targetDir.totalSpace->File.getFreeSpace->UnixFileSystem.getSpace0) reported from a TCL Smart TV Pro (SDK 34, app 2.0.6-GOOGLE). When opening or navigating to the root of a storage volume,FileBrowserActivitysynchronously queriedfreeSpaceandtotalSpaceon the main looper thread to populate the toolbar and TV header subtitle ("X free of Y"), invoking the nativestatvfssyscall which can stall for over 5 seconds on slow flash or busy USB storage. Initial subtitle rendering now sets the storage path synchronously without blocking, while free and total capacity calculations are offloaded toDispatchers.IOwith lifecycle cancellation guards (storageSpaceJob), updating the UI headers smoothly once computed. - Storage Initialization & Collection Iterator ANR: Resolved an ANR ("Main thread blocked >5000ms") in
FileBrowserActivityduring Activity creation and relaunch (FileBrowserActivity.onCreate->SafTreeManager.hasTreePermissionForPath->findMatchingTreeEntry->SafLocationRepository.getLocations->EmptyList.iterator()) reported from a Vantiva XstreamIPTV1-VT (SDK 34, app 2.0.9-GOOGLE). When opening or relaunchingFileBrowserActivity,SafLocationRepository.getLocationsperformed synchronouscontentResolver.persistedUriPermissionsIPC calls andDocumentFile.fromTreeUriContentProvider queries on the main thread, contending with concurrent background media and indexing workers. Persisted URI permission reconciliation is now offloaded toDispatchers.IO, andSafTreeManager.hasTreePermissionForPathandFileBrowserActivity.onCreatefast-path standard internal storage (/storage/emulated/0) to bypass SAF permission queries completely. In addition,AnrWatchdogThreadfilter 66 (isActivityOnCreateCollectionIteratorStall) treats main-thread samples in trivial in-memory collection iterators (iterator/listIterator) during Activity creation and relaunch with no framework blocking primitives as false positives caused by TV device CPU starvation, resetting the watchdog heartbeat instead of writing spurious reports. - TV Background Server & Pairing Init ANR: Resolved an ANR ("Main thread blocked >5000ms") in
TvServerForegroundService.onCreateandonStartCommandduring service startup on Android TV (ZTE OTT Xview+ AV1, SDK 30, app 1.9.8-GOOGLE). WhenTvServerForegroundServicewas created, it invokedUfmApplication.instance.ensurePairingServerRunning()on the main looper, which attempted to acquire a monitor lock onthis(UfmApplication.instance) that was already held by the backgroundufm-pairing-initthread performing heavyAndroidKeyStoreECDSA key generation, SSLContext setup, and AES-GCM token decryption viaSecureTokenStoreunderTHREAD_PRIORITY_BACKGROUNDCPU starvation.ensurePairingServerRunning()inTvServerForegroundService.onCreateandonStartCommandis now offloaded to a dedicated background daemon thread (ufm-tv-server-init), andPairingManager.hasPairedDevices()provides a lightweight check bypassing token decryption on the main thread. In addition,UfmApplication.pairingServeris marked@Volatilewith a dedicated lock object (pairingServerLock),ensurePairingServerRunning()automatically dispatches to background if called from the main thread, andufm-pairing-initpriority reduction was removed to prevent startup CPU starvation.