Skip to content

Optimize NetToggle Root/Shizuku handling and QS tile performance - #1

Merged
Dhangofa merged 10 commits into
mainfrom
dev
Jul 27, 2026
Merged

Optimize NetToggle Root/Shizuku handling and QS tile performance#1
Dhangofa merged 10 commits into
mainfrom
dev

Conversation

@Dhangofa

Copy link
Copy Markdown
Owner

Summary

This PR merges the dev branch improvements into main to make NetToggle safer, lighter, and more reliable for Root/Shizuku based network mode switching.

The update improves execution mode handling, Root/Shizuku permission flow, QS tile state accuracy, command execution safety, icon caching, SIM handling, and lifecycle cleanup.

MainActivity changes

  • Added explicit execution mode constants:
    • MODE_NONE
    • MODE_ROOT
    • MODE_SHIZUKU
  • Changed fresh install behavior so no execution mode is selected by default.
  • Removed old behavior that automatically selected Root mode on first launch.
  • Added Root permission check when Root mode is selected or restored.
  • Re-checks Root permission when saved Root mode is opened again.
  • Changed Shizuku permission flow so permission is requested only when user selects Shizuku mode.
  • Saved Shizuku mode now checks status without automatically triggering the permission popup.
  • Guarded Shizuku binder callbacks so they only update UI when:
    • Activity is still alive
    • Shizuku mode is currently selected
  • Added Activity destroyed flag to prevent stale UI updates after MainActivity closes.
  • Tracked Root permission check thread and process.
  • Destroyed active Root check process during onDestroy().
  • Interrupted active Root check thread during Activity cleanup.
  • Preserved Shizuku listener cleanup in onDestroy().
  • Prevented stale Root permission results from overwriting current selected mode.

NetworkTileService changes

  • Added explicit execution mode constants and network state constants.
  • Added STATE_UNKNOWN to avoid assuming 4G Only on first install.
  • Updated QS tile startup to show cached state instead of blindly assuming mode.
  • Cached generated QS tile icons to avoid recreating Bitmap/Icon objects on every tile update.
  • Added unknown/setup tile state handling.
  • Refactored network mode cycling into getNextState().
  • Refactored binary mode selection into getBinaryForState().
  • Changed network command execution to return success/failure.
  • Updated tile state only after successful command execution.
  • Preserved previous tile state when command execution fails.
  • Moved Root/Shizuku command execution off the QS tile click path using a background executor.
  • Added immediate "Switching..." tile feedback while command is running.
  • Added main-thread Handler updates for Android 7+ compatibility.
  • Added AtomicBoolean guard to prevent rapid repeated taps from queueing duplicate commands.
  • Replaced hardcoded SIM handling with active data SIM detection using multi_sim_data_call.
  • Mapped active data SIM index to phone command index:
    • multi_sim_data_call=1 -> cmd phone -s 0
    • multi_sim_data_call=2 -> cmd phone -s 1
  • Reads current mode from preferred_network_mode1/2 using legacy mode IDs.
  • Added legacy mode ID mapping:
    • 11 -> 4G Only
    • 23 -> 5G Only
    • 33 -> Preferred 5G
    • 9 -> Preferred 4G
  • Avoided running real network mode checks on every QS panel open.
  • Real current mode is queried only when cached tile state is unknown.
  • Cached Shizuku newProcess reflection Method to avoid repeated reflection lookup.
  • Cached regex Pattern used for legacy mode parsing.
  • Removed unused stderr storage from command result handling.
  • Added Root/Shizuku process cleanup after command execution.

Performance impact

  • Reduces CPU overhead during QS panel refresh.
  • Avoids unnecessary shell/Shizuku command execution on every QS pull-down.
  • Avoids repeated bitmap/icon generation.
  • Prevents duplicate toggle commands from rapid taps.
  • Avoids blocking the QS tile callback thread.
  • Keeps tile state updates dependent on actual command success.

Reliability impact

  • Fresh install no longer assumes Root mode or 4G state.
  • Root/Shizuku mode selection is safer and more explicit.
  • Tile no longer shows a changed state when command execution fails.
  • Active data SIM handling is improved.
  • MainActivity and TileService lifecycle cleanup is safer.
  • Android 7+ compatibility is improved by avoiding API 28-only main executor usage.

Testing

Tested expected flows:

  • Fresh install starts with no selected execution mode.
  • Root mode checks Root access before reporting authorized state.
  • Shizuku mode requests permission only after user selection.
  • Saved Root/Shizuku modes restore safely.
  • QS tile toggles modes asynchronously.
  • QS tile shows "Switching..." while command is running.
  • Failed command does not update cached tile state.
  • Rapid repeated tile taps do not queue duplicate commands.
  • Current mode detection works from legacy preferred_network_mode1/2 values.

