github Kilowatch/ultimate-file-manager-pro v2.1.0

latest releases: v2.2.3, v2.2.2, v2.2.1...
one month ago

Added

  • Zstandard ZIP Archive Support (RFC 8478 / Method 93): Added full support for opening, browsing, previewing, extracting, and modifying Zstandard-compressed .zip files 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 bundled zstd-jni native 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 ActivityManager while launching an Activity on Android 9 and earlier — top frame android.os.BinderProxy.transactNative (or transact), under android.app.IActivityManager$Stub$Proxy.startActivity (or ActivityManagerProxy.startActivity) -> Instrumentation.execStartActivity -> Activity.startActivityForResult -> Activity.startActivity dispatched 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 framework startActivity() API; on Android 9 (API 28) and earlier, activity management resides in IActivityManager rather than Android 10+'s IActivityTaskManager. Under high system-server load or concurrent background I/O on CPU-constrained TV boxes, the synchronous binder IPC round-trip to ActivityManagerService can take over 5 seconds while no application code is executing. ANR watchdog filter 23 (isActivityLaunchBinderStall) in CrashReportManager now recognizes both IActivityManager$Stub$Proxy.startActivity and ActivityManagerProxy.startActivity alongside IActivityTaskManager$Stub$Proxy.startActivity across 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" in ActivityThread.handleLaunchActivity under LaunchActivityItem.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 caused LaunchActivityItem.execute to invoke handleLaunchActivity when the corresponding ActivityClientRecord was missing from ActivityThread.mLaunchingActivities, causing field access on r.profilerInfo to throw an uncaught exception directly on the main thread looper. CrashReportManager now installs a defensive Handler.Callback on ActivityThread.mH during application startup to intercept EXECUTE_TRANSACTION (msg.what == 159). If a LaunchActivityItem transaction is received whose token is not present in mLaunchingActivities, it proactively invokes LaunchActivityItem.preExecute to populate the ActivityClientRecord so the Activity launches normally. Furthermore, the callback wraps transaction dispatch in defensive exception handling to catch and suppress any remaining profilerInfo NullPointerExceptions, with a secondary looper recovery fallback in Thread.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.dispatchKeyEvent on 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, StorageAdapter invoked LongPressDurationManager.loadDurationMs() inside itemView.setOnKeyListener on the main looper. Because ufm_long_press_prefs was not loaded until first key interaction, SharedPreferencesImpl.getInt() blocked the main thread in awaitLoadedLocked() while the background SharedPreferencesImpl-load thread loaded the preferences XML from flash storage under concurrent I/O, freezing the UI thread for over 5 seconds. LongPressDurationManager now 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, and UfmApplication.onCreate() pre-warms LongPressDurationManager (alongside FontSizeHelper, LocaleHelper, and ColorblindPrefs) during cold start before the ANR watchdog is armed and before any Activity attaches. In addition, MainMenuViewModeManager caches 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.valueOf or weak reference resolution during Snackbar layout inflation — top frame java.lang.ref.Reference.getReferent (or Reference.get, android.content.res.ColorStateList.valueOf), under ColorStateList.valueOf -> com.google.android.material.snackbar.Snackbar$SnackbarLayout.<init> (or SnackbarBaseLayout.<init>, SnackbarContentLayout.<init>) -> LayoutInflater.createView / createViewFromTag / inflate, under Snackbar.make dispatched 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.valueOf performs an in-memory cache lookup in a SparseArray<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. The AnrWatchdogThread filter 71 (isSnackbarInflateColorStateListStall) now treats a main-thread stack whose top frame is Reference.getReferent, Reference.get, or ColorStateList.valueOf, with a ColorStateList.valueOf frame, a Snackbar or SnackbarLayout frame, a LayoutInflater frame, 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.showPremiumSnackbar adds 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.onCreate while the system creates the service on the main thread — top frame xw6.a (or WorkManagerImpl.getInstance, JobExecutionTracker.<init>, PreferenceUtils, or SystemJobService.onCreate), under androidx.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. The AnrWatchdogThread filter 70 (isSystemJobServiceCreateStall) now treats a main-thread stack containing SystemJobService.onCreate under ActivityThread.handleCreateService with 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' own onCreate) 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 RecentFilesActivity during 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 synchronous fileObj.exists() and fileObj.isFile stat 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 to Dispatchers.IO via .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 to Dispatchers.IO prior to main-thread UI dispatch, and delete confirmation counts files directly via selected.size without synchronous stat queries.
  • Package Install Result Dialog ANR: Resolved an ANR ("Main thread blocked >5000ms") in InstallResultActivity.onCreate on Android TV (reported on a Google X96Q, SDK 29, app 2.0.0-GOOGLE). Previously, InstallResultActivity (a translucent floating activity) created and displayed a secondary MaterialAlertDialogBuilder dialog window synchronously inside its own onCreate(), calling Dialog.show() -> WindowManagerGlobal.addView before the activity's window was attached. On Android TV devices with accessibility services active, this triggered a synchronous Binder IPC to IAccessibilityManager.addAccessibilityInteractionConnection that blocked in BinderProxy.transactNative under system-server lock contention. InstallResultActivity now sets its layout directly via setContentView with 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, AnrWatchdogThread filter 68 (isAccessibilityConnectionBinderStall) treats main-thread samples inside BinderProxy.transact under IAccessibilityManager.addAccessibilityInteractionConnection during ViewRootImpl.setView / WindowManagerGlobal.addView with 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) in ZipViewerActivity.dispatchKeyEvent (and SevenZipViewerActivity) 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, currentFocus was passed directly to recyclerEntries.getChildAdapterPosition(), which threw ClassCastException whenever the focused view was not a direct child of the RecyclerView (such as inner child views inside item cards or header action buttons with FrameLayout.LayoutParams). Focused entries are now safely resolved using recyclerEntries.findContainingViewHolder(focused) with binding adapter position validation, defensive exception handling, and recyclerEntries.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 (or android.icu.text.CaseMap$Upper.apply, android.text.TextUtils.toUpperCase, java.lang.String.toUpperCase, or android.text.method.AllCapsTransformationMethod.getTransformation), under AllCapsTransformationMethod.getTransformation -> TextView.setText / MaterialButton.setText -> TextView.setTransformationMethod / setTransformationMethodInternal -> TextView.applyTextAppearance -> TextView.<init> / MaterialButton.<init> under LayoutInflater.inflate -> setContentView during 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. The AnrWatchdogThread filter 67 (isCaseMapAllCapsButtonInflateStall) now treats a main-thread stack whose top frame is inside ICU/text uppercase transformation under AllCapsTransformationMethod.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 in RecycleBinActivity when the recycle bin contains over ~1,200 items on Android 16 (reported on a Motorola signature device, SDK 37, app 2.0.9-FOSS). In RecycleBinDao, unbounded SELECT * FROM recycle_bin queries loaded all 14 columns into a single SQLite cursor, which exceeded Android's 2MB CursorWindow capacity and caused native row reads to throw IllegalStateException when advancing past the initial window. RecycleBinDao.getAllFlow() and getAll() are now bounded with LIMIT 500, and RecycleBinManager.getAllEntries() loads in safe 250-row chunks using getPaged(limit, offset) pagination so bulk operations (emptyTrash, validateEntries) iterate safely without CursorWindow exhaustion. In addition, RecycleBinActivity.observeData guards flow collection with .catch, updateTrashSize() and RecycleBinCleanupWorker compute trash totals and expired entries via direct SQL aggregation (getTotalFileSize, getFileCount, getFolderCount, getExpiredEntries) rather than full table cursor scans, and UfmApplication and RecycleBinDatabase defensively expand sCursorWindowSize to 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) during onCreate() of TvRemoteActivity (reported from an Honor 90 / HONOR CRT-LX1, SDK 34, app 1.9.8-FOSS). In TvRemoteActivity, 33 view references were declared as strict non-null lateinit var properties and assigned directly via findViewById during bindViews(). In Kotlin, assigning findViewById to a non-nullable property automatically emits a non-null intrinsic assertion (java.lang.Object.getClass() in compiled DEX/R8 bytecode), which threw an uncaught NullPointerException if 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 in TvRemoteActivity are now nullable properties initialized to null, bindViews() provides back navigation fallback (android.R.id.home), and all toolbar, button, and status card interactions operate with safe calls (?.). Additionally, bluetoothStateReceiver registration in onCreate() was migrated to ContextCompat.registerReceiver with RECEIVER_EXPORTED and wrapped in defensive try/catch exception 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" in TvRemoteActivity on TV builds (reported from a Samsung Galaxy M20, SDK 29, app 1.9.9-AMAZON). When TvRemoteActivity and TvSetupGuideActivity were moved to the shared main manifest so they could resolve on TV builds when DeviceUtils.isTvDevice() is false, the Bluetooth permissions (BLUETOOTH, BLUETOOTH_ADMIN, BLUETOOTH_CONNECT, BLUETOOTH_ADVERTISE, BLUETOOTH_SCAN) and BluetoothHidService remained declared only in the mobile-specific manifest, leaving TV variants without android.permission.BLUETOOTH and causing BluetoothAdapter.isEnabled to throw an uncaught SecurityException from the main looper. Bluetooth permissions and BluetoothHidService are 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(), and cleanup() now defensively catch SecurityException and general exceptions, and TvRemoteActivity verifies BLUETOOTH permission 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_NODELAY and 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, Shizuku and Shevery being 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 scrolling on the storage list during rapid tile reordering or detached view cleanup on Android 16 (SDK 37). StorageAdapter.safeNotifyDataSetChanged now verifies that the attached RecyclerView is not mid-layout before notifying (deferring via re-post if computing layout) and is backed by defensive exception handlers. In addition, StorageAdapter.moveItem guards against dispatching notifyItemMoved during layout passes, and TV reorder mode and custom header operations now use safe notifications. Similar layout-computation guards were added to FileAdapter and NetworkFileAdapter.
  • Recycled Bitmap Crash on Eviction: Fixed Canvas: trying to use a recycled bitmap during rapid scrolling by removing premature manual .recycle() calls from volume and LRU cache evictions in FileAdapter and AudioCoverHelper, allowing garbage collection to reclaim bitmap memory safely without racing active ImageView draws.
  • Foreground Service Startup Watchdog Crash: Fixed RemoteServiceException$ForegroundServiceDidNotStartInTimeException in UFMPlaybackService, AdbSessionForegroundService, and AdbRemoteForegroundService on Android 14+ (SDK 34–36) by ensuring services do not terminate prematurely before foreground promotion is confirmed by the system server, and favoring startService before attempting foreground promotion.
  • Document Scanner Camera Intent Crash: Fixed ActivityNotFoundException in DocumentScannerActivity when attempting to launch MediaStore.ACTION_IMAGE_CAPTURE on 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 NullPointerException on switchToggle.setOnCheckedChangeListener in NetworkFileAdapter when running on Android TV by making the toggle listener null-safe and including @+id/switchToggle in the TV item layout.
  • File Server 6-Hour Timeout Crash (Android 15): Resolved RemoteServiceException$ForegroundServiceDidNotStopInTimeException in FileServerService by implementing Service.onTimeout for dataSync foreground 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. Defensive onTimeout overrides were also added to TransferService and SmartSortWidgetExecuteService.
  • Package Install Receiver ANR: Resolved an ANR ("Main thread blocked >5000ms") in InstallReceiver.onReceive when dispatching PackageInstaller completion broadcasts on Android TV. Handled broadcasts asynchronously via goAsync() on a dedicated background daemon executor (ufm-install-receiver), offloading synchronous NotificationManager IPC 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 frame android.graphics.text.LineBreaker$Result.getLineCount (or LineBreaker.nComputeLineBreaks/computeLineBreaks), under StaticLayout.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.getLineCount is a µs-scale bounded native/framework call that returns the line count of the computed breaks, and TextView.setText is 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.handleCallback directly below the Runnable's run()), 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. The AnrWatchdogThread filter 65 (isTextViewSetTextLineBreakerStall) now treats a main-thread stack whose top frame is LineBreaker$Result.getLineCount (or LineBreaker.nComputeLineBreaks/computeLineBreaks), with a StaticLayout.generate/StaticLayout$Builder.build frame, a TextView.makeSingleLayout/makeNewLayout/checkForRelayout frame, a TextView.setText frame, a main-looper Runnable (run() sitting directly on Handler.handleCallback), with no za.kilowatch.ultimatefilemanager frames 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 FileBrowserActivity during 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, FileBrowserActivity synchronously queried freeSpace and totalSpace on the main looper thread to populate the toolbar and TV header subtitle ("X free of Y"), invoking the native statvfs syscall 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 to Dispatchers.IO with lifecycle cancellation guards (storageSpaceJob), updating the UI headers smoothly once computed.
  • Storage Initialization & Collection Iterator ANR: Resolved an ANR ("Main thread blocked >5000ms") in FileBrowserActivity during 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 relaunching FileBrowserActivity, SafLocationRepository.getLocations performed synchronous contentResolver.persistedUriPermissions IPC calls and DocumentFile.fromTreeUri ContentProvider queries on the main thread, contending with concurrent background media and indexing workers. Persisted URI permission reconciliation is now offloaded to Dispatchers.IO, and SafTreeManager.hasTreePermissionForPath and FileBrowserActivity.onCreate fast-path standard internal storage (/storage/emulated/0) to bypass SAF permission queries completely. In addition, AnrWatchdogThread filter 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.onCreate and onStartCommand during service startup on Android TV (ZTE OTT Xview+ AV1, SDK 30, app 1.9.8-GOOGLE). When TvServerForegroundService was created, it invoked UfmApplication.instance.ensurePairingServerRunning() on the main looper, which attempted to acquire a monitor lock on this (UfmApplication.instance) that was already held by the background ufm-pairing-init thread performing heavy AndroidKeyStore ECDSA key generation, SSLContext setup, and AES-GCM token decryption via SecureTokenStore under THREAD_PRIORITY_BACKGROUND CPU starvation. ensurePairingServerRunning() in TvServerForegroundService.onCreate and onStartCommand is now offloaded to a dedicated background daemon thread (ufm-tv-server-init), and PairingManager.hasPairedDevices() provides a lightweight check bypassing token decryption on the main thread. In addition, UfmApplication.pairingServer is marked @Volatile with a dedicated lock object (pairingServerLock), ensurePairingServerRunning() automatically dispatches to background if called from the main thread, and ufm-pairing-init priority reduction was removed to prevent startup CPU starvation.

Don't miss a new ultimate-file-manager-pro release

NewReleases is sending notifications on new releases.