Snap for 12974810 from 3c357edc9f to 25Q2-release

Change-Id: Ibb94a1b7fa87a14d4491bef852d4db295a1ed997
This commit is contained in:
Android Build Coastguard Worker
2025-01-27 16:18:43 -08:00
14 changed files with 544 additions and 26 deletions

View File

@@ -8847,6 +8847,13 @@
<!-- App Info > Notifications: Title for section where notifications bundles can be configured [CHAR LIMIT=80]-->
<string name="notification_bundles">Notification bundles</string>
<!-- App Info > Notifications: Title for section where notifications summaries can be configured [CHAR LIMIT=80]-->
<string name="notification_summarization_title">Notification summaries</string>
<string name="notification_summarization_on">On</string>
<string name="notification_summarization_off">Off</string>
<string name="notification_summarization_main_control_title">Use notification summaries</string>
<string name="notification_summarization_description">Automatically summarize conversation notifications from any app</string>
<!-- App Info > Notifications: Title for section controlling whether this app may show notifications in a promoted format [CHAR LIMIT=80] -->
<string name="live_notifications">Live notifications</string>
<!-- App Info > Notifications: Text on the switch to enable or disable an app from showing notifications in a live/promoted format [CHAR LIMIT=50] -->
@@ -9269,7 +9276,6 @@
<string name="notification_bundle_main_control_title">Use notification bundling</string>
<string name="notification_bundle_description">Notifications with similar themes will be silenced and grouped together for a quieter experience. Bundling will override an app\'s own notification settings.</string>
<!-- Title for managing VR (virtual reality) helper services. [CHAR LIMIT=50] -->
<string name="vr_listeners_title">VR helper services</string>

View File

@@ -25,7 +25,7 @@
<!-- See all apps button -->
<Preference
android:key="all_notifications"
android:order="10"
android:order="1"
android:title="@string/app_notification_field"
android:summary="@string/app_notification_field_summary"
android:fragment="com.android.settings.applications.manageapplications.ManageApplications">
@@ -35,7 +35,7 @@
</Preference>
<Preference
android:key="notification_history"
android:order="11"
android:order="2"
android:title="@string/notification_history"
android:summary="@string/notification_history_summary">
<intent
@@ -44,11 +44,19 @@
android:targetClass="com.android.settings.notification.history.NotificationHistoryActivity" />
</Preference>
<Preference
android:fragment="com.android.settings.notification.SummarizationPreferenceFragment"
android:key="summarization_notifications_preference"
android:order="3"
android:persistent="false"
android:title="@string/notification_summarization_title"
settings:controller="com.android.settings.notification.SummarizationPreferenceController" />
<Preference
android:fragment="com.android.settings.notification.BundlePreferenceFragment"
android:key="bundle_notifications_preference"
android:persistent="false"
android:order="12"
android:order="4"
android:title="@string/notification_bundle_title"
settings:controller="com.android.settings.notification.BundlePreferenceController" />
</PreferenceCategory>

View File

@@ -49,7 +49,7 @@
android:title="@string/trackpad_pointer_speed"
android:order="40"
android:selectable="false"
settings:controller="com.android.settings.inputmethod.TrackpadPointerSpeedPreferenceController"/>
settings:controller="com.android.settings.inputmethod.TouchpadPointerSpeedPreferenceController"/>
<Preference
android:fragment="com.android.settings.inputmethod.PointerTouchpadFragment"

View File

@@ -0,0 +1,39 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2025 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.
-->
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:settings="http://schemas.android.com/apk/res-auto"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:title="@string/notification_summarization_title">
<com.android.settingslib.widget.IllustrationPreference
android:key="illustration"
settings:searchable="false"
android:selectable="false"
app:lottie_cacheComposition="false"
settings:dynamicColor="true"/>
<com.android.settingslib.widget.TopIntroPreference
android:key="feature_description"
settings:searchable="false"
android:title="@string/notification_summarization_description"/>
<com.android.settingslib.widget.MainSwitchPreference
android:key="global_pref"
android:title="@string/notification_summarization_main_control_title"
settings:controller="com.android.settings.notification.SummarizationGlobalPreferenceController" />
</PreferenceScreen>

View File

@@ -44,11 +44,16 @@ public class ZenAccessDetails extends AppInfoWithHeader implements
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.zen_access_permission_details);
getSettingsLifecycle().addObserver(
new ZenAccessSettingObserverMixin(getContext(), this /* listener */));
}
@Override
public void onResume() {
super.onResume();
requireActivity().setTitle(Flags.modesApi() && Flags.modesUi()
? R.string.manage_zen_modes_access_title
: R.string.manage_zen_access_title);
getSettingsLifecycle().addObserver(
new ZenAccessSettingObserverMixin(getContext(), this /* listener */));
}
@Override

