Skip to content

rclone to 1.73 and ndk to 29, Internxt, Drime support#394

Open
thies2005 wants to merge 64 commits into
newhinton:masterfrom
thies2005:master
Open

rclone to 1.73 and ndk to 29, Internxt, Drime support#394
thies2005 wants to merge 64 commits into
newhinton:masterfrom
thies2005:master

Conversation

@thies2005

Copy link
Copy Markdown

Changes: * New Providers: * Added explicit support for Drime cloud storage. * Added support for Internxt decentralized cloud storage, including a new flow for handling Two-Factor Authentication (2FA). * UI Enhancements: * Updated transfer notifications to display real-time Upload and Download speeds. * Added session statistics to track total data Uploaded and Downloaded. * Documentation: * Updated README.md to reflect the newly supported providers. bumped rclone to 1.73 and ndk to 29

thies2005 and others added 30 commits February 2, 2026 23:45
Internxt requires interactive authentication to connect to their API
and retrieve a mnemonic during config. This change adds internxt to
the list of providers that use the OAuth-style ConfigCreate flow,
enabling proper authentication handling.
…logging

- Add internxt to OAuth-style providers list for interactive multi-step auth
- Internxt requires connecting to their API to get mnemonic and handle 2FA
- Add error logging to RemoteConfigHelper to capture rclone stderr on failure
- This helps debug authentication issues with new backends
- Add InternxtTwoFactorStep and InternxtTwoFactorAction to OauthHelper.java
- Shows dialog for 2FA code input, blocks until user enters code
- Add InternxtFinishStep to handle config completion
- Update ConfigCreate.kt to detect Internxt and use InteractiveRunner
- Pass provider type from DynamicRemoteConfigFragment to ConfigCreate
- Uses CountDownLatch for thread synchronization with UI dialog
- Process all rclone log lines for stats/progress, not just error/warning
- Notification now updates with transfer progress, speed, ETA during sync
- Speed indication was already implemented in StatusObject, just not being used
- Add signing config passwords for release builds
…agement

Implements proactive session healing for OAuth-enabled remotes (Internxt, etc.)

Phase 1 - Go Backend:
- Replace boolean authFailed with stateful authFailCount/nextAuthAllowed
- Add TOTP time window retries (T, T-1, T+1) for clock skew handling
- Implement exponential backoff: 1m, 5m, 15m, 1h, 1h with ±10% jitter
- Max 5 failures before requiring manual re-auth
- Reset authFailCount to 0 on successful operations

Phase 2 - Android WorkManager:
- Create SessionGuardianWorker for 8-hour periodic health checks
- Discover OAuth remotes via config dump (token/access_token/totp_secret)
- Lightweight health probe using rclone lsd --max-depth 1
- Silent healing via Go backend during probe
- Add SessionGuardianScheduler with network/battery constraints

Phase 3 - Android UI:
- Add "Re-authenticate" menu item to remote options
- Manual re-auth triggers existing RemoteConfig with CONFIG_EDIT_TARGET
- Leverages existing OAuth flow and Internxt 2FA UI

Phase 4 - Failsafe Notifications:
- Detect "auth exceeded max retries" error from Go backend
- Show notification with deep-link to Remotes view
- Added checkAndNotifyAuthError() helper for easy integration

This moves from "Hard Fail" to "Resilient Background Healing" model,
preventing silent session drops after 2FA failures or clock skew.

Resolves: Sessions dropping silently for 2FA-enabled remotes after few days
- Enable CGO_ENABLED=1 for Android ARM builds (was disabled)
- Add CC environment variable pointing to NDK cross-compilers
- Support ARM64 Linux as build host (os.arch detection)
- Fixes cross-compilation on ARM64 build machines

Note: This enables native builds on ARM64 Linux hosts when using
the Android NDK with x86_64 toolchains via QEMU or native compilers.
- Skip cross-compiler (CC env var) on Windows builds
- Let Go handle CGO natively on Windows (Go 1.25.6 supports this)
- Only use cross-compiler when available (Linux/Mac builds)

Fixes build failures on Windows AMD64 systems where getCC() returned null
and caused Go build to fail with empty CC environment variable.

