Skip to content

feat: add privacy toggles for telemetry, ads, and tracking - #481

Merged
laurentiu021 merged 2 commits into
mainfrom
feat/privacy-toggles
May 21, 2026
Merged

laurentiu021 merged 2 commits into
mainfrom
feat/privacy-toggles

Conversation

@laurentiu021

@laurentiu021 laurentiu021 commented May 21, 2026 •

Copy link
Copy Markdown
Owner

Summary

New Privacy tab with 12 one-click toggles for Windows privacy settings.

Categories:

  • Telemetry — diagnostic data, activity history, advertising ID, feedback
  • UI Declutter — Start suggestions, tips, lock screen tips, Spotlight ads
  • Features — Copilot, Cortana, web search in Start, widgets

Behavior:

  • Reads current state from registry on load
  • Instant apply on toggle change (no "Save" button needed)
  • "Apply All" enables all privacy protections at once
  • "Reset to defaults" turns all off (restores Windows defaults)
  • Category filter for quick access
  • Graceful handling of HKLM paths requiring admin (shows elevation badge)

Closes #9

Test plan

  • CI build passes
  • Tab appears in navigation
  • Toggles reflect current registry state
  • Toggling a switch immediately writes to registry
  • HKLM toggles show warning if not elevated
  • Apply All / Reset work correctly

@coderabbitai

coderabbitai Bot commented May 21, 2026 •

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

This PR implements the Privacy Toggles feature by introducing a registry-backed toggle system with a data model, core service for Windows privacy management, view model for UI state orchestration, XAML UI with category filtering and commands, and replacing the WIP placeholder in the main window navigation. All toggles support instant registry apply, state detection on load, and bulk operations.

Changes

Privacy Toggles Implementation

Layer / File(s) Summary
Privacy Toggle Model and Core Service
SysManager/Models/PrivacyToggle.cs, SysManager/Services/PrivacyService.cs
PrivacyToggle observable model holds display metadata and registry state. PrivacyService creates a hardcoded catalog of 12 toggle definitions, reads current registry state on load, writes DWORD values on apply with exception handling and logging, and supports both single-toggle and bulk operations.
Dependency Injection Registration
SysManager/ServiceRegistration.cs
PrivacyService and PrivacyViewModel are registered as singletons in the service container.
Privacy View Model with Toggle Management
SysManager/ViewModels/PrivacyViewModel.cs
PrivacyViewModel loads toggles from PrivacyService, subscribes to IsEnabled changes for immediate registry apply, filters toggles by category, and provides commands for applying all, resetting to defaults, and refreshing from registry with proper event unsubscription on disposal.
Main Window ViewModel Placeholder Replacement
SysManager/ViewModels/MainWindowViewModel.cs
Replaces WipPrivacySettings placeholder property with real PrivacyViewModel Privacy property, updates both DI and test/designer initialization paths, removes placeholder setup, rebinds sidebar "Privacy & Telemetry" navigation to PrivacyView, and updates Dispose() to clean up the new PrivacyViewModel.
Privacy View XAML and Code-Behind
SysManager/Views/PrivacyView.xaml, SysManager/Views/PrivacyView.xaml.cs
Implements privacy settings UI with grouped toggle list, toolbar buttons (Apply All / Reset to Defaults / Refresh), category dropdown filter, admin elevation status indicators, and status message bar bound to PrivacyViewModel properties.
Release Notes Documentation
CHANGELOG.md
Documents Privacy Toggles under Unreleased and reorganizes feature entries: File Shredder → [1.3.0], System Info Export and Bulk App Installer → [1.2.0].

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related issues

  • laurentiu021/SysManager#9: This PR implements the complete Privacy & debloat toggles feature requested in the enhancement, including registry-backed switches grouped by category (telemetry, UI declutter, features) with reversible on/off state and current state detection.

Possibly related PRs

  • laurentiu021/SystemManager#345: Replaced WIP privacy placeholder navigation/view wiring and updated MainWindowViewModel to integrate real PrivacyViewModel and PrivacyView instead of placeholder.
  • laurentiu021/SystemManager#396: MainWindowViewModel.Dispose() now disposes the new PrivacyViewModel, coordinating with window lifecycle management on Application.Exit.

Poem

