diff --git a/res/xml/notification_access_permission_details.xml b/res/xml/notification_access_permission_details.xml index cec383c90f7..9867b6d4c0a 100644 --- a/res/xml/notification_access_permission_details.xml +++ b/res/xml/notification_access_permission_details.xml @@ -26,7 +26,7 @@ android:layout="@layout/settings_entity_header" settings:controller="com.android.settings.applications.specialaccess.notificationaccess.HeaderPreferenceController"/> - diff --git a/src/com/android/settings/applications/specialaccess/notificationaccess/ApprovalPreferenceController.java b/src/com/android/settings/applications/specialaccess/notificationaccess/ApprovalPreferenceController.java index a43b9fd9145..0767e65bbcb 100644 --- a/src/com/android/settings/applications/specialaccess/notificationaccess/ApprovalPreferenceController.java +++ b/src/com/android/settings/applications/specialaccess/notificationaccess/ApprovalPreferenceController.java @@ -27,10 +27,10 @@ import android.os.AsyncTask; import androidx.annotation.VisibleForTesting; import androidx.preference.Preference; import androidx.preference.PreferenceFragmentCompat; -import androidx.preference.SwitchPreference; import com.android.settings.core.BasePreferenceController; import com.android.settings.overlay.FeatureFactory; +import com.android.settingslib.RestrictedSwitchPreference; public class ApprovalPreferenceController extends BasePreferenceController { @@ -78,9 +78,11 @@ public class ApprovalPreferenceController extends BasePreferenceController { @Override public void updateState(Preference pref) { - final SwitchPreference preference = (SwitchPreference) pref; + final RestrictedSwitchPreference preference = + (RestrictedSwitchPreference) pref; final CharSequence label = mPkgInfo.applicationInfo.loadLabel(mPm); - preference.setChecked(isServiceEnabled(mCn)); + final boolean isEnabled = isServiceEnabled(mCn); + preference.setChecked(isEnabled); preference.setOnPreferenceChangeListener((p, newValue) -> { final boolean access = (Boolean) newValue; if (!access) { @@ -103,6 +105,7 @@ public class ApprovalPreferenceController extends BasePreferenceController { return false; } }); + preference.updateState(mCn.getPackageName(), mPkgInfo.applicationInfo.uid, isEnabled); } public void disable(final ComponentName cn) { diff --git a/tests/robotests/src/com/android/settings/accessibility/AccessibilitySettingsTest.java b/tests/robotests/src/com/android/settings/accessibility/AccessibilitySettingsTest.java index f7c546fa015..c1950be2506 100644 --- a/tests/robotests/src/com/android/settings/accessibility/AccessibilitySettingsTest.java +++ b/tests/robotests/src/com/android/settings/accessibility/AccessibilitySettingsTest.java @@ -20,6 +20,8 @@ import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.isNull; import static org.mockito.Mockito.atLeast; @@ -31,6 +33,7 @@ import static java.util.Collections.singletonList; import android.accessibilityservice.AccessibilityServiceInfo; import android.accessibilityservice.AccessibilityShortcutInfo; +import android.app.AppOpsManager; import android.content.ComponentName; import android.content.ContentResolver; import android.content.Context; @@ -110,6 +113,8 @@ public class AccessibilitySettingsTest { @Mock private PreferenceManager mPreferenceManager; private ShadowAccessibilityManager mShadowAccessibilityManager; + @Mock + private AppOpsManager mAppOpsManager; @Before public void setup() { @@ -121,6 +126,9 @@ public class AccessibilitySettingsTest { when(mFragment.getPreferenceManager()).thenReturn(mPreferenceManager); when(mFragment.getPreferenceManager().getContext()).thenReturn(mContext); mContext.setTheme(R.style.Theme_AppCompat); + when(mContext.getSystemService(AppOpsManager.class)).thenReturn(mAppOpsManager); + when(mAppOpsManager.noteOpNoThrow(eq(AppOpsManager.OP_ACCESS_RESTRICTED_SETTINGS), + anyInt(), anyString())).thenReturn(AppOpsManager.MODE_ALLOWED); } @Test diff --git a/tests/unit/src/com/android/settings/applications/specialaccess/notificationaccess/ApprovalPreferenceControllerTest.java b/tests/unit/src/com/android/settings/applications/specialaccess/notificationaccess/ApprovalPreferenceControllerTest.java index 064f8134c67..249b713987c 100644 --- a/tests/unit/src/com/android/settings/applications/specialaccess/notificationaccess/ApprovalPreferenceControllerTest.java +++ b/tests/unit/src/com/android/settings/applications/specialaccess/notificationaccess/ApprovalPreferenceControllerTest.java @@ -18,12 +18,15 @@ package com.android.settings.applications.specialaccess.notificationaccess; import static com.google.common.truth.Truth.assertThat; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import android.app.AppOpsManager; import android.app.NotificationManager; import android.content.ComponentName; import android.content.Context; @@ -31,12 +34,12 @@ import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; -import androidx.preference.SwitchPreference; import androidx.test.core.app.ApplicationProvider; import androidx.test.ext.junit.runners.AndroidJUnit4; import com.android.internal.logging.nano.MetricsProto; import com.android.settings.testutils.FakeFeatureFactory; +import com.android.settingslib.RestrictedSwitchPreference; import org.junit.Before; import org.junit.Test; @@ -55,6 +58,8 @@ public class ApprovalPreferenceControllerTest { @Mock NotificationManager mNm; @Mock + AppOpsManager mAppOpsManager; + @Mock PackageManager mPm; PackageInfo mPkgInfo; ComponentName mCn = new ComponentName("a", "b"); @@ -75,15 +80,47 @@ public class ApprovalPreferenceControllerTest { mController.setNm(mNm); mController.setParent(mFragment); mController.setPkgInfo(mPkgInfo); + } @Test public void updateState_checked() { + when(mAppOpsManager.noteOpNoThrow(anyInt(), anyInt(), anyString())).thenReturn( + AppOpsManager.MODE_ALLOWED); when(mNm.isNotificationListenerAccessGranted(mCn)).thenReturn(true); - SwitchPreference pref = new SwitchPreference(mContext); + RestrictedSwitchPreference pref = new RestrictedSwitchPreference( + mContext); + pref.setAppOps(mAppOpsManager); mController.updateState(pref); assertThat(pref.isChecked()).isTrue(); + assertThat(pref.isEnabled()).isTrue(); + } + + @Test + public void restrictedSettings_appOpsDisabled() { + when(mAppOpsManager.noteOpNoThrow(anyInt(), anyInt(), anyString())).thenReturn( + AppOpsManager.MODE_ERRORED); + when(mNm.isNotificationListenerAccessGranted(mCn)).thenReturn(false); + RestrictedSwitchPreference pref = new RestrictedSwitchPreference( + mContext); + pref.setAppOps(mAppOpsManager); + + mController.updateState(pref); + assertThat(pref.isEnabled()).isFalse(); + } + + @Test + public void restrictedSettings_serviceAlreadyEnabled() { + when(mAppOpsManager.noteOpNoThrow(anyInt(), anyInt(), anyString())).thenReturn( + AppOpsManager.MODE_ERRORED); + when(mNm.isNotificationListenerAccessGranted(mCn)).thenReturn(true); + RestrictedSwitchPreference pref = new RestrictedSwitchPreference( + mContext); + pref.setAppOps(mAppOpsManager); + + mController.updateState(pref); + assertThat(pref.isEnabled()).isTrue(); } @Test