Tested on: Windows 10 (amd64) / AMD Ryzen 8845HS
- Document GitHub Actions workflow usage (already working)
- Provide multiple build options (GitHub Actions, MinGW, Docker, skip)
- Include download instructions for APK artifacts
- Explain current Session Guardian implementation status

This helps users on Windows build APKs using CI/CD workflow
- Complete rewrite of android.yml workflow
- Added detailed comments explaining Session Guardian features
- Documented each build step
- Added conditional uploads based on build success
- Included build summary with download instructions
- Added workflow_dispatch for manual triggering

This workflow builds all APK architectures including arm64-v8a
needed for Pixel 9 and other devices.
- Fix line 320: use mrand.Int63n instead of rand.Int63n (import alias)
- Fix line 400: rename offset to truncationOffset to avoid variable shadowing

These errors were preventing rclone compilation in GitHub Actions due to
CGO cross-compilation issues.
- Set CGO_ENABLED=0 to avoid cross-compilation issues
- Session Guardian code uses only standard Go libraries, no CGO needed
- Fixes build failures on GitHub Actions due to missing standard library packages
- Re-enabled CGO (required for Android ARM builds)
- Added go install std step before rclone build to prepare Android std lib
- This should resolve 'could not import' errors when cross-compiling
- Cleaned up duplicate steps in GitHub Actions workflow
- Removed duplicate/corrupted section from buildRclone function
- File had duplicate lines from previous edit
- Now build.gradle has correct structure with std lib build step
- Removed 'android' tag from Go build command
- The android tag was causing import issues with CGO cross-compilation
- Keeping 'noselfupdate' tag to exclude update checking
- This should allow Go to find the standard library packages
- Reverted to CGO_ENABLED=0 (no CGO required for GitHub Actions)
- Removed CC compiler environment variable
- Restored 'android' build tag
- This matches the working configuration before Session Guardian changes
- CGO changes were intended for ARM64 Linux hosts, not CI/CD
- Changed GOOS from 'android' to 'linux' to bypass CGO requirement
- Removed 'android' build tag since we're targeting linux now
- This allows building without CGO, avoiding standard library issues
- Linux ARM binaries should still work on Android (Android is Linux-based)
- Changed Go version from 1.24 to 1.19.8
- This matches the configuration that was working before Session Guardian
- Go 1.24 may have compatibility issues with cross-compilation
- Using proven Go version that was successfully building earlier
- Added build-windows.ps1 - PowerShell build script with menu
- Added build.bat - Simple batch file launcher
- Added WINDOWS_BUILD_GUIDE.md - Detailed build instructions
- Added BUILD_CHECKLIST.md - Environment verification checklist

These files help users build Session Guardian APK locally on Windows
(Ryzen 8845HS) to work around GitHub Actions CGO issues.
- Removed incorrect -x flags (were excluding tasks instead of running)
- Changed to use module-specific task :app:assembleOssDebugArm64-v8a
- Added proper error checking with LASTEXITCODE
- Shows BUILD FAILED message when build exits with error
- Added safety check to verify APK was actually created

This fixes the issue where ARM64 build was failing due to incorrect Gradle syntax.
thies2005 and others added 6 commits April 23, 2026 12:06
- Migrate package namespace from de.felixnuesse.extract to de.schuelken.cloudbridge
- Update display names across localized string resources
- Generate and apply padded launcher icons from new CloudBridge logo
- Adjust theme colors for new branding
- Update GitHub download URL for automatic updates
- Clean up outdated badges and standardize version bumping rules
…oudBridge

This release completes the transformation from Round Sync to CloudBridge.

Key Changes:
- App Identity: Renamed application ID to de.schuelken.cloudbridge and built as CloudBridge 1.0.0 (versionCode 10).
- Package Structure: Fully migrated and renamed the java/kotlin packages from de.felixnuesse.extract to de.schuelken.cloudbridge.
- Visual Assets: Regenerated and integrated all new Android launcher icons and adaptive foregrounds, fully padded for proper rendering inside circular masks. Updated colors.xml to the new blueish primary palette.
- UI Strings & Localization: Rewrote all legacy project references to CloudBridge across English, German, Catalan, and Simplified Chinese localizations.
- Documentation & Build Pipelines: Cleaned up README.md badges, specified new GitHub source URLs (thies2005/CloudBridge) for automatic app updates, and set up the documentation domain to cloudbridge.schuelken.uk.
…custom DNS resolver