🐰 Twelve privacy toggles hop into place,
Registry paths traced with careful grace,
Categories grouped, elevation detected true—
Windows debloat is finally in view!
One click to reclaim your digital space. 🔐

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 31.82% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately and specifically describes the main change: adding privacy toggles for telemetry, ads, and tracking, which aligns with the core feature delivered.
Linked Issues check ✅ Passed The PR successfully implements all core requirements from issue #9: 12 privacy toggles across three categories (Telemetry, UI Declutter, Features), current state detection on load, category grouping, reversible toggles, and immediate registry application.
Out of Scope Changes check ✅ Passed All changes are directly related to implementing privacy toggles. Model, service, view-model, and UI changes are focused on the privacy feature. Only incidental changes are CHANGELOG and service registration updates required for the feature.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/privacy-toggles

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@SysManager/SysManager/Services/PrivacyService.cs`:
- Around line 66-77: ApplyAll promises to log per-toggle errors and continue,
but because ApplyToggle only handles certain exception types, unexpected
exceptions can abort the loop; to fix, wrap each ApplyToggle(toggle) call inside
a broad try/catch in ApplyAll (after ArgumentNullException.ThrowIfNull) that
catches Exception, logs the error with context (including the toggle identifier)
and continues to the next item; alternatively, ensure ApplyToggle(PrivacyToggle
toggle) itself catches all exceptions, logs them, and returns without throwing —
reference ApplyAll(IEnumerable<PrivacyToggle> toggles) and
ApplyToggle(PrivacyToggle toggle) when making the change.

In `@SysManager/SysManager/ViewModels/PrivacyViewModel.cs`:
- Around line 92-97: ApplyAll currently just reapplies current states; change it
so it first sets every PrivacyToggle.IsEnabled = true on each entry in the
Toggles collection, then call _service.ApplyAll(Toggles); update StatusMessage
and Log.Information accordingly (e.g., "All {Count} toggles enabled and
applied") to reflect that protections were turned on; touch the ApplyAll method
and the Toggles iteration (use a simple foreach over Toggles to set IsEnabled)
before invoking _service.ApplyAll.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 68048afb-051b-4998-a964-38262db87732

📥 Commits

Reviewing files that changed from the base of the PR and between 97bdf32 and 9527ce1.

📒 Files selected for processing (8)
  • CHANGELOG.md
  • SysManager/SysManager/Models/PrivacyToggle.cs
  • SysManager/SysManager/ServiceRegistration.cs
  • SysManager/SysManager/Services/PrivacyService.cs
  • SysManager/SysManager/ViewModels/MainWindowViewModel.cs
  • SysManager/SysManager/ViewModels/PrivacyViewModel.cs
  • SysManager/SysManager/Views/PrivacyView.xaml
  • SysManager/SysManager/Views/PrivacyView.xaml.cs
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Analyze (csharp)
  • GitHub Check: Build & unit tests
🔇 Additional comments (8)
CHANGELOG.md (1)

9-12: LGTM!

Also applies to: 14-15, 21-21, 26-27, 29-31

SysManager/SysManager/Models/PrivacyToggle.cs (1)

14-38: LGTM!

SysManager/SysManager/Services/PrivacyService.cs (1)

22-64: LGTM!

Also applies to: 82-145, 147-280

SysManager/SysManager/ServiceRegistration.cs (1)

56-56: LGTM!

Also applies to: 88-88

SysManager/SysManager/ViewModels/PrivacyViewModel.cs (1)

31-89: LGTM!

Also applies to: 99-142

SysManager/SysManager/ViewModels/MainWindowViewModel.cs (1)

47-47: LGTM!

Also applies to: 73-73, 146-146, 194-194, 228-228, 404-404, 569-569

SysManager/SysManager/Views/PrivacyView.xaml.cs (1)

9-12: LGTM!

SysManager/SysManager/Views/PrivacyView.xaml (1)

57-69: ⚡ Quick win

Action: Paste the review comment to rewrite. Provide the full contents of the <review_comment>...</review_comment> block (including any diff snippets and file/line references) so I can rewrite it in the required format.

Comment on lines +66 to +77
/// <summary>
/// Applies all toggles in sequence. Errors on individual toggles are
/// logged but do not stop the batch.
/// </summary>
public void ApplyAll(IEnumerable<PrivacyToggle> toggles)
{
ArgumentNullException.ThrowIfNull(toggles);

foreach (var toggle in toggles)
{
ApplyToggle(toggle);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

ApplyAll can still abort despite the “continue on error” contract.

Line 67 says per-toggle failures should not stop the batch, but currently only security/access exceptions are handled in ApplyToggle. Other exceptions can still terminate the loop.

Proposed fix
 public void ApplyAll(IEnumerable<PrivacyToggle> toggles)
 {
     ArgumentNullException.ThrowIfNull(toggles);

     foreach (var toggle in toggles)
     {
-        ApplyToggle(toggle);
+        try
+        {
+            ApplyToggle(toggle);
+        }
+        catch (Exception ex)
+        {
+            Log.Error(ex, "Failed applying privacy toggle {Name}; continuing batch", toggle.Name);
+        }
     }
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
/// <summary>
/// Applies all toggles in sequence. Errors on individual toggles are
/// logged but do not stop the batch.
/// </summary>
public void ApplyAll(IEnumerable<PrivacyToggle> toggles)
{
ArgumentNullException.ThrowIfNull(toggles);
foreach (var toggle in toggles)
{
ApplyToggle(toggle);
}
/// <summary>
/// Applies all toggles in sequence. Errors on individual toggles are
/// logged but do not stop the batch.
/// </summary>
public void ApplyAll(IEnumerable<PrivacyToggle> toggles)
{
ArgumentNullException.ThrowIfNull(toggles);
foreach (var toggle in toggles)
{
try
{
ApplyToggle(toggle);
}
catch (Exception ex)
{
Log.Error(ex, "Failed applying privacy toggle {Name}; continuing batch", toggle.Name);
}
}
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@SysManager/SysManager/Services/PrivacyService.cs` around lines 66 - 77,
ApplyAll promises to log per-toggle errors and continue, but because ApplyToggle
only handles certain exception types, unexpected exceptions can abort the loop;
to fix, wrap each ApplyToggle(toggle) call inside a broad try/catch in ApplyAll
(after ArgumentNullException.ThrowIfNull) that catches Exception, logs the error
with context (including the toggle identifier) and continues to the next item;
alternatively, ensure ApplyToggle(PrivacyToggle toggle) itself catches all
exceptions, logs them, and returns without throwing — reference
ApplyAll(IEnumerable<PrivacyToggle> toggles) and ApplyToggle(PrivacyToggle
toggle) when making the change.

