Skip to content

Power page foundation#2618

Open
anjani-1 wants to merge 21 commits intocelzero:mainfrom
anjani-1:codex/power-page-foundation
Open

Power page foundation#2618
anjani-1 wants to merge 21 commits intocelzero:mainfrom
anjani-1:codex/power-page-foundation

Conversation

@anjani-1
Copy link
Copy Markdown

No description provided.

Copilot AI review requested due to automatic review settings April 12, 2026 15:30
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR lays the groundwork for a new “Power” start destination and a portable/hosted “Power Profile” model, introducing initial UI surfaces (Power, Discover, Active, Profile details) plus data-layer storage/sanitization to support importing/exporting and tracking active profiles.

Changes:

  • Switch app start destination + bottom-nav “home” to PowerFragment, and hide bottom nav for deep Power destinations.
  • Add initial Power Profile data model, storage, artifact loading, and security/sanitization utilities (plus ownership tracking).
  • Add documentation + sample “community-knowledge” registry/profile artifacts and a broad set of Robolectric/unit tests.

Reviewed changes

Copilot reviewed 89 out of 90 changed files in this pull request and generated 10 comments.

Show a summary per file
File Description
gradle.properties Increases Kotlin daemon heap via kotlin.daemon.jvmargs.
docs/POWER_PAGE_PRODUCT_MODEL.md Adds proposed Power-page product model/IA and merge semantics doc.
docs/HOSTED_PROFILES.md Defines proposed hosted profile + registry JSON formats and fetch model.
community-knowledge/registry/profile-registry.v1.json Adds example hosted registry JSON.
community-knowledge/README.md Describes the example hosted registry/profile directory.
community-knowledge/profiles/app-horse/app-horse.power-profile.v1.json Adds example hosted profile artifact JSON.
app/src/test/java/com/celzero/bravedns/ui/PowerDestinationPolicyTest.kt Tests deep-destination + bottom-nav mapping policy.
app/src/test/java/com/celzero/bravedns/ui/activity/PowerProfilePreviewUiPolicyTest.kt Tests preview-mode UI disabling/enabling policies.
app/src/test/java/com/celzero/bravedns/ui/activity/AppInfoActivityUnitTest.kt Adds intent-extra coverage for preview mode.
app/src/test/java/com/celzero/bravedns/data/SavedPowerProfileTest.kt Adds JSON round-trip + parsing tests for saved setups.
app/src/test/java/com/celzero/bravedns/data/PowerProfileTextTest.kt Adds tests for word-based truncation utility.
app/src/test/java/com/celzero/bravedns/data/PowerProfileStoreTest.kt Adds tests for saving/activating/deactivating profiles.
app/src/test/java/com/celzero/bravedns/data/PowerProfileSecurityTest.kt Adds tests for sanitization and size limiting.
app/src/test/java/com/celzero/bravedns/data/PowerProfileOwnershipStoreTest.kt Adds tests for per-profile ownership persistence and aggregation.
app/src/test/java/com/celzero/bravedns/data/PowerProfileLocalCatalogManagerTest.kt Adds tests for local catalog hydration and tag presence.
app/src/test/java/com/celzero/bravedns/data/PowerProfileImportManagerTest.kt Adds tests for importing bundled rules and counting outcomes.
app/src/test/java/com/celzero/bravedns/data/PowerProfileAppManagerTest.kt Adds tests for app summaries and preview construction.
app/src/test/java/com/celzero/bravedns/data/PowerProfileActivationPolicyTest.kt Tests activation action resolution based on state/tunnel.
app/src/test/java/com/celzero/bravedns/data/ActivePowerProfileTest.kt Adds JSON round-trip + parsing tests for active profiles.
app/src/test/java/com/celzero/bravedns/adapter/WgConfigAdapterTest.kt Updates tests for adapter constructor signature changes.
app/src/test/java/com/celzero/bravedns/adapter/FirewallAppListAdapterTest.kt Updates tests for adapter constructor signature changes.
app/src/main/res/menu/bottom_nav_menu.xml Replaces Home nav item with Power nav item.
app/src/main/res/layout/view_power_profile_section_card.xml Adds reusable section-card layout for Power profile pages.
app/src/main/res/layout/view_power_profile_app_item.xml Adds layout for Power profile app entries.
app/src/main/res/layout/view_power_list_item_save_setup.xml Adds Power list-row layout for “save setup”.
app/src/main/res/layout/view_power_list_item_logs.xml Adds Power list-row layout for logs.
app/src/main/res/layout/view_power_list_item_firewall.xml Adds Power list-row layout for firewall.
app/src/main/res/layout/view_power_list_item_discover_profiles.xml Adds Power list-row layout for discovering profiles.
app/src/main/res/layout/view_power_list_item_dashboard.xml Adds Power list-row layout for dashboard.
app/src/main/res/layout/view_power_list_item_configure.xml Adds Power list-row layout for configure.
app/src/main/res/layout/view_power_list_item_apps.xml Adds Power list-row layout for apps.
app/src/main/res/layout/view_power_list_item_active_profiles.xml Adds Power list-row layout for active profiles.
app/src/main/res/layout/view_discover_profile_smooth_internet.xml Adds discover-card layout for Smooth browsing profile.
app/src/main/res/layout/view_discover_profile_safe_beautiful.xml Adds discover-card layout for Safe & Beautiful profile.
app/src/main/res/layout/view_discover_profile_parental_control.xml Adds discover-card layout for Parental control profile.
app/src/main/res/layout/view_discover_profile_import.xml Adds discover-card layout for importing profiles.
app/src/main/res/layout/view_discover_profile_focus.xml Adds discover-card layout for Deep focus profile.
app/src/main/res/layout/view_discover_profile_exam.xml Adds discover-card layout for Exam profile.
app/src/main/res/layout/view_discover_profile_app_horse.xml Adds discover-card layout for App Horse profile.
app/src/main/res/layout/view_active_power_profile_item.xml Adds generic card layout used for profile list entries.
app/src/main/res/layout/fragment_power.xml Adds the main Power screen layout.
app/src/main/res/layout/fragment_power_profile_entries.xml Adds layout for a profile’s entries preview page.
app/src/main/res/layout/fragment_power_profile_detail.xml Adds layout for profile detail + section cards and actions.
app/src/main/res/layout/fragment_power_profile_apps.xml Adds layout for profile apps page.
app/src/main/res/layout/fragment_discover_profiles.xml Adds layout for Discover Profiles screen.
app/src/main/res/layout/fragment_active_profiles.xml Adds layout for Active Profiles screen.
app/src/main/java/com/celzero/bravedns/service/RethinkBlocklistManager.kt Adds RDNS fallback for local stamp/tag conversion.
app/src/main/java/com/celzero/bravedns/database/RethinkLocalFileTagRepository.kt Adds DAO wrapper to fetch local tags by ids.
app/src/main/java/com/celzero/bravedns/database/RethinkLocalFileTagDao.kt Adds query to fetch local tags by ids.
app/src/main/java/com/celzero/bravedns/database/CustomIpRepository.kt Adds bulk insert and chunked delete helpers.
app/src/main/java/com/celzero/bravedns/database/CustomIpDao.kt Adds bulk insert and UID+port+ipAddress delete query.
app/src/main/java/com/celzero/bravedns/database/CustomDomainRepository.kt Adds bulk insert and chunked delete helper.
app/src/main/java/com/celzero/bravedns/database/CustomDomainDAO.kt Adds bulk insert and UID+domains delete query.
app/src/main/java/com/celzero/bravedns/data/SavedPowerProfile.kt Adds JSON-serializable “saved setup” model.
app/src/main/java/com/celzero/bravedns/data/PowerProfileText.kt Adds word-truncation helper for UI descriptions.
app/src/main/java/com/celzero/bravedns/data/PowerProfileStore.kt Adds SharedPreferences-backed store for saved/active profiles.
app/src/main/java/com/celzero/bravedns/data/PowerProfileSecurity.kt Adds sanitization/limits for profile/artifact inputs.
app/src/main/java/com/celzero/bravedns/data/PowerProfilePortableDocument.kt Adds portable profile document parsing/exporting.
app/src/main/java/com/celzero/bravedns/data/PowerProfileOwnershipStore.kt Adds per-profile owned-rule persistence + aggregation.
app/src/main/java/com/celzero/bravedns/data/PowerProfileLocalCatalogManager.kt Adds local-catalog presence + hydration helper.
app/src/main/java/com/celzero/bravedns/data/PowerProfileDefinition.kt Defines a catalog/display model for Power profiles.
app/src/main/java/com/celzero/bravedns/data/PowerProfileCurrentSetupManager.kt Adds “save current setup as reusable profile” helper.
app/src/main/java/com/celzero/bravedns/data/PowerProfileCatalog.kt Adds combined curated+imported catalog API.
app/src/main/java/com/celzero/bravedns/data/PowerProfileBlocklistPreviewManager.kt Adds grouped preview of local-blocklist tag selections.
app/src/main/java/com/celzero/bravedns/data/PowerProfileArtifacts.kt Adds artifact loading + exportable portable document assembly.
app/src/main/java/com/celzero/bravedns/data/PowerProfileAppModels.kt Adds app-scoped rule models + firewall/status sanitizers.
app/src/main/java/com/celzero/bravedns/data/PowerProfileAppManager.kt Adds app summary + preview builders for profiles.
app/src/main/java/com/celzero/bravedns/data/PowerProfileActivationPolicy.kt Adds activation action resolution policy.
app/src/main/java/com/celzero/bravedns/data/ImportedPowerProfileStore.kt Adds import/export persistence for portable profiles.
app/src/main/java/com/celzero/bravedns/data/CuratedPowerProfileCatalog.kt Adds curated built-in Power profiles and metadata.
app/src/main/java/com/celzero/bravedns/data/BundledDomainProfileArtifact.kt Adds parsing + sanitization wrapper for bundled artifacts.
app/src/main/java/com/celzero/bravedns/data/ActivePowerProfile.kt Adds JSON-serializable “active profile” model.
app/src/main/assets/power/app-horse-profile.json Adds bundled artifact data for the App Horse profile.
app/src/full/res/navigation/app_navigation.xml Sets Power as start destination and adds Power-related fragments.
app/src/full/java/com/celzero/bravedns/ui/PowerDestinationPolicy.kt Adds helper for bottom-nav visibility + menu mapping.
app/src/full/java/com/celzero/bravedns/ui/HomeScreenActivity.kt Integrates Power start destination + bottom-nav policy behavior.
app/src/full/java/com/celzero/bravedns/ui/fragment/PowerProfileAppsFragment.kt Adds UI to list apps contained in a profile and open preview.
app/src/full/java/com/celzero/bravedns/ui/fragment/DiscoverProfilesFragment.kt Adds curated+imported discovery UI and import flow.
app/src/full/java/com/celzero/bravedns/ui/fragment/ActiveProfilesFragment.kt Adds coverage/summary UI for active/saved profiles.
app/src/full/java/com/celzero/bravedns/ui/activity/PowerProfilePreviewUiPolicy.kt Adds UI policy helpers for preview/read-only state.
app/src/full/java/com/celzero/bravedns/ui/activity/AppInfoActivity.kt Adds Power-profile preview mode for app details.
app/src/full/java/com/celzero/bravedns/RethinkDnsApplication.kt Triggers reconciliation of active profiles during app startup.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread gradle.properties
Comment on lines +10 to +11
# Kotlin daemon JVM args for more memory
kotlin.daemon.jvmargs=-Xmx4048m -Dfile.encoding=UTF-8
Copy link