- Switch rclone source to thies2005/rclone fork which includes Android DNS override
- Add getDnsServers() to Rclone.java and RcloneRcd.java using ConnectivityManager
- Pass detected DNS servers via RCLONE_DNS_SERVERS env var to rclone process
- Falls back to Google DNS (8.8.8.8, 8.8.4.4) if detection fails
Property names were renamed from de.felixnuesse.extract.* to
de.schuelken.cloudbridge.* but the CI workflow still grepped for the
old names, causing NDK version to be empty.
- Switch from debug to release builds with the in-repo keystore
- Auto-tag as v<version>-beta.<short-sha> on every master push
- Attach all ABI APKs to a prerelease GitHub release
- Clean up old beta releases before creating new one
@newhinton

Copy link
Copy Markdown
Owner

Hi!
Are you still willing to fork your changes to this branch?
What are your mid-term goals with your fork?

SessionGuardianWorker was treating ANY non-zero rclone exit code as a
session expiration, including DNS/network failures. This caused false
'Session expired' notifications when the device had intermittent
connectivity (e.g. DNS resolver not ready on wake).

Changes:
- Rclone.listDirectories() now returns DirectoryProbeResult with both
  exit code and stderr output
- DirectoryProbeResult.isNetworkError() detects transient network issues
  (DNS failure, connection refused, timeout, etc.)
- SessionGuardianWorker skips notification for network errors, only
  notifies on genuine auth/session failures
@thies2005

Copy link
Copy Markdown
Author

Hi,

When I first found your app I was very happy to finally find a good and reliable rclone syncing for my media and different backups. Then I saw that it hadn't been updated in a while, and with AI I updated the rclone and opened this merge request.

As some time passed, I needed rclone to re-auth Internxt on my server so I could reliably run my Immich server with it while still using 2FA. So I decided to fork rclone/rclone and implement the changes there, so I could then use my custom fork on the server and in the app. Due to the license, I saw I needed to change the name and so on of the app, and I started doing so but haven't migrated it completely. I am a medical student and don't have too much time. I guess when merging you don't want the custom rclone ? Also, I wanted to ask if I can publish my app on the Play Store for easier access? I would credit you and the previous fork and link to the source code. What do you think?
Greetings from Munich

@newhinton

Copy link
Copy Markdown
Owner

Ah, the license is more for "republishing". If you use the app only for yourself, even a fork, you do not need to change the name. That part is only if you "publish" it officialy, like on github releases or google play.

The reason for the long time without updates is twofold:

  1. The app is stable "enough" for most people
  2. The code is so outdated and convoluted, a rewrite is nessessary for many improvements.

But a rewrite is extremely time consuming.

Regarding the appstore: i won't stop you.
However: if you only maintain the fork for yourself, i would advise againts it:

  1. Google takes fees for the developer account
  2. If you put it out there, you will probably have to deal with issues&complaints on a more active basis
  3. Releasing is not that easy
  4. Google sucks. See: https://keepandroidopen.com/

What i instead suggest you to do is to either use fdroid (which is more complicated) or the far easier variant by using obtainium and there you add your own fork from github. (Note: if that is your goal, the name-change stuff also does not apply. its really just if you want to long-term maintain your own fork)
Using obtainium is the least effort way to quickly get updates on your device.

Now to this pr:
You did mix multiple featues/fixes together, especially with all the name-changes and the likes. This makes it basically impossible to review. Part of that is due to me not regularly checking PR's but it is still a problem. There is also the problem with using AI. While i am not vehemently opposed to people using it, i do need to know which parts are ai-assisted and which are not. I am not sure if this can move forward in the current state.

thies2005 and others added 3 commits June 5, 2026 08:38
…iles

- Add project-specific agent guidelines (AGENTS.md) covering core rules,
  rclone upgradeability policy, build/verification commands, and conventions.