Comment on lines +92 to +97
private void ApplyAll()
{
_service.ApplyAll(Toggles);
StatusMessage = $"All {Toggles.Count} toggles applied.";
Log.Information("Privacy: applied all {Count} toggles", Toggles.Count);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

ApplyAll currently does not turn protections on.

ApplyAll() applies existing states only; it never flips all PrivacyToggle.IsEnabled values to true, so it can be a no-op instead of “enable all protections”.

Suggested fix
 [RelayCommand]
 private void ApplyAll()
 {
+    _suppressApply = true;
+    try
+    {
+        foreach (var toggle in Toggles)
+            toggle.IsEnabled = true;
+    }
+    finally
+    {
+        _suppressApply = false;
+    }
+
     _service.ApplyAll(Toggles);
+    UpdateStatus();
     StatusMessage = $"All {Toggles.Count} toggles applied.";
     Log.Information("Privacy: applied all {Count} toggles", Toggles.Count);
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@SysManager/SysManager/ViewModels/PrivacyViewModel.cs` around lines 92 - 97,
ApplyAll currently just reapplies current states; change it so it first sets
every PrivacyToggle.IsEnabled = true on each entry in the Toggles collection,
then call _service.ApplyAll(Toggles); update StatusMessage and Log.Information
accordingly (e.g., "All {Count} toggles enabled and applied") to reflect that
protections were turned on; touch the ApplyAll method and the Toggles iteration
(use a simple foreach over Toggles to set IsEnabled) before invoking
_service.ApplyAll.

@laurentiu021
laurentiu021 merged this pull request into main May 21, 2026
5 checks passed
@laurentiu021
laurentiu021 deleted the feat/privacy-toggles branch May 21, 2026 11:04
laurentiu021 added a commit that referenced this pull request May 22, 2026
#481)

## Summary

Fully implements the App Blocker tab, replacing the WIP placeholder.
Blocks applications from executing using the Image File Execution
Options (IFEO) registry mechanism.

## Changes

- **New**: \AppBlockerService\ — uses IFEO Debugger key to prevent app
execution. Block, unblock, check status, enumerate all blocked apps.
Fully reversible.
- **New**: \AppBlockerViewModel\ — block by name or browse, unblock
selected, refresh list, select/deselect all. Admin privilege detection.
- **New**: \BlockedApp\ model — executable name, full path, blocked
timestamp, selection state.
- **New**: \AppBlockerView.xaml\ — text input + browse, toolbar,
DataGrid.
- **Updated**: \MainWindowViewModel\ — replaced \WipAppBlocker\
placeholder with real \AppBlockerViewModel\.
- **Tests**: 5 unit tests for ViewModel and Model.

## Safety

- Confirmation dialog before block and unblock
- Admin privilege check with clear status message
- Fully reversible — unblock removes the IFEO Debugger key
- Only blocks apps marked by SysManager (checks for specific debugger
path)

Closes #378

Co-authored-by: laurentiu021 <laurentiu021@users.noreply.github.com>
laurentiu021 added a commit that referenced this pull request May 22, 2026
* Initial state

* feat: add privacy toggles for telemetry, ads, and tracking

---------

Co-authored-by: laurentiu021 <laurentiu021@users.noreply.github.com>
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.

[Enhancement]: Privacy ΓÇö Windows debloat and privacy toggles

1 participant