Copilot AI Apr 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

kotlin.daemon.jvmargs uses -Xmx4048m, which looks like a typo / non-standard heap size (typically 4096m). If this is meant to be 4 GiB, consider correcting to 4096m to avoid confusion and accidental misconfiguration.

Copilot uses AI. Check for mistakes.
Comment on lines +141 to +145
val ipRules =
app.ipRules
.mapNotNull { sanitizeAppIpRule(it) }
.distinctBy { "${it.ipAddress}|${it.port}|${it.protocol}|${it.status}|${it.wildcard}" }
.take(MAX_APP_IP_RULES)
Copy link

Copilot AI Apr 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sanitizeApps() de-dupes ipRules without considering fields like proxyId, proxyCC, or isActive. This can collapse distinct rules into one entry and silently drop proxy configuration / activation state. Include all rule-shaping fields in the de-dupe key (similar to domainRules) to avoid data loss.

Copilot uses AI. Check for mistakes.
Comment on lines +161 to +165
val appJson = appsJson.optJSONObject(index) ?: continue
val packageName = appJson.optString("packageName", "").trim()
val appName = appJson.optString("appName", "").trim()
if (packageName.isEmpty() || appName.isEmpty()) continue
val domainRules =
Copy link

Copilot AI Apr 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fromJson() skips app entries when appName is missing/blank (if (packageName.isEmpty() || appName.isEmpty()) continue). This conflicts with PowerProfileSecurity.sanitizeApps(), which already falls back to packageName when appName is blank, and it reduces format forward-compatibility. Consider only requiring packageName here and letting the sanitizer fill in the display name.