- Remove obsolete build logs, patches, and temporary planning docs that
  are not relevant to the project going forward.
@thies2005

Copy link
Copy Markdown
Author

Hi,
Sorry for the late reply, we're in exam season and I forgot about this.
To be transparent: yes, I used AI heavily throughout this. The goal was getting Internxt + 2FA working reliably, which this PR never fully accomplished anyway, it kept getting unauthenticated after a few days. I ended up forking rclone directly (thies2005/rclone) and implementing the changes there natively — that's what I'm now using on my server and in the app. So feel free to cherry-pick whatever is useful, but I don't think this initial pull request advances the project.
Regarding distribution: I understand the Play Store concerns, but accessibility for me means non-technical users can find and install the app without knowing what Obtainium is. I will try fixing the app up and then rely on GitHub Releases for now, and the Play Store once things are stable enough or I have the time. F-Droid/Obtainium I will also add alongside. If you have any concerns please reach out.
Greetings from Munich

thies2005 and others added 16 commits June 18, 2026 19:34
…grity)

Phase 1 (critical bugs + security + build unblocking):
- RC-9/11/12/17/18: add return after finish(), null-guard rclone stdout/config
- RC-23/25: null-check Thumbnails remote; fix inverted getDisplayNameCompat
- RC-2: allowBackup=false; RC-4: unexport app-private components
- RC-5: serve() requires creds for remote bind; ServeDialog enforces non-empty
- RC-6/7/8: fix dependencies.yml globs/prefix, SDK 34->35, pin rclone ref (SHA)
- Guard pre-existing NewApi (destroyForcibly/waitFor) for API < 26 in InternxtReauth

Phase 2 (correctness + resource hygiene):
- RC-13: scoped WorkManager cancellation (replace cancelAllWork) across 3 managers
- RC-22: UpdateWorker -> CoroutineWorker, returns real result
- RC-15/16: RcdService thread-safety (final lock, volatile bool, sync spawn)
- RC-10/20/26: drop leaked probe process, guard exitValue, try-with-resources
- RC-21: rewrite update download (GitHub metadata, SHA-256/size verify, WorkManager)
- RC-27: remove duplicate FileProvider
- RC-30: VCP remotes/remotes dedup + main-thread-safe getDocumentType; real upload FileItem
- RC-24: Log2File rotation 10GB->10MB + null ext-dir guard
- RC-3: add credential-storage ADR (design gate)

Phase 0 (RC-1 signing key rotation) intentionally SKIPPED to preserve the
existing GitHub release signature, per constraint.

Verification: ./gradlew testOssDebugUnitTest + lint + assembleOssDebug all green.

Checkpoint: pushing to resume Phase 3 (UI/UX) and later phases on a cloud instance.
Phase 3 — UI/UX, Accessibility & Dark-Mode:
- RC-34: add values-night/colors.xml + values-night-v31 overrides so the
  convenience color aliases (cardColor, iconTint, dividerColor, text*, fabOverlay)
  resolve to dark tokens instead of light. SecondaryCardStyle no longer uses the
  M3-1.2-only colorSurfaceBright (swapped to colorSurfaceVariant).
- RC-33: actionBarSize 12dp -> 56dp (typo). MainViewToolbar contrast fixed
  (colorOnSecondary -> colorOnPrimary); overflow/dialog parents repointed to M3.
- UI-028: wire core-splashscreen (Theme.App.Starting + installSplashScreen in
  MainActivity).
- RC-32: extract every hardcoded UI literal to @string (Run on Failure/Success,
  "Switch preference" placeholder, task id/path placeholders -> tools:text,
  7 Toast/setTitle literals).
- RC-40: add Locale.ROOT to all 14 DefaultLocale toLowerCase() sites.
- RC-35/36: contentDescription on interactive icons, importantForAccessibility
  on decorative settings icons, labelFor on 8 EditTexts, paddingStart/End,
  48dp tap targets, SwitchPreference -> SwitchPreferenceCompat (12 sites).
- RC-37: delete now shows an undo Snackbar; the destructive WorkManager enqueue
  is deferred until the undo window elapses.
- RC-38: cache rclone config-dump JSON in Rclone.getRemotes() (invalidated on
  config()/deleteRemote()); pin state still re-applied fresh each call.