Dhangofa added 10 commits July 27, 2026 17:28
- Added MODE_NONE as default execution mode to avoid auto-selecting Root or Shizuku on fresh install.
- Updated first-launch behavior to show setup prompt instead of assuming Root mode.
- Added Root permission check using `su -c id` when Root mode is selected or restored.
- Re-check Root permission on app open if Root mode was previously saved.
- Changed Shizuku flow so permission is requested only when user manually selects Shizuku mode.
- For saved Shizuku mode, only check current Shizuku status without triggering permission popup.
- Added Shizuku binder received/dead/result listeners with current-mode validation.
- Prevented Shizuku callbacks from overwriting Root mode status.
- Prevented stale Root permission check result from overwriting UI if user switches mode during check.
- Wrapped Shizuku permission checks in try/catch for safer binder failure handling.
- Removed listener references in onDestroy to avoid memory leaks.
- Added explicit execution mode constants for none, root, and Shizuku.
- Added explicit network state constants including STATE_UNKNOWN.
- Updated tile startup to avoid assuming 4G Only when no cached state exists.
- Added unknown/unavailable tile state for unconfigured mode.
- Added cached QS tile icons to avoid regenerating bitmap icons on every tile update.
- Refactored state cycling into getNextState().
- Refactored state-to-bitmask selection into getBinaryForState().
- Prevented tile click from running when no execution mode is selected.
- Updated applyNetworkMode() to use execution mode constants instead of defaulting to Root.
- Changed applyNetworkMode() to return success or failure.
- Updated QS tile click flow to save and display the next state only after successful command execution.
- Added separate Root and Shizuku command runners.
- Simplified Root execution using `su -c`.
- Added exit code checks for both Root and Shizuku command execution.
- Prevented tile state from changing visually when command execution fails.
- Preserved previous tile state on failed toggle attempt.
- Removed old DataOutputStream-based Root command flow.
- Added default data subscription lookup using SubscriptionManager.
- Replaced hardcoded `-s 0` with the current default data subscription ID.
- Added invalid subscription handling using SubscriptionManager.INVALID_SUBSCRIPTION_ID.
- Prevented network mode command execution when no valid data subscription is available.
- Improved dual-SIM compatibility by targeting the active/default data SIM instead of assuming subscription 0.
- Kept existing binary allowed-network-type values because the command path supports them on tested devices.
- Added a single-thread executor for QS tile command execution.
- Moved root/Shizuku network mode command execution off the tile click callback path.
- Added immediate "Switching..." tile feedback while the command runs.
- Updated tile state on the main executor after command completion.
- Preserved previous tile state when command execution fails.
- Prevented the QS tile from blocking while waiting for root/Shizuku process completion.
- Replaced API 28+ getMainExecutor() usage with Handler and Looper.getMainLooper() for Android 7+ compatibility.
- Added AtomicBoolean switching guard to prevent rapid QS tile taps from queueing duplicate network mode commands.
- Kept network mode command execution on a background single-thread executor.
- Posted tile UI updates back to the main thread after command completion.
- Preserved previous tile state when command execution fails.
- Improved QS tile stability across Android 7 through newer Android versions.
- Avoided running real network mode checks on every QS panel open.
- Updated onStartListening() to show cached tile state immediately.
- Queried real current network mode only when cached state is unknown.
- Used `settings get global multi_sim_data_call` as the active data SIM source.
- Read current legacy network mode from `preferred_network_mode1/2` based on active data SIM.
- Mapped active data SIM index to phone command index for network mode updates.
  - multi_sim_data_call 1 -> cmd phone -s 0
  - multi_sim_data_call 2 -> cmd phone -s 1
- Removed SubscriptionManager-based data subscription lookup from tile command flow.
- Added legacy network mode ID mapping for tile state detection.
  - 11 -> 4G Only
  - 23 -> 5G Only
  - 33 -> Preferred 5G
  - 9 -> Preferred 4G
- Simplified current mode detection using preferred_network_mode legacy values.
- Cached Shizuku `newProcess` reflection Method to avoid repeated method lookup.
- Cached number regex Pattern used for legacy mode parsing.
- Simplified CommandResult by removing unused stderr storage.
- Added process cleanup in Root and Shizuku command execution paths.
- Kept command execution asynchronous and protected by duplicate-toggle guard.
- Reduced shell/Shizuku process usage during normal QS tile refresh.
- Added Activity destroyed flag to prevent stale UI updates after MainActivity closes.
- Tracked Root permission check thread and process.
- Destroyed active Root check process during onDestroy().
- Interrupted active Root check thread during Activity cleanup.
- Preserved Shizuku listener cleanup in onDestroy().
- Guarded Shizuku callbacks so they update UI only when Activity is alive and Shizuku mode is selected.
- Prevented stale Root permission check result from updating UI after Activity destruction.
@Dhangofa
Dhangofa merged commit 6c88955 into main Jul 27, 2026
1 check passed
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.

1 participant