Copilot uses AI. Check for mistakes.
val appJson = appsJson.optJSONObject(index) ?: continue
val packageName = appJson.optString("packageName", "").trim()
val appName = appJson.optString("appName", "").trim()
if (packageName.isEmpty() || appName.isEmpty()) continue
Copy link

Copilot AI Apr 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Artifact parsing currently drops apps[] entries when appName is blank (if (packageName.isEmpty() || appName.isEmpty()) continue). Since later sanitization can already supply a fallback name, consider only requiring packageName so artifacts remain resilient to missing display names.

Suggested change
if (packageName.isEmpty() || appName.isEmpty()) continue
if (packageName.isEmpty()) continue

Copilot uses AI. Check for mistakes.
Comment on lines +86 to +89
val first = PowerProfileStore.saveCurrentSetup(context, appConfig)
Thread.sleep(2)
val second = PowerProfileStore.saveCurrentSetup(context, appConfig)

Copy link

Copilot AI Apr 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test relies on Thread.sleep(2) to force ordering based on System.currentTimeMillis(), which can be flaky on slow/virtualized CI runners. Consider injecting a clock/time provider into PowerProfileStore for tests or allowing saveCurrentSetup() to accept a timestamp in test builds so ordering can be deterministic without sleeping.

Copilot uses AI. Check for mistakes.
Comment on lines +64 to +68
<Button
android:id="@+id/fp_pause_icon"
android:layout_width="60dp"
android:layout_height="48dp"
android:layout_gravity="start"
Copy link

