From 789292dd8836631670035e2bbdd9326d89460c3b Mon Sep 17 00:00:00 2001
From: DK <117024745+Dhangofa@users.noreply.github.com>
Date: Sat, 15 Aug 2026 15:12:17 +0530
Subject: [PATCH 01/81] Update color palette for module cards and dynamic
themes
- Modified brand_primary_container from #EADDFF (purple tint) to #F3EDF7 (softer grayish-purple) for better contrast.
- Modified surface_background from #FAF8F5 (warm off-white) to #FDFBFF (cooler, crisper white) to modernize the app's base background.
- Removed unused status_success_text color since the success text color is currently handled inline or elsewhere in the UI.
- Added segmented_separator (#CAC4D0) to provide a dedicated color for the vertical divider lines between the segmented control options (like Root | Shizuku).
- Added a new Colorful Accents block containing accent_green, accent_orange, and accent_pink to provide vibrant tints for icons (like the developer person icon) and badges.
- Added a new Cycle Card Custom Tones block containing specific warm/orange color overrides (cycle_card_surface, cycle_segmented_selected, cycle_badge_bg, cycle_segmented_text_selected) to give the Quick Tile Cycle card its distinct warm visual identity.
- Added a new Exec Card Custom Tones block containing specific cool/blue color overrides (exec_accent, exec_card_surface, exec_segmented_selected, exec_segmented_text_selected) to give the Execution Mode card its distinct cool visual identity.
---
app/src/main/res/values/colors.xml | 23 ++++++++++++++++++++---
1 file changed, 20 insertions(+), 3 deletions(-)
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
index b71b1d3..262aeb9 100644
--- a/app/src/main/res/values/colors.xml
+++ b/app/src/main/res/values/colors.xml
@@ -2,11 +2,11 @@
#6750A4
- #EADDFF
+ #F3EDF7
#21005D
- #FAF8F5
+ #FDFBFF
#FFFFFF
#E7E0EC
#F3EDF7
@@ -18,7 +18,6 @@
#E8F5E9
- #1E4620
#FFEDEA
#8C1D18
@@ -26,8 +25,26 @@
#F4EFF4
+ #CAC4D0
#F3EDF7
#EADDFF
#21005D
#49454F
+
+
+ #198754
+ #D96509
+ #C2185B
+
+
+ #FFF8F3
+ #FFE0C2
+ #F3EDF7
+ #7A3600
+
+
+ #005B9F
+ #F2F8FF
+ #D6EBFF
+ #004275
From 8ba2e1a598fd807c1f7a3a55cf3d57e9a20dcb0a Mon Sep 17 00:00:00 2001
From: DK <117024745+Dhangofa@users.noreply.github.com>
Date: Sat, 15 Aug 2026 15:16:05 +0530
Subject: [PATCH 02/81] Update night color palette for module cards and pure
black themes
- Modified brand_primary_container from #4F378B (deep purple) to #23212A (dark grayish-purple) for a more muted, elegant dark mode contrast.
- Modified surface_background from #141218 (dark gray) to #000000 (pure black) to improve AMOLED screen battery efficiency and provide a higher contrast canvas.
- Modified card_surface from #211F26 to #141218 to match the darker overall theme.
- Modified card_border from #36343B to #2B2930 for subtler edge highlights on cards.
- Removed unused status_success_text color, as text color logic for status badges is handled efficiently via inline colors or specific badge shapes now.
- Added segmented_separator (#49454F) to provide a dedicated, visible divider line between segmented control tabs (like Root | Shizuku) in dark mode.
- Added a new Colorful Accents block (accent_green, accent_orange, accent_pink) to ensure UI icons and developer graphics remain vibrant against the dark backgrounds.
- Added a new Cycle Card Custom Tones block (cycle_card_surface, cycle_segmented_selected, cycle_badge_bg, cycle_segmented_text_selected) bringing dark, warm/orange variants to the Quick Tile Cycle card so it visually distinguishes itself in dark mode.
- Added a new Exec Card Custom Tones block (exec_accent, exec_card_surface, exec_segmented_selected, exec_segmented_text_selected) bringing dark, cool/blue variants to the Execution Mode card so it visually distinguishes itself in dark mode.
---
app/src/main/res/values-night/colors.xml | 27 +++++++++++++++++++-----
1 file changed, 22 insertions(+), 5 deletions(-)
diff --git a/app/src/main/res/values-night/colors.xml b/app/src/main/res/values-night/colors.xml
index b3b7f98..7b9931a 100644
--- a/app/src/main/res/values-night/colors.xml
+++ b/app/src/main/res/values-night/colors.xml
@@ -2,13 +2,13 @@
#D0BCFF
- #4F378B
+ #23212A
#EADDFF
- #141218
- #211F26
- #36343B
+ #000000
+ #141218
+ #2B2930
#2B2930
@@ -18,7 +18,6 @@
#1A3822
- #A8F2B2
#3E1A19
#F2B8B5
@@ -26,8 +25,26 @@
#2B2930
+ #49454F
#1B1A20
#36323F
#EADDFF
#938F96
+
+
+ #61D48A
+ #FFB782
+ #F48FB1
+
+
+ #1A130F
+ #3D210F
+ #1B1A20
+ #FFB782
+
+
+ #57AFFF
+ #11161A
+ #1A364F
+ #8ECCFF
From 2856ae1f0cf40d8a9ae18ee9b1d21e31baed4f52 Mon Sep 17 00:00:00 2001
From: DK <117024745+Dhangofa@users.noreply.github.com>
Date: Sat, 15 Aug 2026 15:18:38 +0530
Subject: [PATCH 03/81] Update night theme status bar color for improved layout
blending
- Changed android:statusBarColor from @color/surface_background to @color/card_surface. This ensures the status bar visually blends with the top header cards and components rather than matching the pure black background, creating a more cohesive, edge-to-edge aesthetic in dark mode.
---
app/src/main/res/values-night/themes.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/src/main/res/values-night/themes.xml b/app/src/main/res/values-night/themes.xml
index b82eec7..d4d0294 100644
--- a/app/src/main/res/values-night/themes.xml
+++ b/app/src/main/res/values-night/themes.xml
@@ -2,7 +2,7 @@
+
From dbd61c34ab565ba714a88677e9ebd1d325ea565c Mon Sep 17 00:00:00 2001
From: DK <117024745+Dhangofa@users.noreply.github.com>
Date: Mon, 17 Aug 2026 00:33:59 +0530
Subject: [PATCH 58/81] Inject diagnostic error banner layout in landscape mode
- Added
---
app/src/main/res/layout-land/activity_main.xml | 2 ++
1 file changed, 2 insertions(+)
diff --git a/app/src/main/res/layout-land/activity_main.xml b/app/src/main/res/layout-land/activity_main.xml
index 473cf68..34f4c44 100644
--- a/app/src/main/res/layout-land/activity_main.xml
+++ b/app/src/main/res/layout-land/activity_main.xml
@@ -208,6 +208,8 @@
android:textColor="@color/text_secondary" />
+
+
Date: Mon, 17 Aug 2026 00:44:58 +0530
Subject: [PATCH 59/81] Add android:id="@+id/targetSimHeaderContainer"
attribute
- Added android:id="@+id/targetSimHeaderContainer" attribute in the Target SIM's RelativeLayout
- MainActivity.java uses findViewById(R.id.targetSimHeaderContainer) to dim the text opacity when Root/Shizuku is not authorized
---
app/src/main/res/layout/view_execution_card.xml | 1 +
1 file changed, 1 insertion(+)
diff --git a/app/src/main/res/layout/view_execution_card.xml b/app/src/main/res/layout/view_execution_card.xml
index cf0e013..9171237 100644
--- a/app/src/main/res/layout/view_execution_card.xml
+++ b/app/src/main/res/layout/view_execution_card.xml
@@ -105,6 +105,7 @@
From 2866cfd043c6f91aa00923ac783dfc94a75fe160 Mon Sep 17 00:00:00 2001
From: DK <117024745+Dhangofa@users.noreply.github.com>
Date: Mon, 17 Aug 2026 01:00:40 +0530
Subject: [PATCH 60/81] Added button shape
---
app/src/main/res/drawable/shape_button_primary.xml | 5 +++++
1 file changed, 5 insertions(+)
create mode 100644 app/src/main/res/drawable/shape_button_primary.xml
diff --git a/app/src/main/res/drawable/shape_button_primary.xml b/app/src/main/res/drawable/shape_button_primary.xml
new file mode 100644
index 0000000..efa2239
--- /dev/null
+++ b/app/src/main/res/drawable/shape_button_primary.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
From 29b8fdb18909ccb472fa863d0916c2db0665cc3e Mon Sep 17 00:00:00 2001
From: DK <117024745+Dhangofa@users.noreply.github.com>
Date: Mon, 17 Aug 2026 01:19:48 +0530
Subject: [PATCH 61/81] Expand LTEandAbove carrier registry with global 2G/3G
sunset data
- Updated USA Registry: Added at&t, t-mobile, and dish to reflect the completed 2G/3G shutdowns across all major US networks as of August 2026.
- Added Japan Registry: Created JAPAN_LTE_AND_ABOVE to include docomo, au (KDDI), softbank, and rakuten, reflecting the final termination of Docomo's FOMA network.
- Added Australia Registry: Created AUSTRALIA_LTE_AND_ABOVE to include telstra, optus, and vodafone australia (TPG) following their nationwide 3G switch-offs.
- Added Taiwan Registry: Created TAIWAN_LTE_AND_ABOVE to include chunghwa, taiwan mobile, and far eastone following their mid-2024 shutdowns.
Added Singapore Registry: Created SINGAPORE_LTE_AND_ABOVE to include singtel, starhub, and m1 following their 2024 shutdowns.
- Added South Korea Registry: Created SOUTHKOREA_LTE_AND_ABOVE for lg u+, which is fully LTE/5G (intentionally omitting SK Telecom and KT as they still operate 3G networks).
- Updated Logic Flow: Appended new for loops inside the isLteAndAboveOnly() method to dynamically cross-reference the device's current SIM carrier against all the newly added regional lists.
---
.../telephony/LteAndAboveCarrierRegistry.java | 58 +++++++++++++++++--
1 file changed, 54 insertions(+), 4 deletions(-)
diff --git a/app/src/main/java/com/dhangofa/networktoggle/telephony/LteAndAboveCarrierRegistry.java b/app/src/main/java/com/dhangofa/networktoggle/telephony/LteAndAboveCarrierRegistry.java
index 8de62ef..4b99aea 100644
--- a/app/src/main/java/com/dhangofa/networktoggle/telephony/LteAndAboveCarrierRegistry.java
+++ b/app/src/main/java/com/dhangofa/networktoggle/telephony/LteAndAboveCarrierRegistry.java
@@ -4,16 +4,46 @@
import java.util.List;
public final class LteAndAboveCarrierRegistry {
-
+
// REGION: INDIA
- // Jio is purely 4G/5G. It has no 2G/3G infrastructure.
private static final List INDIA_LTE_AND_ABOVE = Arrays.asList(
"jio", "ind-jio", "jio 4g", "jio true5g"
);
- // REGION: USA (Examples)
+ // REGION: USA
+ // Verizon, AT&T, and T-Mobile have fully shut down 2G/3G networks as of 2026. Dish is 5G only.
private static final List USA_LTE_AND_ABOVE = Arrays.asList(
- "verizon", "vzw"
+ "verizon", "vzw", "at&t", "att", "t-mobile", "tmobile", "dish", "dish wireless"
+ );
+
+ // REGION: JAPAN
+ // Docomo, KDDI (au), SoftBank, and Rakuten have shut down their 3G networks.
+ private static final List JAPAN_LTE_AND_ABOVE = Arrays.asList(
+ "docomo", "ntt docomo", "au", "kddi", "softbank", "rakuten", "rakuten mobile"
+ );
+
+ // REGION: AUSTRALIA
+ // Telstra, Optus, and Vodafone Australia (TPG) have fully shut down 3G.
+ private static final List AUSTRALIA_LTE_AND_ABOVE = Arrays.asList(
+ "telstra", "optus", "vodafone au", "vodafone australia", "tpg"
+ );
+
+ // REGION: TAIWAN
+ // Chunghwa Telecom, Taiwan Mobile, and Far EasTone fully shut down 3G in mid-2024.
+ private static final List TAIWAN_LTE_AND_ABOVE = Arrays.asList(
+ "chunghwa", "chunghwa telecom", "taiwan mobile", "far eastone", "fet"
+ );
+
+ // REGION: SINGAPORE
+ // Singtel, StarHub, and M1 fully shut down 3G in 2024.
+ private static final List SINGAPORE_LTE_AND_ABOVE = Arrays.asList(
+ "singtel", "starhub", "m1"
+ );
+
+ // REGION: SOUTH KOREA
+ // LG U+ never had 3G and shut down 2G. (SK Telecom and KT still operate 3G as of 2026).
+ private static final List SOUTHKOREA_LTE_AND_ABOVE = Arrays.asList(
+ "lg u+", "lgu+", "lg uplus", "uplus"
);
private LteAndAboveCarrierRegistry() {
@@ -38,6 +68,26 @@ public static boolean isLteAndAboveOnly(String carrierName) {
if (normalized.equals(name) || normalized.contains(name)) return true;
}
+ for (String name : JAPAN_LTE_AND_ABOVE) {
+ if (normalized.equals(name) || normalized.contains(name)) return true;
+ }
+
+ for (String name : AUSTRALIA_LTE_AND_ABOVE) {
+ if (normalized.equals(name) || normalized.contains(name)) return true;
+ }
+
+ for (String name : TAIWAN_LTE_AND_ABOVE) {
+ if (normalized.equals(name) || normalized.contains(name)) return true;
+ }
+
+ for (String name : SINGAPORE_LTE_AND_ABOVE) {
+ if (normalized.equals(name) || normalized.contains(name)) return true;
+ }
+
+ for (String name : SOUTHKOREA_LTE_AND_ABOVE) {
+ if (normalized.equals(name) || normalized.contains(name)) return true;
+ }
+
return false;
}
}
From 29187a067089ffb45ca6bc76dd8b1556e1d72cb6 Mon Sep 17 00:00:00 2001
From: DK <117024745+Dhangofa@users.noreply.github.com>
Date: Mon, 17 Aug 2026 01:21:57 +0530
Subject: [PATCH 62/81] Updated version code and name
---
app/build.gradle.kts | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index 22a5513..6726641 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -10,8 +10,8 @@ android {
applicationId = "com.dhangofa.networktoggle"
minSdk = 24
targetSdk = 36
- versionCode = 32
- versionName = "1.0.32"
+ versionCode = 65
+ versionName = "1.0.65"
}
// Suggested by IzzyOnDroid
dependenciesInfo {
From fbb6326c03ab6fa27fcd6925e0a1c7bc8e8da9a4 Mon Sep 17 00:00:00 2001
From: DK <117024745+Dhangofa@users.noreply.github.com>
Date: Tue, 18 Aug 2026 00:13:32 +0530
Subject: [PATCH 63/81] Add carousel page colors
- Added 3 carousek page bg color
- Added view_guide_button bg color
---
app/src/main/res/values/colors.xml | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
index 262aeb9..9352d40 100644
--- a/app/src/main/res/values/colors.xml
+++ b/app/src/main/res/values/colors.xml
@@ -36,6 +36,12 @@
#D96509
#C2185B
+
+ #F2F8FF
+ #FFF8F3
+ #FCE9F1
+ #FFFFFF
+
#FFF8F3
#FFE0C2
From 850ae8c269a0a0ad3a72622b14d3979393cd7a9d Mon Sep 17 00:00:00 2001
From: DK <117024745+Dhangofa@users.noreply.github.com>
Date: Tue, 18 Aug 2026 00:14:57 +0530
Subject: [PATCH 64/81] Add carousel page colors for dark mode
- Added 3 carousek page bg color
- Added view_guide_button bg color
---
app/src/main/res/values-night/colors.xml | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/app/src/main/res/values-night/colors.xml b/app/src/main/res/values-night/colors.xml
index 7b9931a..229b26e 100644
--- a/app/src/main/res/values-night/colors.xml
+++ b/app/src/main/res/values-night/colors.xml
@@ -36,6 +36,12 @@
#FFB782
#F48FB1
+
+ #11161A
+ #1A130F
+ #160309
+ #2B2930
+
#1A130F
#3D210F
From 99721c7f27344683c4da9d3c365db0073fa62a10 Mon Sep 17 00:00:00 2001
From: DK <117024745+Dhangofa@users.noreply.github.com>
Date: Tue, 18 Aug 2026 00:18:36 +0530
Subject: [PATCH 65/81] Update dialog background radius and color
- Changed solid color from @color/card_surface to @color/segmented_container.
- Changed top-only 24dp corners to a uniform 28dp radius on all sides.
---
app/src/main/res/drawable/shape_dialog_bg.xml | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/app/src/main/res/drawable/shape_dialog_bg.xml b/app/src/main/res/drawable/shape_dialog_bg.xml
index 98d1f63..b9a57cd 100644
--- a/app/src/main/res/drawable/shape_dialog_bg.xml
+++ b/app/src/main/res/drawable/shape_dialog_bg.xml
@@ -1,8 +1,6 @@
-
-
+
+
From 84d16149ca8cf335f810a7d0e1281149f8ecbbce Mon Sep 17 00:00:00 2001
From: DK <117024745+Dhangofa@users.noreply.github.com>
Date: Tue, 18 Aug 2026 00:25:36 +0530
Subject: [PATCH 66/81] Add carousel graphics and new vector icons
- Added standard Material icons (ic_terminal, ic_sim_card, ic_help_outline, ic_menu_book, ic_open_in_new).
- Created custom shapes (shape_dot_active, shape_dot_inactive) for the carousel pagination dots.
---
app/src/main/res/drawable/ic_help_outline.xml | 10 ++++++++++
app/src/main/res/drawable/ic_menu_book.xml | 14 ++++++++++++++
app/src/main/res/drawable/ic_open_in_new.xml | 14 ++++++++++++++
app/src/main/res/drawable/ic_sim_card.xml | 10 ++++++++++
app/src/main/res/drawable/ic_terminal.xml | 14 ++++++++++++++
app/src/main/res/drawable/shape_dot_active.xml | 6 ++++++
app/src/main/res/drawable/shape_dot_inactive.xml | 6 ++++++
7 files changed, 74 insertions(+)
create mode 100644 app/src/main/res/drawable/ic_help_outline.xml
create mode 100644 app/src/main/res/drawable/ic_menu_book.xml
create mode 100644 app/src/main/res/drawable/ic_open_in_new.xml
create mode 100644 app/src/main/res/drawable/ic_sim_card.xml
create mode 100644 app/src/main/res/drawable/ic_terminal.xml
create mode 100644 app/src/main/res/drawable/shape_dot_active.xml
create mode 100644 app/src/main/res/drawable/shape_dot_inactive.xml
diff --git a/app/src/main/res/drawable/ic_help_outline.xml b/app/src/main/res/drawable/ic_help_outline.xml
new file mode 100644
index 0000000..cdd7a83
--- /dev/null
+++ b/app/src/main/res/drawable/ic_help_outline.xml
@@ -0,0 +1,10 @@
+
+
+
+
diff --git a/app/src/main/res/drawable/ic_menu_book.xml b/app/src/main/res/drawable/ic_menu_book.xml
new file mode 100644
index 0000000..1564a49
--- /dev/null
+++ b/app/src/main/res/drawable/ic_menu_book.xml
@@ -0,0 +1,14 @@
+
+
+
+
diff --git a/app/src/main/res/drawable/ic_open_in_new.xml b/app/src/main/res/drawable/ic_open_in_new.xml
new file mode 100644
index 0000000..95f40fc
--- /dev/null
+++ b/app/src/main/res/drawable/ic_open_in_new.xml
@@ -0,0 +1,14 @@
+
+
+
+
diff --git a/app/src/main/res/drawable/ic_sim_card.xml b/app/src/main/res/drawable/ic_sim_card.xml
new file mode 100644
index 0000000..fd09856
--- /dev/null
+++ b/app/src/main/res/drawable/ic_sim_card.xml
@@ -0,0 +1,10 @@
+
+
+
+
diff --git a/app/src/main/res/drawable/ic_terminal.xml b/app/src/main/res/drawable/ic_terminal.xml
new file mode 100644
index 0000000..a02c6c4
--- /dev/null
+++ b/app/src/main/res/drawable/ic_terminal.xml
@@ -0,0 +1,14 @@
+
+
+
+
diff --git a/app/src/main/res/drawable/shape_dot_active.xml b/app/src/main/res/drawable/shape_dot_active.xml
new file mode 100644
index 0000000..cd0e886
--- /dev/null
+++ b/app/src/main/res/drawable/shape_dot_active.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
diff --git a/app/src/main/res/drawable/shape_dot_inactive.xml b/app/src/main/res/drawable/shape_dot_inactive.xml
new file mode 100644
index 0000000..bf61b4d
--- /dev/null
+++ b/app/src/main/res/drawable/shape_dot_inactive.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
From a02bc6dce34f8967a4f8447d3551816742d0b3c3 Mon Sep 17 00:00:00 2001
From: DK <117024745+Dhangofa@users.noreply.github.com>
Date: Tue, 18 Aug 2026 00:28:15 +0530
Subject: [PATCH 67/81] Add shape_code_block for formatting raw stdout/stderr
text in the diagnostic dialog
---
app/src/main/res/drawable/shape_code_block.xml | 6 ++++++
1 file changed, 6 insertions(+)
create mode 100644 app/src/main/res/drawable/shape_code_block.xml
diff --git a/app/src/main/res/drawable/shape_code_block.xml b/app/src/main/res/drawable/shape_code_block.xml
new file mode 100644
index 0000000..c2207d2
--- /dev/null
+++ b/app/src/main/res/drawable/shape_code_block.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
From a0d0c3d688a10c29efeaf1d1c731bf953fcae201 Mon Sep 17 00:00:00 2001
From: DK <117024745+Dhangofa@users.noreply.github.com>
Date: Tue, 18 Aug 2026 00:32:01 +0530
Subject: [PATCH 68/81] Add Carousel viewholder
- Added to show guides based on the current app state
---
.../main/res/layout/item_setup_carousel.xml | 89 +++++++++++++++++++
1 file changed, 89 insertions(+)
create mode 100644 app/src/main/res/layout/item_setup_carousel.xml
diff --git a/app/src/main/res/layout/item_setup_carousel.xml b/app/src/main/res/layout/item_setup_carousel.xml
new file mode 100644
index 0000000..3eb5a12
--- /dev/null
+++ b/app/src/main/res/layout/item_setup_carousel.xml
@@ -0,0 +1,89 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
From 9e56ace62c6a56a4948df98dd95ffa492496a014 Mon Sep 17 00:00:00 2001
From: DK <117024745+Dhangofa@users.noreply.github.com>
Date: Tue, 18 Aug 2026 00:33:54 +0530
Subject: [PATCH 69/81] Add carousel view adapter
- Implemented the RecyclerView.Adapter logic for the ViewPager2 onboarding flow.
- Designed the individual carousel page layout with title, description, and image components.
---
.../ui/SetupCarouselAdapter.java | 113 ++++++++++++++++++
1 file changed, 113 insertions(+)
create mode 100644 app/src/main/java/com/dhangofa/networktoggle/ui/SetupCarouselAdapter.java
diff --git a/app/src/main/java/com/dhangofa/networktoggle/ui/SetupCarouselAdapter.java b/app/src/main/java/com/dhangofa/networktoggle/ui/SetupCarouselAdapter.java
new file mode 100644
index 0000000..792ecf8
--- /dev/null
+++ b/app/src/main/java/com/dhangofa/networktoggle/ui/SetupCarouselAdapter.java
@@ -0,0 +1,113 @@
+package com.dhangofa.networktoggle.ui;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.res.ColorStateList;
+import android.net.Uri;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+import androidx.recyclerview.widget.RecyclerView;
+import androidx.core.content.ContextCompat;
+
+import com.dhangofa.networktoggle.R;
+
+import java.util.List;
+
+public class SetupCarouselAdapter extends RecyclerView.Adapter {
+
+ public static class SetupItem {
+ public String title;
+ public String description;
+ public String buttonText;
+ public String url;
+ public int iconRes;
+ public int bgColorRes;
+ public int accentColorRes;
+ public int btnBgColorRes;
+
+ public SetupItem(String title, String description, String buttonText, String url, int iconRes, int bgColorRes, int accentColorRes, int btnBgColorRes) {
+ this.title = title;
+ this.description = description;
+ this.buttonText = buttonText;
+ this.url = url;
+ this.iconRes = iconRes;
+ this.bgColorRes = bgColorRes;
+ this.accentColorRes = accentColorRes;
+ this.btnBgColorRes = btnBgColorRes;
+ }
+ }
+
+ private List items;
+ private Context context;
+
+ public SetupCarouselAdapter(Context context, List items) {
+ this.context = context;
+ this.items = items;
+ }
+
+ @NonNull
+ @Override
+ public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
+ View view = LayoutInflater.from(context).inflate(R.layout.item_setup_carousel, parent, false);
+ // Important: Ensure the item fills the ViewPager2 width
+ view.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
+ return new ViewHolder(view);
+ }
+
+ @Override
+ public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
+ SetupItem item = items.get(position);
+ holder.title.setText(item.title);
+ holder.desc.setText(item.description);
+ holder.buttonText.setText(item.buttonText);
+ holder.icon.setImageResource(item.iconRes);
+
+ int bgColor = ContextCompat.getColor(context, item.bgColorRes);
+ int accentColor = ContextCompat.getColor(context, item.accentColorRes);
+
+ holder.background.setBackgroundTintList(ColorStateList.valueOf(bgColor));
+
+ holder.buttonText.setTextColor(accentColor);
+ holder.buttonIcon.setColorFilter(accentColor);
+ holder.icon.setColorFilter(accentColor);
+ int btnBgColor = ContextCompat.getColor(context, item.btnBgColorRes);
+ holder.button.setBackgroundTintList(ColorStateList.valueOf(btnBgColor));
+ holder.iconContainer.setBackgroundTintList(ColorStateList.valueOf(btnBgColor));
+
+ holder.button.setOnClickListener(v -> {
+ Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(item.url));
+ try { context.startActivity(browserIntent); } catch (Exception e) { android.widget.Toast.makeText(context, "No web browser installed to open this link.", android.widget.Toast.LENGTH_SHORT).show(); }
+ });
+ }
+
+ @Override
+ public int getItemCount() {
+ return items.size();
+ }
+
+ static class ViewHolder extends RecyclerView.ViewHolder {
+ View background;
+ TextView title, desc, buttonText;
+ ImageView icon, buttonIcon;
+ LinearLayout button;
+ View iconContainer;
+
+ public ViewHolder(@NonNull View itemView) {
+ super(itemView);
+ background = itemView.findViewById(R.id.carouselBackground);
+ title = itemView.findViewById(R.id.carouselTitle);
+ desc = itemView.findViewById(R.id.carouselDesc);
+ buttonText = itemView.findViewById(R.id.carouselButtonText);
+ icon = itemView.findViewById(R.id.carouselIcon);
+ buttonIcon = itemView.findViewById(R.id.carouselButtonIcon);
+ button = itemView.findViewById(R.id.carouselButton);
+ iconContainer = itemView.findViewById(R.id.carouselIconContainer);
+ }
+ }
+}
From 051d3542db3948399800bd7afc7896874af57fbf Mon Sep 17 00:00:00 2001
From: DK <117024745+Dhangofa@users.noreply.github.com>
Date: Tue, 18 Aug 2026 00:37:20 +0530
Subject: [PATCH 70/81] Polish diagnostic dialog padding and constraints
- Changed the root background from shape_segmented_container to shape_dialog_bg.
- Replaced the hardcoded padding="20dp" with specific horizontal/vertical paddings.
- Removed the hardcoded 250dp height limit on the ScrollView, changing it to wrap_content with layout_weight="1".
---
app/src/main/res/layout/dialog_diagnostic.xml | 22 +++++++++++--------
1 file changed, 13 insertions(+), 9 deletions(-)
diff --git a/app/src/main/res/layout/dialog_diagnostic.xml b/app/src/main/res/layout/dialog_diagnostic.xml
index 3420ff4..e348fcd 100644
--- a/app/src/main/res/layout/dialog_diagnostic.xml
+++ b/app/src/main/res/layout/dialog_diagnostic.xml
@@ -3,8 +3,10 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
- android:padding="20dp"
- android:background="@drawable/shape_segmented_container">
+ android:paddingTop="20dp"
+ android:paddingBottom="12dp"
+ android:paddingHorizontal="16dp"
+ android:background="@drawable/shape_dialog_bg">
+ android:layout_marginBottom="12dp"
+ android:layout_marginStart="4dp" />
+ android:layout_marginBottom="12dp">
+ android:textColor="@color/text_secondary" />
@@ -54,7 +58,7 @@
android:textSize="14sp"
android:fontFamily="sans-serif-medium"
android:textStyle="bold"
- android:textColor="@color/text_secondary"
+ android:textColor="@color/text_primary"
android:padding="8dp"
android:layout_marginEnd="16dp"
android:clickable="true"
From 01d3b8113deed1e6fe57f0cd08513b54a7bf52ea Mon Sep 17 00:00:00 2001
From: DK <117024745+Dhangofa@users.noreply.github.com>
Date: Tue, 18 Aug 2026 00:39:30 +0530
Subject: [PATCH 71/81] Fix constraint alignment on execution card title
- Added @+id/execModeTitleGroup ID to the title container.
- Updated the layout constraints (added layout_alignParentStart and layout_centerVertical) to align the title group and the autoSimWarningText correctly within the relative layout.
---
.../main/res/layout/view_execution_card.xml | 63 +++++++++++++------
1 file changed, 45 insertions(+), 18 deletions(-)
diff --git a/app/src/main/res/layout/view_execution_card.xml b/app/src/main/res/layout/view_execution_card.xml
index 9171237..8994720 100644
--- a/app/src/main/res/layout/view_execution_card.xml
+++ b/app/src/main/res/layout/view_execution_card.xml
@@ -13,16 +13,22 @@
android:layout_marginBottom="10dp">
+ android:gravity="center_vertical"
+ android:layout_alignParentStart="true"
+ android:layout_centerVertical="true"
+ android:layout_marginEnd="8dp">
+
+
-
+ android:layout_centerVertical="true"
+ android:layout_toEndOf="@id/execModeTitleGroup"
+ android:gravity="end|center_vertical">
+
+
+
+
@@ -109,18 +125,24 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp">
+
+ android:layout_centerVertical="true"
+ android:layout_alignParentStart="true"
+ android:layout_marginEnd="8dp">
+
+
+
-
+ android:visibility="gone" />
+
+
+
From 9bf81106171c3c97571192c66cd88fadf612f59c Mon Sep 17 00:00:00 2001
From: DK <117024745+Dhangofa@users.noreply.github.com>
Date: Tue, 18 Aug 2026 00:42:25 +0530
Subject: [PATCH 72/81] Protrait mode: Replace static QS hint with Carousel
container
- Removed the hardcoded shape_qs_hint_bg Quick Settings banner.
- Added a new LinearLayout (@+id/setupCarouselContainer) placeholder for the programmatic ViewPager2 carousel.
- Added the faqLink ImageView with the ic_help_outline asset to the header.
---
app/src/main/res/layout/activity_main.xml | 91 +++++++++--------------
1 file changed, 34 insertions(+), 57 deletions(-)
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
index 9784d05..d65a5c1 100644
--- a/app/src/main/res/layout/activity_main.xml
+++ b/app/src/main/res/layout/activity_main.xml
@@ -99,64 +99,30 @@
android:textColor="@color/text_secondary"
android:textSize="13sp" />
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
+
-
+
+
From ea14393d146b4a51d78c7be99bea454573f1a4bb Mon Sep 17 00:00:00 2001
From: DK <117024745+Dhangofa@users.noreply.github.com>
Date: Tue, 18 Aug 2026 00:44:16 +0530
Subject: [PATCH 73/81] Lanscape mode - Replace static QS hint with Carousel
container
- Removed the hardcoded shape_qs_hint_bg Quick Settings banner.
- Added a new LinearLayout (@+id/setupCarouselContainer) placeholder for the programmatic ViewPager2 carousel.
- Added the faqLink ImageView with the ic_help_outline asset to the header.
---
.../main/res/layout-land/activity_main.xml | 65 ++++++-------------
1 file changed, 19 insertions(+), 46 deletions(-)
diff --git a/app/src/main/res/layout-land/activity_main.xml b/app/src/main/res/layout-land/activity_main.xml
index 34f4c44..f3d2c27 100644
--- a/app/src/main/res/layout-land/activity_main.xml
+++ b/app/src/main/res/layout-land/activity_main.xml
@@ -126,7 +126,18 @@
android:background="@drawable/social_icon_bg"
android:clickable="true"
android:focusable="true" />
-
+
+
@@ -160,56 +171,18 @@
android:textColor="@color/text_secondary"
android:textSize="12sp" />
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+ android:baselineAligned="false"
+ android:clipChildren="false"
+ android:clipToPadding="false"
+ android:layout_marginBottom="12dp" />
-
+
Date: Tue, 18 Aug 2026 00:51:40 +0530
Subject: [PATCH 74/81] Overhaul diagnostic report generation formatting
- Removed the direct error checks and rewrote generateReport() to use a StringBuilder.
- Added a formatted --- NETWORK TOGGLE DIAGNOSTIC REPORT --- header.
- Reformatted the [DEVICE INFO] section to include Manufacturer, Brand, Device, Model, Android Version, and SDK Level.
---
.../util/DiagnosticReporter.java | 19 ++++++++++++++-----
1 file changed, 14 insertions(+), 5 deletions(-)
diff --git a/app/src/main/java/com/dhangofa/networktoggle/util/DiagnosticReporter.java b/app/src/main/java/com/dhangofa/networktoggle/util/DiagnosticReporter.java
index c70c9e0..ad57e4a 100644
--- a/app/src/main/java/com/dhangofa/networktoggle/util/DiagnosticReporter.java
+++ b/app/src/main/java/com/dhangofa/networktoggle/util/DiagnosticReporter.java
@@ -9,7 +9,6 @@
import java.util.Locale;
public class DiagnosticReporter {
-
public static String generateReport(AppPreferences prefs, SimResolver simResolver) {
DiagnosticError error = prefs.getLastError();
if (error == null) {
@@ -33,16 +32,26 @@ public static String generateReport(AppPreferences prefs, SimResolver simResolve
sb.append("[APP STATE]\n");
sb.append("Execution Mode: ").append(prefs.getExecutionMode().name()).append("\n");
sb.append("Target SIM Setting: ").append(prefs.getTargetSim().name()).append("\n");
-
+
int slotIndex = simResolver.resolveTargetSlotIndex(prefs.getExecutionMode());
sb.append("Resolved Slot Index: ").append(slotIndex).append("\n\n");
sb.append("[ERROR DETAILS]\n");
sb.append("Command Attempted:\n").append(error.command).append("\n\n");
- sb.append("Standard Error (stderr):\n").append(error.stderr).append("\n\n");
-
- sb.append("--- END OF REPORT ---");
+ sb.append("Exit Code: ").append(error.exitCode).append("\n\n");
+
+ if (error.exceptionMessage != null && !error.exceptionMessage.isEmpty()) {
+ sb.append("Exception Message:\n").append(error.exceptionMessage).append("\n\n");
+ }
+
+ if (error.stdout != null && !error.stdout.isEmpty()) {
+ sb.append("Standard Output (stdout):\n").append(error.stdout).append("\n\n");
+ }
+
+ sb.append("Standard Error (stderr):\n").append(error.stderr != null && !error.stderr.isEmpty() ? error.stderr : "(empty)").append("\n\n");
+
+ sb.append("--- END OF REPORT ---");
return sb.toString();
}
}
From ff93539362e12d7daef9c4e5077fd4628a9d0033 Mon Sep 17 00:00:00 2001
From: DK <117024745+Dhangofa@users.noreply.github.com>
Date: Tue, 18 Aug 2026 00:53:19 +0530
Subject: [PATCH 75/81] Expand DiagnosticError schema
- Added exitCode, stdout, and exceptionMessage properties to the DiagnosticError data model.
- Updated the class constructor to accept and initialize these new properties.
---
.../com/dhangofa/networktoggle/model/DiagnosticError.java | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/app/src/main/java/com/dhangofa/networktoggle/model/DiagnosticError.java b/app/src/main/java/com/dhangofa/networktoggle/model/DiagnosticError.java
index 713143d..f040ac8 100644
--- a/app/src/main/java/com/dhangofa/networktoggle/model/DiagnosticError.java
+++ b/app/src/main/java/com/dhangofa/networktoggle/model/DiagnosticError.java
@@ -2,12 +2,18 @@
public class DiagnosticError {
public final String command;
+ public final int exitCode;
+ public final String stdout;
public final String stderr;
+ public final String exceptionMessage;
public final long timestamp;
- public DiagnosticError(String command, String stderr, long timestamp) {
+ public DiagnosticError(String command, int exitCode, String stdout, String stderr, String exceptionMessage, long timestamp) {
this.command = command;
+ this.exitCode = exitCode;
+ this.stdout = stdout;
this.stderr = stderr;
+ this.exceptionMessage = exceptionMessage;
this.timestamp = timestamp;
}
}
From a58a0f0c961ae4b7251a256366fee612c480b7b8 Mon Sep 17 00:00:00 2001
From: DK <117024745+Dhangofa@users.noreply.github.com>
Date: Tue, 18 Aug 2026 00:57:46 +0530
Subject: [PATCH 76/81] Expand error state serialization for deep telemetry
- Updated setLastError() method signature and SharedPreferences edits to store the new telemetry fields (exit_code, stdout, exception).
---
.../networktoggle/config/AppPreferences.java | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/app/src/main/java/com/dhangofa/networktoggle/config/AppPreferences.java b/app/src/main/java/com/dhangofa/networktoggle/config/AppPreferences.java
index fdc95fb..d56dd31 100644
--- a/app/src/main/java/com/dhangofa/networktoggle/config/AppPreferences.java
+++ b/app/src/main/java/com/dhangofa/networktoggle/config/AppPreferences.java
@@ -87,10 +87,15 @@ public void setAutoSimError(boolean hasError) {
preferences.edit().putBoolean(KEY_AUTO_SIM_ERROR, hasError).apply();
}
- public void setLastError(String command, String stderr) {
+ public void setLastError(String command, int exitCode, String stdout, String stderr, String exceptionMsg) {
preferences.edit()
.putString(KEY_LAST_ERROR_CMD, command)
+ .putInt("last_error_exit_code", exitCode)
+ .putString("last_error_stdout", stdout)
+
.putString(KEY_LAST_ERROR_STDERR, stderr)
+ .putString("last_error_exception", exceptionMsg)
+
.putLong(KEY_LAST_ERROR_TIMESTAMP, System.currentTimeMillis())
.apply();
}
@@ -98,10 +103,13 @@ public void setLastError(String command, String stderr) {
public com.dhangofa.networktoggle.model.DiagnosticError getLastError() {
String cmd = preferences.getString(KEY_LAST_ERROR_CMD, null);
String stderr = preferences.getString(KEY_LAST_ERROR_STDERR, null);
+ int exitCode = preferences.getInt("last_error_exit_code", -1);
+ String stdout = preferences.getString("last_error_stdout", "");
+ String exceptionMsg = preferences.getString("last_error_exception", "");
long time = preferences.getLong(KEY_LAST_ERROR_TIMESTAMP, 0);
if (cmd == null && stderr == null) return null;
- return new com.dhangofa.networktoggle.model.DiagnosticError(cmd, stderr, time);
+ return new com.dhangofa.networktoggle.model.DiagnosticError(cmd, exitCode, stdout, stderr, exceptionMsg, time);
}
public void clearLastError() {
From 406f90cac568d0cbf3fb629ff33211d3c09a1392 Mon Sep 17 00:00:00 2001
From: DK <117024745+Dhangofa@users.noreply.github.com>
Date: Tue, 18 Aug 2026 01:01:29 +0530
Subject: [PATCH 77/81] Integrate interactive setup carousel and FAQ action
- Imported ViewPager2 and SetupCarouselAdapter dependencies.
- Added view variables: setupCarouselPager, setupCarouselContainer, carouselIndicators, and faqLink.
- Replaced the static "Quick Settings Ready" hints with the dynamic Setup Carousel.
---
.../dhangofa/networktoggle/MainActivity.java | 104 ++++++++++++++++++
1 file changed, 104 insertions(+)
diff --git a/app/src/main/java/com/dhangofa/networktoggle/MainActivity.java b/app/src/main/java/com/dhangofa/networktoggle/MainActivity.java
index 3ac7cab..60d77ee 100644
--- a/app/src/main/java/com/dhangofa/networktoggle/MainActivity.java
+++ b/app/src/main/java/com/dhangofa/networktoggle/MainActivity.java
@@ -29,9 +29,16 @@
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
+import android.widget.LinearLayout;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.TextView;
+import androidx.viewpager2.widget.ViewPager2;
+import com.dhangofa.networktoggle.ui.SetupCarouselAdapter;
+import java.util.ArrayList;
+import java.util.List;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
import com.dhangofa.networktoggle.config.AppPreferences;
import com.dhangofa.networktoggle.model.ExecutionMode;
@@ -72,6 +79,10 @@ public class MainActivity extends Activity implements android.content.SharedPref
private RadioButton radioSim1;
private RadioButton radioSim2;
private TextView autoSimWarningText;
+ private ViewPager2 setupCarouselPager;
+ private android.widget.LinearLayout setupCarouselContainer;
+ private LinearLayout carouselIndicators;
+ private ImageView faqLink;
private View separatorRootShizuku;
private View separatorAutoSim1;
@@ -166,6 +177,84 @@ protected void onCreate(Bundle savedInstanceState) {
updateSeparatorVisibility();
}
+ private void setupCarousel() {
+ List carouselItems = new ArrayList<>();
+ carouselItems.add(new SetupCarouselAdapter.SetupItem("New to NetToggle?", "Learn how to set up Execution Modes", "Read Guide", "https://github.com/Dhangofa/NetToggle/wiki/1.-Execution-Mode-Configuration", R.drawable.ic_terminal, R.color.first_pg_bg, R.color.exec_accent, R.color.view_guide_button_bg));
+ carouselItems.add(new SetupCarouselAdapter.SetupItem("Target SIM & Cycle", "Learn how to configure your modes", "Read Guide", "https://github.com/Dhangofa/NetToggle/wiki/2.-Target-SIM-Setup-&-Quick-Tile-Cycle-Guide", R.drawable.ic_sim_card, R.color.second_pg_bg, R.color.accent_orange, R.color.view_guide_button_bg));
+ carouselItems.add(new SetupCarouselAdapter.SetupItem("Quick Settings Ready", "Add the tile to your Control Center", "View Guide", "https://github.com/Dhangofa/NetToggle/wiki/3.-Adding-the-Tile-to-Quick-Settings", R.drawable.ic_network_bars, R.color.third_pg_bg, R.color.accent_pink, R.color.view_guide_button_bg));
+
+ if (setupCarouselContainer != null) {
+ setupCarouselContainer.removeAllViews();
+ for (int i = 0; i < carouselItems.size(); i++) {
+ SetupCarouselAdapter.SetupItem item = carouselItems.get(i);
+ View view = getLayoutInflater().inflate(R.layout.item_setup_carousel, setupCarouselContainer, false);
+ android.widget.LinearLayout.LayoutParams params = new android.widget.LinearLayout.LayoutParams(0, android.widget.LinearLayout.LayoutParams.WRAP_CONTENT, 1.0f);
+ if (i > 0) params.setMarginStart(12);
+ if (i < carouselItems.size() - 1) params.setMarginEnd(12);
+ view.setLayoutParams(params);
+
+ ((TextView) view.findViewById(R.id.carouselTitle)).setText(item.title);
+ ((TextView) view.findViewById(R.id.carouselDesc)).setText(item.description);
+ ((TextView) view.findViewById(R.id.carouselButtonText)).setText(item.buttonText);
+ ((TextView) view.findViewById(R.id.carouselButtonText)).setTextColor(getColor(item.accentColorRes));
+
+ ImageView icon = view.findViewById(R.id.carouselIcon);
+ icon.setImageResource(item.iconRes);
+ icon.setColorFilter(getColor(item.accentColorRes));
+
+ ImageView btnIcon = view.findViewById(R.id.carouselButtonIcon);
+ btnIcon.setColorFilter(getColor(item.accentColorRes));
+
+ view.findViewById(R.id.carouselBackground).setBackgroundTintList(android.content.res.ColorStateList.valueOf(getColor(item.bgColorRes)));
+ view.findViewById(R.id.carouselButton).setBackgroundTintList(android.content.res.ColorStateList.valueOf(getColor(item.btnBgColorRes)));
+ view.findViewById(R.id.carouselIconContainer).setBackgroundTintList(android.content.res.ColorStateList.valueOf(getColor(item.btnBgColorRes)));
+
+ view.findViewById(R.id.carouselButton).setOnClickListener(v -> {
+ try { startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(item.url))); } catch (Exception e) {}
+ });
+
+ setupCarouselContainer.addView(view);
+ }
+ } else if (setupCarouselPager != null) {
+ SetupCarouselAdapter adapter = new SetupCarouselAdapter(this, carouselItems);
+ setupCarouselPager.setAdapter(adapter);
+ setupCarouselIndicators(carouselItems.size());
+ setupCarouselPager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
+ @Override
+ public void onPageSelected(int position) {
+ super.onPageSelected(position);
+ updateCarouselIndicators(position);
+ }
+ });
+ }
+ }
+
+
+ private void setupCarouselIndicators(int count) {
+ if (carouselIndicators == null) return;
+ carouselIndicators.removeAllViews();
+ for (int i = 0; i < count; i++) {
+ android.widget.ImageView dot = new android.widget.ImageView(this);
+ dot.setImageDrawable(getDrawable(R.drawable.shape_dot_inactive));
+ android.widget.LinearLayout.LayoutParams params = new android.widget.LinearLayout.LayoutParams(16, 16);
+ params.setMargins(8, 0, 8, 0);
+ dot.setLayoutParams(params);
+ carouselIndicators.addView(dot);
+ }
+ }
+
+ private void updateCarouselIndicators(int position) {
+ if (carouselIndicators == null) return;
+ for (int i = 0; i < carouselIndicators.getChildCount(); i++) {
+ android.widget.ImageView dot = (android.widget.ImageView) carouselIndicators.getChildAt(i);
+ if (i == position) {
+ dot.setImageDrawable(getDrawable(R.drawable.shape_dot_active));
+ } else {
+ dot.setImageDrawable(getDrawable(R.drawable.shape_dot_inactive));
+ }
+ }
+ }
+
private void configureStatusBar() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) return;
@@ -177,6 +266,11 @@ private void configureStatusBar() {
}
private void bindViews() {
+ setupCarouselPager = findViewById(R.id.setupCarouselPager);
+ setupCarouselContainer = findViewById(R.id.setupCarouselContainer);
+ carouselIndicators = findViewById(R.id.carouselIndicators);
+ faqLink = findViewById(R.id.faqLink);
+ setupCarousel();
radioGroup = findViewById(R.id.modeRadioGroup);
radioRoot = findViewById(R.id.radioRoot);
radioShizuku = findViewById(R.id.radioShizuku);
@@ -202,6 +296,12 @@ private void bindViews() {
}
private void bindLinks() {
+ if (faqLink != null) {
+ faqLink.setOnClickListener(v -> {
+ Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://github.com/Dhangofa/NetToggle/wiki/Frequently-Asked-Questions-(FAQ)"));
+ try { startActivity(browserIntent); } catch (Exception e) { android.widget.Toast.makeText(MainActivity.this, "No web browser installed to open this link.", android.widget.Toast.LENGTH_SHORT).show(); }
+ });
+ }
githubLink.setOnClickListener(v -> openUrl("https://github.com/Dhangofa/NetToggle"));
telegramLink.setOnClickListener(v -> openUrl("https://t.me/dhangofas_projects_chat"));
}
@@ -551,6 +651,9 @@ private void setStatus(String text, int color) {
private boolean isUIAuthorized = true;
private void updateAuthorizationUI(boolean authorized) {
+ if (setupCarouselPager != null) {
+ setupCarouselPager.setCurrentItem(authorized ? 2 : 0, true);
+ }
if (isUIAuthorized == authorized) return;
isUIAuthorized = authorized;
@@ -587,6 +690,7 @@ private void openUrl(String url) {
try {
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
} catch (Exception ignored) {
+ android.widget.Toast.makeText(MainActivity.this, "No web browser installed to open this link.", android.widget.Toast.LENGTH_SHORT).show();
}
}
From 62ede23cf31b7ad5534e9ecf198cb998f1102153 Mon Sep 17 00:00:00 2001
From: DK <117024745+Dhangofa@users.noreply.github.com>
Date: Tue, 18 Aug 2026 01:03:02 +0530
Subject: [PATCH 78/81] Capture detailed execution context on failure
- Modified setLastError call to pass complete process details (exitCode, stdout, stderr, and exceptionMessage) instead of just the generic string stderr
---
.../java/com/dhangofa/networktoggle/NetworkTileService.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/src/main/java/com/dhangofa/networktoggle/NetworkTileService.java b/app/src/main/java/com/dhangofa/networktoggle/NetworkTileService.java
index 6579114..ddc8a28 100644
--- a/app/src/main/java/com/dhangofa/networktoggle/NetworkTileService.java
+++ b/app/src/main/java/com/dhangofa/networktoggle/NetworkTileService.java
@@ -188,7 +188,7 @@ public void onClick() {
if (!isAuthError) {
appPreferences.setTileErrorState(AppPreferences.TILE_ERROR_CMD);
- appPreferences.setLastError(result.getCommand(), result.getStderr());
+ appPreferences.setLastError(result.getCommand(), result.getExitCode(), result.getStdout(), result.getStderr(), result.getExceptionMessage());
}
mainHandler.post(() -> {
From 16fb9e2e9d033e19fd91b0d5c434df6113a0185d Mon Sep 17 00:00:00 2001
From: DK <117024745+Dhangofa@users.noreply.github.com>
Date: Tue, 18 Aug 2026 01:24:27 +0530
Subject: [PATCH 79/81] Add missing dependencies for carousel
implementation("androidx.core:core:1.12.0")
implementation("androidx.recyclerview:recyclerview:1.3.2")
---
app/build.gradle.kts | 3 +++
1 file changed, 3 insertions(+)
diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index 6726641..e536ef0 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -43,6 +43,9 @@ android {
}
dependencies {
+ implementation("androidx.core:core:1.12.0")
+ implementation("androidx.recyclerview:recyclerview:1.3.2")
+
// Shizuku API
implementation("dev.rikka.shizuku:api:13.1.5")
implementation("dev.rikka.shizuku:provider:13.1.5")
From c4cf1fa0f4b4f2fdd67560f267927754fea2ad8b Mon Sep 17 00:00:00 2001
From: DK <117024745+Dhangofa@users.noreply.github.com>
Date: Tue, 18 Aug 2026 01:30:11 +0530
Subject: [PATCH 80/81] Add missing dependency for viewpager2
implementation("androidx.viewpager2:viewpager2:1.0.0")
---
app/build.gradle.kts | 1 +
1 file changed, 1 insertion(+)
diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index e536ef0..a5b677c 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -43,6 +43,7 @@ android {
}
dependencies {
+ implementation("androidx.viewpager2:viewpager2:1.0.0")
implementation("androidx.core:core:1.12.0")
implementation("androidx.recyclerview:recyclerview:1.3.2")
From 25cfacd8ca1128529555f555006bc3c0a0f58a3a Mon Sep 17 00:00:00 2001
From: DK <117024745+Dhangofa@users.noreply.github.com>
Date: Tue, 18 Aug 2026 01:35:46 +0530
Subject: [PATCH 81/81] Removed unncessary dependencies
implementation("androidx.core:core:1.12.0")
implementation("androidx.recyclerview:recyclerview:1.3.2")
---
app/build.gradle.kts | 2 --
1 file changed, 2 deletions(-)
diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index a5b677c..c4907fc 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -44,8 +44,6 @@ android {
dependencies {
implementation("androidx.viewpager2:viewpager2:1.0.0")
- implementation("androidx.core:core:1.12.0")
- implementation("androidx.recyclerview:recyclerview:1.3.2")
// Shizuku API
implementation("dev.rikka.shizuku:api:13.1.5")