- UI-020/021: fragment_logs empty state; FileExplorerFragment keeps the current
  listing on a transient rclone error instead of blanking.

Phase 4 — Architecture & Tech-Debt:
- RC-28: add RemoteItem INTERNXT/DRIME types + getTypeFromString cases (were
  falling through to -1 / generic icon and colliding in equals/hashCode); add
  RemoteItemTest covering type resolution and distinctness.
- 4B: delete dead rclone/patches/internxt/ Go source (fork already contains it),
  remove no-op fileTree('libs') + dead VERSION_11 ext, drop commented Intent
  blocks and literal-"TAG" logs, fix SyncService "SYNC_SERCVICE" typo.
- RC-31: align okhttp logging-interceptor to 4.12.0; remove unused Glide
  annotationProcessor (no @GlideModule). NOTE: Jackson, legacy-support-v4 and
  streamsupport are KEPT — they are actually imported (the prior audit verdict
  that streamsupport was unused was wrong: java9.util.* is used in 3 files).
- 4D: add kotlinx-coroutines-android + lifecycle-runtime-ktx infrastructure and
  migrate MarkdownView.LoadMarkdownAsset off AsyncTask (executor + View.post).
  The remaining ~26 AsyncTask / 3 IntentService migrations are intentionally
  staged file-by-file per the plan (each its own PR); doing them blind in one
  commit without a compiler was deemed too risky.

Phase 5 — CI, Polish & Docs:
- BUILD-008/009: SHA-pin every uses: across all 4 workflows; replace the
  compromised tj-actions/changed-files@v44 with a post-fix v46 SHA and
  fabasoad/translation-action@main with a pinned tag; add a PR-gated
  ./gradlew testOssDebugUnitTest step to lint.yml.
- BUILD-019: rclone/build.gradle Go-version check now throws GradleException
  instead of logger.error.
- BUILD-021..024, CQ-010/011: fix Go version (1.20/1.19.8 -> 1.25), license URL,
  assembleDebug -> assembleOssDebug, drop fictional usePrebuiltRclone section,
  APK glob roundsync_v -> cloudbridge_v, AGENTS.md CI description (release, not
  debug).
- CQ-021: rename BootReciever/TriggerReciever/ClearReportBroadcastReciever ->
  *Receiver (classes, manifest, imports, Intent refs).

Deferred (documented): full CardView -> MaterialCardView migration (cosmetic),
ListAdapter+DiffUtil migration, edge-to-edge, tablet layouts, and the remaining
AsyncTask -> coroutines migrations — all lower-risk to land with CI feedback.