Copilot AI Apr 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fp_pause_icon is a Button with no text or contentDescription. For accessibility (screen readers) and UI semantics, consider using an ImageButton (or setting an appropriate android:contentDescription) for icon-only tappable controls. The same applies to the other icon-only button in this header.

Copilot uses AI. Check for mistakes.
Comment on lines +16 to +18
"artifactUrl": "https://raw.githubusercontent.com/anjani-1/rethink-again/codex/power-page-foundation/community-knowledge/profiles/app-horse/app-horse.power-profile.v1.json",
"homepageUrl": "https://github.com/anjani-1/rethink-again/tree/codex/power-page-foundation/community-knowledge/profiles/app-horse",
"readmeUrl": "https://github.com/anjani-1/rethink-again/blob/codex/power-page-foundation/community-knowledge/README.md",
Copy link

Copilot AI Apr 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The registry/example URLs are hard-coded to a personal fork + feature branch (anjani-1/.../codex/power-page-foundation). Once this PR is merged, those URLs will likely 404. Consider switching to stable URLs (eg, main branch in the canonical repo) or using relative links/placeholders in this sample registry.

Copilot uses AI. Check for mistakes.
Comment on lines +217 to +221
private fun sanitizeDomain(value: String): String? {
val normalized = value.trim().trimEnd('.').lowercase()
if (normalized.isEmpty() || normalized.length > 253) return null
if (!domainRegex.matches(normalized)) return null
if (normalized.contains("..")) return null
Copy link

Copilot AI Apr 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sanitizeDomain() currently accepts labels that start/end with '-' (eg, -bad.example) because of the permissive regex. These are not valid hostnames and may later cause rule insertion/behavior issues. Consider tightening validation (label rules + max label length) or delegating to existing domain validation logic used elsewhere in the app.

Copilot uses AI. Check for mistakes.
Comment on lines +184 to +186
private fun profileFile(context: Context, profileId: String): File {
return File(profileDirectory(context), "$profileId.json")
}
Copy link

Copilot AI Apr 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

profileFile() uses the raw profileId to build a filename. If a caller ever passes an unsanitized id (eg, containing path separators), this can lead to directory traversal / clobbering other files under filesDir. Consider sanitizing profileId (similar to ImportedPowerProfileStore.sanitizeFileName) or enforcing the same strict id regex before writing.

Copilot uses AI. Check for mistakes.

override fun onCreate(savedInstanceState: Bundle?) {
theme.applyStyle(Themes.getCurrentTheme(isDarkThemeOn(), persistentState.theme), true)
super.onCreate(savedInstanceState)
Copy link

Copilot AI Apr 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AppInfoActivity no longer calls handleFrostEffectIfNeeded(persistentState.theme) in onCreate(), while most other activities still do. This can cause inconsistent UI theming/blur behavior for the App Details screen. Consider restoring the call for consistency with the rest of the app.

Suggested change
super.onCreate(savedInstanceState)
super.onCreate(savedInstanceState)
handleFrostEffectIfNeeded(persistentState.theme)

Copilot uses AI. Check for mistakes.
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.

2 participants