Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -13894,6 +13894,12 @@
<!-- Developer settings: Summary for disable app and notification screen share protections summary [CHAR LIMIT=150] -->
<string name="disable_screen_share_protections_for_apps_and_notifications_summary">Turn off system protections for sensitive app content for upcoming screen share sessions</string>


<!-- Developer settings: Title for enabling screenshots in all apps [CHAR LIMIT=50] -->
<string name="disable_secure_windows">Enable screenshots in all apps</string>
<!-- Developer settings: Summary for enabling screenshots in all apps [CHAR LIMIT=150] -->
<string name="disable_secure_windows_summary">Allow screenshots and screen recording in apps that normally prevent it</string>

<!-- Title for media control settings [CHAR LIMIT=50]-->
<string name="media_controls_title">Media</string>
<!-- Title of toggle to enable or disable the media resumption feature in quick settings [CHAR LIMIT=50]-->
Expand Down
5 changes: 5 additions & 0 deletions res/xml/development_settings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -740,6 +740,11 @@
android:title="@string/disable_screen_share_protections_for_apps_and_notifications"
android:summary="@string/disable_screen_share_protections_for_apps_and_notifications_summary" />

<SwitchPreferenceCompat
android:key="force_screenshot_secure_windows"
android:title="@string/disable_secure_windows"
android:summary="@string/disable_secure_windows_summary" />

<Preference
android:key="asst_importance_reset"
android:title="@string/asst_importance_reset_title"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -847,6 +847,7 @@ private static List<AbstractPreferenceController> buildPreferenceControllers(Con
controllers.add(new ForceEnableNotesRolePreferenceController(context));
controllers.add(new GrammaticalGenderPreferenceController(context));
controllers.add(new SensitiveContentProtectionPreferenceController(context));
controllers.add(new DisableSecureWindowsPreferenceController(context));
controllers.add(new ShadeDisplayAwarenessPreferenceController(context));
controllers.add(new TextCursorBlinkRatePreferenceController(context));

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package com.android.settings.development;

import android.content.Context;
import android.provider.Settings;
import androidx.preference.Preference;
import androidx.preference.SwitchPreferenceCompat;
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settingslib.development.DeveloperOptionsPreferenceController;

public class DisableSecureWindowsPreferenceController
extends DeveloperOptionsPreferenceController
implements Preference.OnPreferenceChangeListener, PreferenceControllerMixin {

private static final String KEY = "force_screenshot_secure_windows";

public DisableSecureWindowsPreferenceController(Context context) {
super(context);
}

@Override
public String getPreferenceKey() {
return KEY;
}

@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
Settings.Secure.putInt(mContext.getContentResolver(),
Settings.Secure.FORCE_SCREENSHOT_SECURE_WINDOWS,
(Boolean) newValue ? 1 : 0);
return true;
}

@Override
public void updateState(Preference preference) {
final int value = Settings.Secure.getInt(mContext.getContentResolver(),
Settings.Secure.FORCE_SCREENSHOT_SECURE_WINDOWS, 0);
((SwitchPreferenceCompat) preference).setChecked(value != 0);
}

@Override
protected void onDeveloperOptionsSwitchDisabled() {
super.onDeveloperOptionsSwitchDisabled();
Settings.Secure.putInt(mContext.getContentResolver(),
Settings.Secure.FORCE_SCREENSHOT_SECURE_WINDOWS, 0);
((SwitchPreferenceCompat) mPreference).setChecked(false);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
/*
* Copyright (C) 2026 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.android.settings.development;

import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static com.google.common.truth.Truth.assertThat;

import android.content.Context;
import android.provider.Settings;

import androidx.preference.PreferenceScreen;
import androidx.preference.SwitchPreferenceCompat;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;

@RunWith(RobolectricTestRunner.class)
public class DisableSecureWindowsPreferenceControllerTest {

@Mock
private SwitchPreferenceCompat mPreference;
@Mock
private PreferenceScreen mScreen;

private Context mContext;
private DisableSecureWindowsPreferenceController mController;

@Before
public void setup() {
MockitoAnnotations.initMocks(this);
mContext = RuntimeEnvironment.application;
mController = new DisableSecureWindowsPreferenceController(mContext);
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
mController.displayPreference(mScreen);
}

@Test
public void onPreferenceChange_settingEnabled_shouldSetSettingToOne() {
mController.onPreferenceChange(mPreference, true);

assertThat(Settings.Secure.getInt(mContext.getContentResolver(),
Settings.Secure.FORCE_SCREENSHOT_SECURE_WINDOWS, 0)).isEqualTo(1);
}

@Test
public void onPreferenceChange_settingDisabled_shouldSetSettingToZero() {
mController.onPreferenceChange(mPreference, false);

assertThat(Settings.Secure.getInt(mContext.getContentResolver(),
Settings.Secure.FORCE_SCREENSHOT_SECURE_WINDOWS, 0)).isEqualTo(0);
}

@Test
public void updateState_settingEnabled_shouldCheckPreference() {
Settings.Secure.putInt(mContext.getContentResolver(),
Settings.Secure.FORCE_SCREENSHOT_SECURE_WINDOWS, 1);

mController.updateState(mPreference);

verify(mPreference).setChecked(true);
}

@Test
public void updateState_settingDisabled_shouldUncheckPreference() {
Settings.Secure.putInt(mContext.getContentResolver(),
Settings.Secure.FORCE_SCREENSHOT_SECURE_WINDOWS, 0);

mController.updateState(mPreference);

verify(mPreference).setChecked(false);
}

@Test
public void onDeveloperOptionsSwitchDisabled_shouldResetSettingAndUncheck() {
Settings.Secure.putInt(mContext.getContentResolver(),
Settings.Secure.FORCE_SCREENSHOT_SECURE_WINDOWS, 1);

mController.onDeveloperOptionsSwitchDisabled();

assertThat(Settings.Secure.getInt(mContext.getContentResolver(),
Settings.Secure.FORCE_SCREENSHOT_SECURE_WINDOWS, 1)).isEqualTo(0);
verify(mPreference).setChecked(false);
}
}