ADFA-4640: rework the Usage server-log console for real terminal-style scrolling#176
Merged
Merged
Conversation
…e scrolling Replace the plain TextView (force-scrolled to the bottom on every line, decorative-only scrollbar, no follow/tail state) with a RecyclerView-backed ServerLogView that: - keeps your read position while the log grows (sticky), - follows the newest line (tail, like less +F) only when at the bottom, with a 'jump to newest' button to re-attach after scrolling up, - exposes a draggable fast-scroll thumb to move start<->end quickly, - caps the buffer (ring buffer, 8000 lines) so long streams stay smooth. UsageFragment drives it via append()/setContent()/clear()/getContent(); the old scrollToBottom() and the TextView movement/selectable/touch hacks are removed. New string log_jump_latest localized across all 33 locales. Adds explicit androidx.recyclerview dependency.
…tateListDrawable RecyclerView's fast scroller casts the fastScroll*ThumbDrawable to StateListDrawable; the previous <shape> compiled to a GradientDrawable, so inflating the log RecyclerView threw ClassCastException (GradientDrawable -> StateListDrawable) and crashed the Usage tab. Use dedicated <selector> (StateListDrawable) drawables with an intrinsic size for the fast-scroll thumb and track; drop the now-unused scrollbar_track shape.
…persistence) The log lived only in the transient UsageFragment view, and the install/Ansible receiver was tied to DeployFragment's lifecycle, so: (a) while Usage was offscreen addToLog was a no-op and lines were dropped, and (b) hiding the console re-read the watchdog blackbox and setContent-wiped the live install log. Ansible output — the most important record of Module Management — was being lost. Introduce LogRepository: a process-scoped, observable, bounded single source of truth. Every producer funnels into it (timestamped centrally): - MainActivity.addToLog and UsageFragment.addToLog -> LogRepository.append - InstallService.log() -> LogRepository.append directly (same process), so Ansible/ install output is captured regardless of which fragment/tab is on screen - removed DeployFragment's install-log BroadcastReceiver (its only job was to forward to addToLog; now redundant) UsageFragment observes LogRepository (addListener + render snapshot in onResume, removeListener in onPause) so the console updates live and survives tab switches / hide-show. handleLogToggle no longer setContent-wipes from the blackbox file (it now renders the LogRepository snapshot and reads the file only for the rapid-growth warning + size). Reset clears the repository (the source of truth).
…ollbar; fix follow The AndroidX fast-scroller plus the native scrollbars=vertical rendered TWO bars, the fast-scroll thumb looked split, was hard to grab, and had no tap-to-jump. And the follow state detached on programmatic scrolls, so the tail 'stuck' mid-list. - Drop android:scrollbars and app:fastScroll* from the RecyclerView (removes the double bar and the split-thumb artifact); delete the now-unused fast_scroll_* drawables. - Add a custom scrollbar (track + thumb) in ServerLogView: tap anywhere on the track to jump there and drag to move across thousands of lines (maps the touch fraction to an item index via scrollToPositionWithOffset). The thumb is sized/positioned from the RecyclerView scroll metrics and only shown when the content overflows. - Follow fix: only a user-driven scroll (state != IDLE) detaches the tail; programmatic appends/jumps are instant and keep it pinned. 'At bottom' now uses canScrollVertically.
… across restarts LogRepository was in-memory only, so the log survived tab switches and hide/show but not a process kill. Mirror the buffer to a dedicated file (server_log.txt) with a debounced background write, and reload it on process start (IIABApplication.init), so the Module Management / Ansible log is durable. Kept separate from the watchdog blackbox (watchdog_heartbeat_log.txt): LogRepository does not broadcast, so there is no feedback loop with IIABWatchdog. The file is bounded by the same MAX_LINES cap as the buffer (each flush rewrites the capped snapshot).
… reflow) The default RecyclerView ItemAnimator animated every notifyItemInserted, so a burst of streamed lines plus scrollToPosition on jump-to-newest produced a chaotic 'sea of letters' reflow. A streaming log should not animate: setItemAnimator(null) (and setHasFixedSize(true), since the console is a fixed 250dp box) makes appends and jumps render cleanly and cheaper.
…o-newest reflow)" This reverts commit 710fa4f.
…t the watchdog blackbox updateLogSizeUI now reports LogRepository's persisted file size via a reusable LogManager.formatSize(context, bytes) helper, so the 'Size' figure matches what the console actually shows/persists.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Replaces the Usage-tab server-log
TextView(which force-scrolled to the bottom on every line, had a decorative-only scrollbar, and no follow/tail state) with aRecyclerView-backedServerLogView.Behavior (the three requested)
less +F): auto-sticks to the newest line only when the viewport is at the bottom; scrolling up detaches; a "↓ Newest" button (shown only when detached) re-attaches and jumps to the end.Files
ServerLogView(compound view) +view_server_log.xml,item_log_line.xml,scrollbar_track.xml.fragment_usage.xml:connection_logswappedTextView→ServerLogView(same id).UsageFragment: drives it viaappend()/setContent()/clear()/getContent(); removedscrollToBottom()and the TextView movement/selectable/touch hacks; dropped now-unused imports.build.gradle: explicitandroidx.recyclerviewdependency.log_jump_latestlocalized across all 33 locales.Verify (device)
Relates to ADFA-1028.