Loading res/values/strings.xml +6 −0 Original line number Diff line number Diff line Loading @@ -12922,4 +12922,10 @@ <!-- Label for extra app info settings for a specific app [CHAR LIMIT=40] --> <string name="extra_app_info_label" translatable="false"></string> <!-- Title for toggle controlling whether notifications are shown when an app pastes from clipboard. [CHAR LIMIT=50] --> <string name="show_clip_access_notification">Copy & paste notifications</string> <!-- Summary for toggle controlling whether notifications are shown when an app pastes from clipboard. [CHAR LIMIT=NONE] --> <string name="show_clip_access_notification_summary">Show a message when apps access text or data you have copied</string> </resources> res/xml/privacy_dashboard_settings.xml +7 −0 Original line number Diff line number Diff line Loading @@ -116,4 +116,11 @@ settings:controller="com.android.settings.privacy.EnableContentCaptureWithServiceSettingsPreferenceController"> </com.android.settings.widget.PrimarySwitchPreference> <!-- Clipboard access notifications --> <SwitchPreference android:key="show_clip_access_notification" android:title="@string/show_clip_access_notification" android:summary="@string/show_clip_access_notification_summary" settings:controller="com.android.settings.privacy.ShowClipAccessNotificationPreferenceController"/> </PreferenceScreen> src/com/android/settings/privacy/ShowClipAccessNotificationPreferenceController.java 0 → 100644 +54 −0 Original line number Diff line number Diff line /* * Copyright (C) 2021 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.privacy; import android.content.Context; import android.provider.Settings; import com.android.settings.core.TogglePreferenceController; /** * Controller for preference to toggle whether clipboard access notifications should be shown. */ public class ShowClipAccessNotificationPreferenceController extends TogglePreferenceController { private static final String KEY_SHOW_CLIP_ACCESS_NOTIFICATION = "show_clip_access_notification"; public ShowClipAccessNotificationPreferenceController(Context context) { super(context, KEY_SHOW_CLIP_ACCESS_NOTIFICATION); } @Override public boolean isChecked() { // TODO(b/182349993) Retrieve default value from DeviceConfig. return Settings.Secure.getInt(mContext.getContentResolver(), Settings.Secure.CLIPBOARD_SHOW_ACCESS_NOTIFICATIONS, 1) != 0; } @Override public boolean setChecked(boolean isChecked) { Settings.Secure.putInt(mContext.getContentResolver(), Settings.Secure.CLIPBOARD_SHOW_ACCESS_NOTIFICATIONS, isChecked ? 1 : 0); return true; } @Override public int getAvailabilityStatus() { return AVAILABLE; } } tests/robotests/src/com/android/settings/privacy/ShowClipAccessNotificationPreferenceControllerTest.java 0 → 100644 +102 −0 Original line number Diff line number Diff line /* * Copyright (C) 2021 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.privacy; import static com.google.common.truth.Truth.assertThat; import android.content.ContentResolver; import android.content.Context; import android.provider.Settings; import android.provider.Settings.SettingNotFoundException; import androidx.preference.Preference; import androidx.preference.PreferenceScreen; import androidx.test.core.app.ApplicationProvider; 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; @RunWith(RobolectricTestRunner.class) public class ShowClipAccessNotificationPreferenceControllerTest { @Mock private PreferenceScreen mScreen; private Context mContext; private ShowClipAccessNotificationPreferenceController mController; private Preference mPreference; @Before public void setUp() { MockitoAnnotations.initMocks(this); mContext = ApplicationProvider.getApplicationContext(); mController = new ShowClipAccessNotificationPreferenceController(mContext); mPreference = new Preference(mContext); mPreference.setKey(mController.getPreferenceKey()); } @Test public void isChecked_settingIsOff_shouldReturnFalse() throws Exception { setProperty(0); assertThat(mController.isChecked()).isFalse(); } @Test public void isChecked_settingIsOn_shouldReturnTrue() throws Exception { setProperty(1); assertThat(mController.isChecked()).isTrue(); } @Test public void onPreferenceChange_turnOn_shouldChangeSettingTo1() throws Exception { setProperty(0); mController.onPreferenceChange(mPreference, true); assertThat(mController.isChecked()).isTrue(); assertProperty(1); } @Test public void onPreferenceChange_turnOff_shouldChangeSettingTo0() throws Exception { setProperty(1); mController.onPreferenceChange(mPreference, false); assertThat(mController.isChecked()).isFalse(); assertProperty(0); } private void setProperty(int newValue) { final ContentResolver contentResolver = mContext.getContentResolver(); Settings.Secure.putInt( contentResolver, Settings.Secure.CLIPBOARD_SHOW_ACCESS_NOTIFICATIONS, newValue); } private void assertProperty(int expectedValue) throws SettingNotFoundException { final ContentResolver contentResolver = mContext.getContentResolver(); assertThat(Settings.Secure.getInt( contentResolver, Settings.Secure.CLIPBOARD_SHOW_ACCESS_NOTIFICATIONS)) .isEqualTo(expectedValue); } } Loading
res/values/strings.xml +6 −0 Original line number Diff line number Diff line Loading @@ -12922,4 +12922,10 @@ <!-- Label for extra app info settings for a specific app [CHAR LIMIT=40] --> <string name="extra_app_info_label" translatable="false"></string> <!-- Title for toggle controlling whether notifications are shown when an app pastes from clipboard. [CHAR LIMIT=50] --> <string name="show_clip_access_notification">Copy & paste notifications</string> <!-- Summary for toggle controlling whether notifications are shown when an app pastes from clipboard. [CHAR LIMIT=NONE] --> <string name="show_clip_access_notification_summary">Show a message when apps access text or data you have copied</string> </resources>
res/xml/privacy_dashboard_settings.xml +7 −0 Original line number Diff line number Diff line Loading @@ -116,4 +116,11 @@ settings:controller="com.android.settings.privacy.EnableContentCaptureWithServiceSettingsPreferenceController"> </com.android.settings.widget.PrimarySwitchPreference> <!-- Clipboard access notifications --> <SwitchPreference android:key="show_clip_access_notification" android:title="@string/show_clip_access_notification" android:summary="@string/show_clip_access_notification_summary" settings:controller="com.android.settings.privacy.ShowClipAccessNotificationPreferenceController"/> </PreferenceScreen>
src/com/android/settings/privacy/ShowClipAccessNotificationPreferenceController.java 0 → 100644 +54 −0 Original line number Diff line number Diff line /* * Copyright (C) 2021 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.privacy; import android.content.Context; import android.provider.Settings; import com.android.settings.core.TogglePreferenceController; /** * Controller for preference to toggle whether clipboard access notifications should be shown. */ public class ShowClipAccessNotificationPreferenceController extends TogglePreferenceController { private static final String KEY_SHOW_CLIP_ACCESS_NOTIFICATION = "show_clip_access_notification"; public ShowClipAccessNotificationPreferenceController(Context context) { super(context, KEY_SHOW_CLIP_ACCESS_NOTIFICATION); } @Override public boolean isChecked() { // TODO(b/182349993) Retrieve default value from DeviceConfig. return Settings.Secure.getInt(mContext.getContentResolver(), Settings.Secure.CLIPBOARD_SHOW_ACCESS_NOTIFICATIONS, 1) != 0; } @Override public boolean setChecked(boolean isChecked) { Settings.Secure.putInt(mContext.getContentResolver(), Settings.Secure.CLIPBOARD_SHOW_ACCESS_NOTIFICATIONS, isChecked ? 1 : 0); return true; } @Override public int getAvailabilityStatus() { return AVAILABLE; } }
tests/robotests/src/com/android/settings/privacy/ShowClipAccessNotificationPreferenceControllerTest.java 0 → 100644 +102 −0 Original line number Diff line number Diff line /* * Copyright (C) 2021 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.privacy; import static com.google.common.truth.Truth.assertThat; import android.content.ContentResolver; import android.content.Context; import android.provider.Settings; import android.provider.Settings.SettingNotFoundException; import androidx.preference.Preference; import androidx.preference.PreferenceScreen; import androidx.test.core.app.ApplicationProvider; 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; @RunWith(RobolectricTestRunner.class) public class ShowClipAccessNotificationPreferenceControllerTest { @Mock private PreferenceScreen mScreen; private Context mContext; private ShowClipAccessNotificationPreferenceController mController; private Preference mPreference; @Before public void setUp() { MockitoAnnotations.initMocks(this); mContext = ApplicationProvider.getApplicationContext(); mController = new ShowClipAccessNotificationPreferenceController(mContext); mPreference = new Preference(mContext); mPreference.setKey(mController.getPreferenceKey()); } @Test public void isChecked_settingIsOff_shouldReturnFalse() throws Exception { setProperty(0); assertThat(mController.isChecked()).isFalse(); } @Test public void isChecked_settingIsOn_shouldReturnTrue() throws Exception { setProperty(1); assertThat(mController.isChecked()).isTrue(); } @Test public void onPreferenceChange_turnOn_shouldChangeSettingTo1() throws Exception { setProperty(0); mController.onPreferenceChange(mPreference, true); assertThat(mController.isChecked()).isTrue(); assertProperty(1); } @Test public void onPreferenceChange_turnOff_shouldChangeSettingTo0() throws Exception { setProperty(1); mController.onPreferenceChange(mPreference, false); assertThat(mController.isChecked()).isFalse(); assertProperty(0); } private void setProperty(int newValue) { final ContentResolver contentResolver = mContext.getContentResolver(); Settings.Secure.putInt( contentResolver, Settings.Secure.CLIPBOARD_SHOW_ACCESS_NOTIFICATIONS, newValue); } private void assertProperty(int expectedValue) throws SettingNotFoundException { final ContentResolver contentResolver = mContext.getContentResolver(); assertThat(Settings.Secure.getInt( contentResolver, Settings.Secure.CLIPBOARD_SHOW_ACCESS_NOTIFICATIONS)) .isEqualTo(expectedValue); } }