View File

@@ -17,6 +17,7 @@
package com.android.settings.biometrics;
import android.app.admin.DevicePolicyManager;
import android.app.supervision.SupervisionManager;
import android.content.ComponentName;
import android.content.Context;
import android.hardware.biometrics.BiometricAuthenticator;
@@ -44,6 +45,7 @@ public class ParentalControlsUtils {
* {@link android.hardware.biometrics.ParentalControlsUtilsInternal#getTestComponentName}
* @return non-null EnforcedAdmin if parental consent is required
*/
@Nullable
public static RestrictedLockUtils.EnforcedAdmin parentConsentRequired(@NonNull Context context,
@BiometricAuthenticator.Modality int modality) {
@@ -58,7 +60,11 @@ public class ParentalControlsUtils {
}
final DevicePolicyManager dpm = context.getSystemService(DevicePolicyManager.class);
return parentConsentRequiredInternal(dpm, modality, userHandle);
final SupervisionManager sm =
android.app.supervision.flags.Flags.deprecateDpmSupervisionApis()
? context.getSystemService(SupervisionManager.class)
: null;
return parentConsentRequiredInternal(dpm, sm, modality, userHandle);
}
/**
@@ -68,16 +74,23 @@ public class ParentalControlsUtils {
@Nullable
@VisibleForTesting
static RestrictedLockUtils.EnforcedAdmin parentConsentRequiredInternal(
@NonNull DevicePolicyManager dpm, @BiometricAuthenticator.Modality int modality,
@NonNull DevicePolicyManager dpm,
@Nullable SupervisionManager sm,
@BiometricAuthenticator.Modality int modality,
@NonNull UserHandle userHandle) {
if (ParentalControlsUtilsInternal.parentConsentRequired(dpm, modality,
userHandle)) {
if (!ParentalControlsUtilsInternal.parentConsentRequired(
dpm, sm, modality, userHandle)) {
return null;
}
if (android.app.supervision.flags.Flags.deprecateDpmSupervisionApis()) {
// Supervision doesn't necessarily have have an admin component.
return new RestrictedLockUtils.EnforcedAdmin(
/* component= */ null, UserManager.DISALLOW_BIOMETRIC, userHandle);
} else {
final ComponentName cn =
ParentalControlsUtilsInternal.getSupervisionComponentName(dpm, userHandle);
return new RestrictedLockUtils.EnforcedAdmin(cn, UserManager.DISALLOW_BIOMETRIC,
userHandle);
} else {
return null;
}
}
}

View File