No build toolchain was available locally; verified via static checks (XML/YAML
parse, import/reference consistency, subagent code review) and CI is the gate.
The Phase 3-5 commit was authored without a build toolchain ('verified via
static checks'). Three independently-fatal build errors slipped through:

1. Duplicate string resources: values/strings.xml redefined internxt_2fa_title
   and internxt_2fa_message (RC-32 extraction collided with the pre-existing
   canonical strings already referenced by OauthHelper/InternxtReauth/ConfigCreate).
   -> mergeOssDebugResources: 'Found item more than one time'. Removed the dupes.

2. Corrupted ConstraintLayout attribute: an a11y edit in fragment_log_item.xml
   mangled the adjacent attribute layout_constraintTop_toTopOf into the invalid
   layout_constraintTopToTopOf (dropped underscore).
   -> AAPT: 'attribute layout_constraintTopToTopOf not found'. Restored the name.

3. Over-strict Go-version gate: BUILD-019 made checkoutRclone throw on mismatch,
   but the check used contains("1.25.0") which rejects compatible patches like
   1.25.11. -> Replaced with a proper major.minor comparison that accepts any
   patch of the required minor and any newer minor, while still failing fast on
   an genuinely incompatible toolchain (BUILD-019 intent preserved).

Verification: ./gradlew testOssDebugUnitTest, lint -x :rclone:buildAll, and
assembleOssDebug all BUILD SUCCESSFUL after these fixes (5 ABI APKs produced).
Release signing key rotation (P0): the committed roundsync.keystore plus the
hardcoded 'android'/'android' passwords in app/build.gradle compromised the
signing identity. Generated a new RSA-4096 key (CN=CloudBridge Release, 25y),
moved credentials into a git-ignored keystore.properties (local) / CB_* env
vars (CI), removed the old keystore from the repo, and added .gitignore rules.
android.yml now decodes the keystore from GitHub Secrets before signing.
NOTE: existing installs signed with the old key cannot be updated in place
(signature mismatch) and need a one-time reinstall.

Correctness fixes:
- UpdateDownloadWorker.sha256(): signed-Byte sign-extension made every digest
  wrong, so in-app updates with a published digest never verified. Mask to
  unsigned (it.toInt() and 0xFF).
- Rclone getRemotes() cache: now volatile and validated against the rclone.conf
  mtime/length on every read, so per-instance caches self-invalidate when
  another Rclone instance (e.g. a config dialog) mutates the config; also fixes
  the cross-thread visibility race. synchronized the fetch to avoid duplicate
  rclone processes.
- UpdateUserchoiceReceiver: enqueueUniqueWork(KEEP) so multiple Download taps
  no longer run concurrent workers writing the same APK.
- RcdService.waitOnline(): stop using a synthetic NullPointerException for
  control flow; real NPEs inside isOnline() are no longer masked as 'not online'.
- EphemeralWorker: recycle the Parcel on the read paths (matches the write side).
- MarkdownView: ioExecutor threads are now daemons (no per-View thread leak).

Security fixes:
- UpdateUserchoiceReceiver + SyncService set exported=false (no callers relied
  on them being exported; closes an arbitrary-sync-trigger surface).
- SafDAVServer: stop logging the local Authorization header on the
  not-implemented path.

Lint: Locale.ROOT for stderr lowercasing; ellipsis char in
internxt_reauth_progress.

Verification: testOssDebugUnitTest, lint, assembleOssDebug, assembleOssRelease
all green; release APK verified signed with the new key.
Upstream iBotPeaches/Apktool removed scripts/linux/apktool from master,
so the wget 404'd and the non-FOSS library scan never ran. Inline a minimal
wrapper that invokes apktool.jar from its own directory instead of fetching
the fragile external script.
Targeting SDK 35 enforces edge-to-edge, so toolbar/content rendered
behind the status bar (text invisible). Explicitly opt out per activity
via WindowCompat.setDecorFitsSystemWindows(window, true), restoring the
pre-35 fit-to-system-bars behavior. OnboardingActivity is left on
edge-to-edge by design.
Replace the hardcoded rclone --transfers 1 with a configurable value.
Adds a ListPreference (1/2/4/8, default 1) under Settings > Background
Work, read by Rclone for sync/download/upload. Persisted through the
JSON settings backup/restore.
setDecorFitsSystemWindows(true) per activity was not reliably keeping
content below the status bar (e.g. the RemoteConfig search bar still sat
under the status line). Add android:windowOptOutEdgeToEdgeEnforcement
to AppTheme (light/night) and the splash Theme.App.Starting so every
window is created with the legacy fit-to-system-bars behavior. The
attribute is API 35+ only and a no-op below that (tools:ignore=NewApi).
Update rCloneRef to the latest thies2005/rclone master and align the
informational rCloneVersion. Verified to cross-compile for all ABIs.
Beta APKs all shared versionCode 20 / versionName 1.0.1, so they were
never real updates and installs stalled. CI now derives versionCode from
the git commit count (*10; ABI offsets use 6-9) and versionName as
<base>-beta.<short-sha>, passed to Gradle via CB_VERSION_CODE /
CB_VERSION_NAME env vars (matching the existing RCX_BUILD_CLI pattern).

Also fix the delete-previous-betas step: it grabbed the release title's
first word ("Beta") instead of the tag, so old betas accumulated and the
newest no longer sorted to the top. Now lists tags via --json and deletes
by the real tag, keeping only the latest beta.
- Add optional per-task --transfers override (DB v7 migration adding
  task_transfers column, Task.transfers field, TaskActivity spinner with
  'Use global setting'/1/2/4/8) that falls back to the global pref when
  unset. Plumb SyncWorker -> Rclone.sync() 8-arg overload.
- Fix silent-success bug for unsupported sync directions: SyncWorker now
  validates the direction and reports a clear UNSUPPORTED_DIRECTION
  failure instead of treating a null rclone process as success. Affects
  legacy/imported bisync (direction 5/6) tasks.
actions/checkout defaults to a shallow depth-1 clone, so
'git rev-list --count HEAD' returned 1 and every beta APK was built
with versionCode 10. Android then refuses the update because the new
APK is not newer than the installed one. Set fetch-depth: '0' so the
full commit count (e.g. 1604 -> versionCode 16040) is used, making
each beta a real, installable update.
Implements the transmission-speed audit findings (P0-P2):

- Raise default --transfers from 1 to 4 (rclone upstream default)
- Hold PARTIAL_WAKE_LOCK + high-perf WifiLock for the duration of
  transfers (EphemeralWorker, SyncWorker, RcdService) so the device
  does not stall in Doze with the screen off; add WAKE_LOCK perm
- Throttle EphemeralWorker notification rebuilds to >=500ms and only
  when content changed (previously rebuilt on every stderr line)
- Add CloudBridgeApp Configuration.Provider (setMaxSchedulerLimit=50)
  and disable the default WorkManager initializer
- Bump safdav SAF write buffer 1KB->64KB and write directly through
  ContentResolver (DocumentsContractAccess.writeFile)
- Bump VirtualContentProvider pipe buffer 4KB->128KB
- Add --transfers/--buffer-size/--multi-thread-streams and
  --vfs-read-chunk-size* flags to serve and rcd
- Move DownloadAndOpen AsyncTask off the shared serial executor
- Speed up share-intent staging copy (64KB + BufferedOutputStream)
- Fix VirtualContentProvider MaxWait reporting success before rcd
  jobs complete (await returns completion state; longer timeouts)
- Parallelize rcd job-status polling over a small executor with
  synchronized access to lastStatus/jobsHandlers
TransferLocks.acquire used a multi-catch on SecurityException and
RuntimeException, which is illegal (SecurityException subclasses
RuntimeException) and broke compilation. Collapse to RuntimeException.

Also align the 'transfers' default in SharedPreferencesBackup from
'1' to '4' so all call sites match the new rclone upstream default
introduced in the perf commit.
The 'Session expired' notification previously launched MainActivity
generically and required the user to find and long-press the remote to
re-authenticate. It now deep-links into the InternxtReauth flow for the
named remote.

- AppErrorNotificationManager: notification intent now carries the
  MAIN_ACTIVITY_START_REAUTH action + remote name; request code varies
  per remote with FLAG_UPDATE_CURRENT so distinct remotes don't alias.
- MainActivity: add onNewIntent (required by singleTop launch mode so a
  foreground tap is not dropped) and a handleReauthIntent branch that
  resolves the remote and launches InternxtReauth directly.
- InternxtReauth: capture secret-filtered rclone stderr and surface it
  in the failure toast instead of a generic 'error creating remote'.
- Bump rCloneRef to the fork commit that restores the auth circuit
  breaker and TOTP clock-skew retry (see rclone fork 94f543c9d).
Adds remote-to-remote sync (direction 7) and copy (direction 8) so tasks
can transfer data between two cloud remotes without a local hop. rclone
performs a server-side copy where the backend pair supports it.

- SyncDirectionObject: new SYNC_REMOTE_TO_REMOTE/COPY_REMOTE_TO_REMOTE
  constants and explicit spinner<->direction mapping (the spinner array
  is sparse, so position can't be derived from the constant value).
- Task: add remoteId2/remoteType2/remotePath2 destination fields plus
  matching DB columns (DatabaseHandler/DatabaseInfo schema bump).
- TaskActivity: destination-remote UI card shown only for cloud-to-cloud
  directions, with validation rejecting identical source/dest paths.
- Rclone.sync: new overload taking a second remote; routes local<->remote
  vs remote-to-remote based on the direction.
- SyncWorker/TasksRecyclerViewAdapter: plumb the new directions through.
- gitignore: ignore stray node_modules/, package*.json and .zcode/.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants