Skip to content

Commit 25f3dd6

Browse files
committed
feat: UI Redesign Navigation - Major Update
Navigation Restructure: - Migrated from BottomNavigationView to TabLayout + ViewPager2 - Added swipe gesture support between Dashboard and Apps tabs - Implemented overflow menu (Settings, Action Logs, About) - New MainPagerAdapter for fragment management Apps List Improvements: - Added FilterSortBottomSheet for unified filter/sort UI - New filter options: All, Running, Frozen, Restricted - New sort options: Name A-Z, Name Z-A, Size, Last Updated - Updated search bar with filter button Running State Detection: - Added AppRunningStateDetector interface with multi-method detection - RootRunningStateDetector: /proc check + dumpsys services - ShizukuRunningStateDetector: dumpsys services - ViewOnlyRunningStateDetector: UsageStatsManager - New AppRunningState enum (RUNNING, AWAKENED, STOPPED, UNKNOWN) - Running state badges on app list items Settings Enhancements: - Added Action Logs section with View, Rollback, Clear options - Added Animation Scale controls (presets + custom slider) - Rollback availability state management ℹ About Page Redesign: - Material 3 card-based design - Gradient header background - App Info, Developer, and Links sections - Removed informal text Data Models: - AnimationScale with presets and custom values - AppListFilter for filter/sort state - Updated AppInfo with runningState and isBackgroundRestricted Requirements: 1.x, 2.x, 3.x, 4.x, 6.x, 7.x, 8.x
1 parent 5f6e51a commit 25f3dd6

55 files changed

Lines changed: 3826 additions & 1202 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package com.appcontrolx.data.model
2+
3+
/**
4+
* Data class representing animation scale settings for the device.
5+
* Requirements: 7.3
6+
*/
7+
data class AnimationScale(
8+
val windowScale: Float,
9+
val transitionScale: Float,
10+
val animatorScale: Float
11+
) {
12+
companion object {
13+
val DEFAULT = AnimationScale(1.0f, 1.0f, 1.0f)
14+
val OFF = AnimationScale(0f, 0f, 0f)
15+
16+
/**
17+
* Preset animation scale values with display names.
18+
* Requirements: 7.3
19+
*/
20+
val PRESETS = listOf(
21+
0f to "Off",
22+
0.5f to "0.5x",
23+
0.75f to "0.75x",
24+
1.0f to "1x (Default)",
25+
1.5f to "1.5x",
26+
2.0f to "2x"
27+
)
28+
29+
/**
30+
* Minimum allowed animation scale value.
31+
*/
32+
const val MIN_SCALE = 0.0f
33+
34+
/**
35+
* Maximum allowed animation scale value.
36+
*/
37+
const val MAX_SCALE = 10.0f
38+
39+
/**
40+
* Creates an AnimationScale with all three scales set to the same value.
41+
*/
42+
fun uniform(scale: Float): AnimationScale {
43+
val clampedScale = scale.coerceIn(MIN_SCALE, MAX_SCALE)
44+
return AnimationScale(clampedScale, clampedScale, clampedScale)
45+
}
46+
}
47+
48+
/**
49+
* Returns true if all scales are set to the same value.
50+
*/
51+
fun isUniform(): Boolean = windowScale == transitionScale && transitionScale == animatorScale
52+
53+
/**
54+
* Returns the uniform scale value if all scales are the same, or null otherwise.
55+
*/
56+
fun getUniformScale(): Float? = if (isUniform()) windowScale else null
57+
58+
/**
59+
* Returns the preset name if this matches a preset, or "Custom" otherwise.
60+
*/
61+
fun getPresetName(): String {
62+
val uniformScale = getUniformScale() ?: return "Custom"
63+
return PRESETS.find { it.first == uniformScale }?.second ?: "Custom"
64+
}
65+
}

app/src/main/java/com/appcontrolx/data/model/AppInfo.kt

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ enum class AppStatus {
1515

1616
/**
1717
* Data class representing information about an installed application.
18+
* Requirements: 5.1, 5.2, 4.6
1819
*/
1920
data class AppInfo(
2021
val packageName: String,
@@ -28,7 +29,13 @@ data class AppInfo(
2829
val isStopped: Boolean,
2930
val isBackgroundRestricted: Boolean,
3031
val installedTime: Long,
31-
val lastUpdateTime: Long
32+
val lastUpdateTime: Long,
33+
val size: Long = 0L,
34+
/**
35+
* The running state of the app detected via multi-method detection.
36+
* Requirements: 4.6
37+
*/
38+
val runningState: AppRunningState = AppRunningState.UNKNOWN
3239
) {
3340
/**
3441
* Whether the app is frozen (disabled)
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package com.appcontrolx.data.model
2+
3+
/**
4+
* Filter type options for app list filtering.
5+
* Requirements: 3.4
6+
*/
7+
enum class FilterType(val displayName: String) {
8+
ALL("All"),
9+
RUNNING("Running"),
10+
FROZEN("Frozen"),
11+
RESTRICTED("Restricted")
12+
}
13+
14+
/**
15+
* Sort type options for app list sorting.
16+
* Requirements: 3.5
17+
*/
18+
enum class SortType(val displayName: String) {
19+
NAME_ASC("Name (A-Z)"),
20+
NAME_DESC("Name (Z-A)"),
21+
SIZE_DESC("Size"),
22+
UPDATED_DESC("Last updated")
23+
}
24+
25+
/**
26+
* Data class representing the current filter and sort configuration for the app list.
27+
* Requirements: 3.4, 3.5
28+
*/
29+
data class AppListFilter(
30+
val filterType: FilterType = FilterType.ALL,
31+
val sortType: SortType = SortType.NAME_ASC
32+
)
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package com.appcontrolx.data.model
2+
3+
/**
4+
* Enum representing the running state of an application.
5+
* Used for accurate running detection on Android 12+.
6+
*
7+
* Requirements: 4.6
8+
*/
9+
enum class AppRunningState {
10+
/**
11+
* App is confirmed running (foreground or background service).
12+
* Detected via /proc check, dumpsys services, or UsageStatsManager.
13+
*/
14+
RUNNING,
15+
16+
/**
17+
* App has been launched but may not be running now.
18+
* FLAG_STOPPED is false, meaning the app was launched at some point.
19+
*/
20+
AWAKENED,
21+
22+
/**
23+
* App has never been launched or was force-stopped.
24+
* FLAG_STOPPED is true.
25+
*/
26+
STOPPED,
27+
28+
/**
29+
* Cannot determine the running state.
30+
* Used when detection methods fail or timeout.
31+
*/
32+
UNKNOWN
33+
}

app/src/main/java/com/appcontrolx/data/model/SystemInfo.kt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ data class NetworkInfo(
6464
val type: NetworkType,
6565
val isConnected: Boolean,
6666
val signalStrength: Int?, // 0-4 bars, null if unavailable
67+
val signalPercent: Int?, // 0-100 percentage, null if unavailable
68+
val signalDbm: Int?, // Signal strength in dBm, null if unavailable
6769
val ssid: String? // WiFi name, null if not WiFi
6870
)
6971

@@ -96,11 +98,13 @@ data class DeviceInfo(
9698
val model: String,
9799
val device: String,
98100
val androidVersion: String,
101+
val androidCodename: String?, // e.g., "Baklava" for Android 16
99102
val apiLevel: Int,
100103
val buildNumber: String,
101104
val kernelVersion: String,
105+
val socName: String?, // SoC/processor name
102106
val uptimeMs: Long,
103-
val deepSleepMs: Long? // requires root
107+
val deepSleepMs: Long? // requires root
104108
)
105109

106110
/**

app/src/main/java/com/appcontrolx/di/ExecutorModule.kt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ import com.appcontrolx.domain.executor.PermissionBridge
77
import com.appcontrolx.domain.executor.RootExecutor
88
import com.appcontrolx.domain.executor.ShizukuExecutor
99
import com.appcontrolx.domain.manager.ActionLogger
10+
import com.appcontrolx.domain.manager.AnimationScaleManager
11+
import com.appcontrolx.domain.manager.AnimationScaleManagerImpl
1012
import com.appcontrolx.domain.manager.DisplayManager
1113
import dagger.Module
1214
import dagger.Provides
@@ -95,4 +97,14 @@ object ExecutorModule {
9597
@ApplicationContext context: Context,
9698
commandExecutor: CommandExecutor
9799
): ActionLogger = ActionLogger(context, commandExecutor)
100+
101+
/**
102+
* Provides AnimationScaleManager for animation scale control.
103+
* Requirements: 7.4
104+
*/
105+
@Provides
106+
@Singleton
107+
fun provideAnimationScaleManager(
108+
commandExecutor: CommandExecutor
109+
): AnimationScaleManager = AnimationScaleManagerImpl(commandExecutor)
98110
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package com.appcontrolx.domain.detector
2+
3+
import com.appcontrolx.data.model.AppRunningState
4+
5+
/**
6+
* Interface for detecting the running state of applications.
7+
* Implementations use different methods based on execution mode.
8+
*
9+
* Requirements: 4.1, 4.6
10+
*/
11+
interface AppRunningStateDetector {
12+
13+
/**
14+
* Detect the running state of a single application.
15+
*
16+
* @param packageName The package name of the app to check
17+
* @return The detected running state
18+
*/
19+
suspend fun detectRunningState(packageName: String): AppRunningState
20+
21+
/**
22+
* Detect the running states of multiple applications in batch.
23+
* More efficient than calling detectRunningState() for each app.
24+
*
25+
* @param packageNames List of package names to check
26+
* @return Map of package name to detected running state
27+
*/
28+
suspend fun detectBatchRunningStates(packageNames: List<String>): Map<String, AppRunningState>
29+
}

0 commit comments

Comments
 (0)