@@ -687,6 +687,37 @@ public class NotificationBackend {
}
}
public boolean isNotificationSummarizationSupported() {
try {
return !sINM.getUnsupportedAdjustmentTypes().contains(Adjustment.KEY_SUMMARIZATION);
} catch (Exception e) {
Log.w(TAG, "Error calling NoMan", e);
}
return false;
}
public boolean isNotificationSummarizationEnabled(Context context) {
try {
return sINM.getAllowedAssistantAdjustments(context.getPackageName())
.contains(Adjustment.KEY_SUMMARIZATION);
} catch (Exception e) {
Log.w(TAG, "Error calling NoMan", e);
}
return false;
}
public void setNotificationSummarizationEnabled(boolean enabled) {
try {
if (enabled) {
sINM.allowAssistantAdjustment(Adjustment.KEY_SUMMARIZATION);
} else {
sINM.disallowAssistantAdjustment(Adjustment.KEY_SUMMARIZATION);
}
} catch (Exception e) {
Log.w(TAG, "Error calling NoMan", e);
}
}
public boolean isBundleTypeApproved(@Adjustment.Types int type) {
try {
int[] approved = sINM.getAllowedAdjustmentKeyTypes();

View File

@@ -0,0 +1,62 @@
/*
* Copyright (C) 2025 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.notification;
import android.app.Flags;
import android.content.Context;
import androidx.annotation.NonNull;
import com.android.settings.widget.SettingsMainSwitchPreferenceController;
public class SummarizationGlobalPreferenceController extends
SettingsMainSwitchPreferenceController {
NotificationBackend mBackend;
public SummarizationGlobalPreferenceController(@NonNull Context context,
@NonNull String preferenceKey) {
super(context, preferenceKey);
mBackend = new NotificationBackend();
}
@Override
public int getAvailabilityStatus() {
if ((Flags.nmSummarization() || Flags.nmSummarizationUi())
&& mBackend.isNotificationSummarizationSupported()) {
return AVAILABLE;
}
return CONDITIONALLY_UNAVAILABLE;
}
@Override
public boolean isChecked() {
return mBackend.isNotificationSummarizationEnabled(mContext);
}
@Override
public boolean setChecked(boolean isChecked) {
mBackend.setNotificationSummarizationEnabled(isChecked);
return true;
}
@Override
public int getSliceHighlightMenuRes() {
// not needed since it's not sliceable
return NO_RES;
}
}

View File

@@ -0,0 +1,50 @@
/*
* Copyright (C) 2025 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.notification;
import android.app.Flags;
import android.content.Context;
import com.android.settings.R;
import com.android.settings.core.BasePreferenceController;
/**
* Controller for the summarized notifications settings page.
*/
public class SummarizationPreferenceController extends BasePreferenceController {
NotificationBackend mBackend;
public SummarizationPreferenceController(Context context, String preferenceKey) {
super(context, preferenceKey);
mBackend = new NotificationBackend();
}
@Override
public int getAvailabilityStatus() {
return (Flags.nmSummarization() || Flags.nmSummarizationUi())
&& mBackend.isNotificationSummarizationSupported()
? AVAILABLE : CONDITIONALLY_UNAVAILABLE;
}
@Override
public CharSequence getSummary() {
return mBackend.isNotificationSummarizationEnabled(mContext)
? mContext.getString(R.string.notification_summarization_on)
: mContext.getString(R.string.notification_summarization_off);
}
}

View File

@@ -0,0 +1,56 @@
/*
* Copyright (C) 2025 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.notification;
import android.app.Flags;
import android.app.settings.SettingsEnums;
import android.content.Context;
import com.android.settings.R;
import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settingslib.search.SearchIndexable;
/**
* Fragment for summarized notifications.
*/
@SearchIndexable(forTarget = SearchIndexable.ALL & ~SearchIndexable.ARC)
public class SummarizationPreferenceFragment extends DashboardFragment {
@Override
public int getMetricsCategory() {
return SettingsEnums.SUMMARIZED_NOTIFICATIONS;
}
@Override
protected int getPreferenceScreenResId() {
return R.xml.summarization_notifications_settings;
}
@Override
protected String getLogTag() {
return "SummarizationPreferenceFragment";
}
public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
new BaseSearchIndexProvider(R.xml.summarization_notifications_settings) {
@Override
protected boolean isPageSearchEnabled(Context context) {
return Flags.notificationClassificationUi();
}
};
}

View File

@@ -69,9 +69,6 @@ public class ZenAccessSettings extends EmptyTextSettings implements
mContext = getActivity();
mPkgMan = mContext.getPackageManager();
mNoMan = mContext.getSystemService(NotificationManager.class);
requireActivity().setTitle(Flags.modesApi() && Flags.modesUi()
? R.string.manage_zen_modes_access_title
: R.string.manage_zen_access_title);
getSettingsLifecycle().addObserver(
new ZenAccessSettingObserverMixin(getContext(), this /* listener */));
}
@@ -92,6 +89,9 @@ public class ZenAccessSettings extends EmptyTextSettings implements
@Override
public void onResume() {
super.onResume();
requireActivity().setTitle(Flags.modesApi() && Flags.modesUi()
? R.string.manage_zen_modes_access_title
: R.string.manage_zen_access_title);
reloadList();
}

View File

@@ -0,0 +1,100 @@
/*
* Copyright (C) 2025 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.notification;
import static android.service.notification.Adjustment.KEY_IMPORTANCE;
import static android.service.notification.Adjustment.KEY_SUMMARIZATION;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.app.Flags;
import android.app.INotificationManager;
import android.content.Context;
import android.platform.test.flag.junit.SetFlagsRule;
import org.junit.Before;
import org.junit.Rule;
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;
import java.util.List;
@RunWith(RobolectricTestRunner.class)
public class SummarizationGlobalPreferenceControllerTest {
@Rule
public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
private static final String PREFERENCE_KEY = "preference_key";
private Context mContext;
SummarizationGlobalPreferenceController mController;
@Mock
INotificationManager mInm;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mContext = RuntimeEnvironment.application;
mSetFlagsRule.enableFlags(Flags.FLAG_NM_SUMMARIZATION, Flags.FLAG_NM_SUMMARIZATION_UI);
mController = new SummarizationGlobalPreferenceController(mContext, PREFERENCE_KEY);
mController.mBackend.setNm(mInm);
}
@Test
public void isAvailable_flagEnabledNasSupports_shouldReturnTrue() {
assertThat(mController.isAvailable()).isTrue();
}
@Test
public void isAvailable_flagEnabledNasDoesNotSupport_shouldReturnFalse() throws Exception {
when(mInm.getUnsupportedAdjustmentTypes()).thenReturn(List.of(KEY_SUMMARIZATION));
assertThat(mController.isAvailable()).isFalse();
}
@Test
public void isAvailable_flagDisabledNasSupports_shouldReturnFalse() {
mSetFlagsRule.disableFlags(Flags.FLAG_NM_SUMMARIZATION);
mSetFlagsRule.disableFlags(Flags.FLAG_NM_SUMMARIZATION_UI);
assertThat(mController.isAvailable()).isFalse();
}
@Test
public void isChecked() throws Exception {
when(mInm.getAllowedAssistantAdjustments(any())).thenReturn(List.of(KEY_SUMMARIZATION));
assertThat(mController.isChecked()).isTrue();
when(mInm.getAllowedAssistantAdjustments(any())).thenReturn(List.of(KEY_IMPORTANCE));
assertThat(mController.isChecked()).isFalse();
}
@Test
public void setChecked() throws Exception {
mController.setChecked(false);
verify(mInm).disallowAssistantAdjustment(KEY_SUMMARIZATION);
mController.setChecked(true);
verify(mInm).allowAssistantAdjustment(KEY_SUMMARIZATION);
}
}

View File

@@ -0,0 +1,90 @@
/*
* Copyright (C) 2025 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.notification;
import static android.service.notification.Adjustment.KEY_IMPORTANCE;
import static android.service.notification.Adjustment.KEY_SUMMARIZATION;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.when;
import android.app.Flags;
import android.app.INotificationManager;
import android.content.Context;
import android.platform.test.flag.junit.SetFlagsRule;
import org.junit.Before;
import org.junit.Rule;
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;
import java.util.List;
@RunWith(RobolectricTestRunner.class)
public class SummarizationPreferenceControllerTest {
@Rule
public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
private static final String PREFERENCE_KEY = "preference_key";
private Context mContext;
SummarizationPreferenceController mController;
@Mock
INotificationManager mInm;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mContext = RuntimeEnvironment.application;
mSetFlagsRule.enableFlags(Flags.FLAG_NM_SUMMARIZATION, Flags.FLAG_NM_SUMMARIZATION_UI);
mController = new SummarizationPreferenceController(mContext, PREFERENCE_KEY);
mController.mBackend.setNm(mInm);
}
@Test
public void isAvailable_flagEnabledNasSupports_shouldReturnTrue() {
assertThat(mController.isAvailable()).isTrue();
}
@Test
public void isAvailable_flagEnabledNasDoesNotSupport_shouldReturnFalse() throws Exception {
when(mInm.getUnsupportedAdjustmentTypes()).thenReturn(List.of(KEY_SUMMARIZATION));
assertThat(mController.isAvailable()).isFalse();
}
@Test
public void isAvailable_flagDisabledNasSupports_shouldReturnFalse() {
mSetFlagsRule.disableFlags(Flags.FLAG_NM_SUMMARIZATION);
mSetFlagsRule.disableFlags(Flags.FLAG_NM_SUMMARIZATION_UI);
assertThat(mController.isAvailable()).isFalse();
}
@Test
public void getSummary() throws Exception {
when(mInm.getAllowedAssistantAdjustments(any())).thenReturn(List.of(KEY_SUMMARIZATION));
assertThat(mController.getSummary()).isEqualTo("On");
when(mInm.getAllowedAssistantAdjustments(any())).thenReturn(List.of(KEY_IMPORTANCE));
assertThat(mController.getSummary()).isEqualTo("Off");
}
}

View File

@@ -16,26 +16,32 @@
package com.android.settings.biometrics;
import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FACE;
import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FINGERPRINT;
import static android.hardware.biometrics.BiometricAuthenticator.TYPE_IRIS;
import static junit.framework.TestCase.assertNotNull;
import static junit.framework.TestCase.assertNull;
import static org.junit.Assert.assertEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import android.app.admin.DevicePolicyManager;
import android.app.supervision.SupervisionManager;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FACE;
import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FINGERPRINT;
import static android.hardware.biometrics.BiometricAuthenticator.TYPE_IRIS;
import android.hardware.biometrics.BiometricAuthenticator;
import android.os.UserHandle;
import android.os.UserManager;
import android.platform.test.annotations.RequiresFlagsDisabled;
import android.platform.test.annotations.RequiresFlagsEnabled;
import android.platform.test.flag.junit.CheckFlagsRule;
import android.platform.test.flag.junit.DeviceFlagsValueProvider;
import androidx.annotation.Nullable;
import androidx.test.ext.junit.runners.AndroidJUnit4;
@@ -43,6 +49,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.android.settingslib.RestrictedLockUtils;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
@@ -50,11 +57,12 @@ import org.mockito.MockitoAnnotations;
@RunWith(AndroidJUnit4.class)
public class ParentalControlsUtilsTest {
@Rule public final CheckFlagsRule checkFlags = DeviceFlagsValueProvider.createCheckFlagsRule();
@Mock private Context mContext;
@Mock private DevicePolicyManager mDpm;
@Mock private SupervisionManager mSm;
@Mock
private Context mContext;
@Mock
private DevicePolicyManager mDpm;
private ComponentName mSupervisionComponentName = new ComponentName("pkg", "cls");
@Before
@@ -76,11 +84,28 @@ public class ParentalControlsUtilsTest {
when(mDpm.getKeyguardDisabledFeatures(eq(supervisionComponentName)))
.thenReturn(keyguardDisabledFlags);
return ParentalControlsUtils.parentConsentRequiredInternal(mDpm, modality,
new UserHandle(UserHandle.myUserId()));
return ParentalControlsUtils.parentConsentRequiredInternal(
mDpm, mSm, modality, new UserHandle(UserHandle.myUserId()));
}
/**
* Helper that sets the appropriate mocks and testing behavior before returning the actual
* EnforcedAdmin from ParentalControlsUtils.
*/
@Nullable
private RestrictedLockUtils.EnforcedAdmin getEnforcedAdminForSupervision(
boolean supervisionEnabled,
@BiometricAuthenticator.Modality int modality,
int keyguardDisabledFlags) {
when(mSm.isSupervisionEnabledForUser(anyInt())).thenReturn(supervisionEnabled);
when(mDpm.getKeyguardDisabledFeatures(eq(null))).thenReturn(keyguardDisabledFlags);
return ParentalControlsUtils.parentConsentRequiredInternal(
mDpm, mSm, modality, new UserHandle(UserHandle.myUserId()));
}
@Test
@RequiresFlagsDisabled(android.app.supervision.flags.Flags.FLAG_DEPRECATE_DPM_SUPERVISION_APIS)
public void testEnforcedAdmin_whenDpmDisablesBiometricsAndSupervisionComponentExists() {
int[][] tests = {
{TYPE_FINGERPRINT, DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT},
@@ -99,6 +124,28 @@ public class ParentalControlsUtilsTest {
}
@Test
@RequiresFlagsEnabled(android.app.supervision.flags.Flags.FLAG_DEPRECATE_DPM_SUPERVISION_APIS)
public void testEnforcedAdmin_whenDpmDisablesBiometricsAndSupervisionIsEnabled() {
int[][] tests = {
{TYPE_FINGERPRINT, DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT},
{TYPE_FACE, DevicePolicyManager.KEYGUARD_DISABLE_FACE},
{TYPE_IRIS, DevicePolicyManager.KEYGUARD_DISABLE_IRIS},
};
for (int i = 0; i < tests.length; i++) {
RestrictedLockUtils.EnforcedAdmin admin = getEnforcedAdminForSupervision(
/* supervisionEnabled= */ true,
/* modality= */ tests[i][0],
/* keyguardDisableFlags= */ tests[i][1]);
assertNotNull(admin);
assertEquals(UserManager.DISALLOW_BIOMETRIC, admin.enforcedRestriction);
assertNull(admin.component);
}
}
@Test
@RequiresFlagsDisabled(android.app.supervision.flags.Flags.FLAG_DEPRECATE_DPM_SUPERVISION_APIS)
public void testNoEnforcedAdmin_whenNoSupervisionComponent() {
// Even if DPM flag exists, returns null EnforcedAdmin when no supervision component exists
RestrictedLockUtils.EnforcedAdmin admin = getEnforcedAdminForCombination(
@@ -106,4 +153,15 @@ public class ParentalControlsUtilsTest {
DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT);
assertNull(admin);
}
@Test
@RequiresFlagsEnabled(android.app.supervision.flags.Flags.FLAG_DEPRECATE_DPM_SUPERVISION_APIS)
public void testNoEnforcedAdmin_whenSupervisionIsDisabled() {
RestrictedLockUtils.EnforcedAdmin admin = getEnforcedAdminForSupervision(
/* supervisionEnabled= */ false,
TYPE_FINGERPRINT,
DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT);
assertNull(admin);
}
}