summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/qs/QSSecurityFooterTest.java48
-rw-r--r--packages/SystemUI/res/drawable/ic_supervision.xml11
-rw-r--r--packages/SystemUI/res/values/strings.xml3
-rw-r--r--packages/SystemUI/src/com/android/systemui/dagger/FrameworkServicesModule.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooterUtils.java16
-rw-r--r--packages/SystemUI/src/com/android/systemui/security/data/model/SecurityModel.kt21
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityController.java31
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java48
-rw-r--r--packages/SystemUI/src/com/android/systemui/supervision/shared/DeprecateDpmSupervisionApis.kt61
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SecurityControllerTest.java68
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/FakeSecurityController.kt11
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/SecurityControllerKosmos.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/supervision/SupervisionManagerKosmos.kt24
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeSecurityController.java10
14 files changed, 322 insertions, 40 deletions
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/QSSecurityFooterTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/QSSecurityFooterTest.java
index f6d57325bb1c..d7b91c64ba40 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/QSSecurityFooterTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/QSSecurityFooterTest.java
@@ -40,6 +40,8 @@ import android.graphics.drawable.Drawable;
import android.graphics.drawable.VectorDrawable;
import android.os.Handler;
import android.os.Looper;
+import android.platform.test.annotations.DisableFlags;
+import android.platform.test.annotations.EnableFlags;
import android.provider.DeviceConfig;
import android.provider.Settings;
import android.testing.TestableLooper;
@@ -659,6 +661,7 @@ public class QSSecurityFooterTest extends SysuiTestCase {
}
@Test
+ @DisableFlags(android.app.supervision.flags.Flags.FLAG_DEPRECATE_DPM_SUPERVISION_APIS)
public void testParentalControls() {
// Make sure the security footer is visible, so that the images are updated.
when(mSecurityController.isProfileOwnerOfOrganizationOwnedDevice()).thenReturn(true);
@@ -673,7 +676,6 @@ public class QSSecurityFooterTest extends SysuiTestCase {
Drawable testDrawable = new VectorDrawable();
when(mSecurityController.getIcon(any())).thenReturn(testDrawable);
- assertNotNull(mSecurityController.getIcon(null));
buttonConfig = getButtonConfig();
assertNotNull(buttonConfig);
@@ -689,13 +691,55 @@ public class QSSecurityFooterTest extends SysuiTestCase {
}
@Test
+ @EnableFlags(android.app.supervision.flags.Flags.FLAG_DEPRECATE_DPM_SUPERVISION_APIS)
+ public void testParentalControls_newSupervisionApis() {
+ // Make sure the security footer is visible, so that the images are updated.
+ when(mSecurityController.isProfileOwnerOfOrganizationOwnedDevice()).thenReturn(true);
+ when(mSecurityController.isParentalControlsEnabled()).thenReturn(true);
+
+ // We use the default icon when there is no admin icon.
+ when(mSecurityController.getIcon()).thenReturn(null);
+ SecurityButtonConfig buttonConfig = getButtonConfig();
+ assertEquals(mContext.getString(R.string.quick_settings_disclosure_parental_controls),
+ buttonConfig.getText());
+ assertIsDefaultIcon(buttonConfig.getIcon());
+
+ Drawable testDrawable = new VectorDrawable();
+ when(mSecurityController.getIcon()).thenReturn(testDrawable);
+
+ buttonConfig = getButtonConfig();
+ assertNotNull(buttonConfig);
+ assertEquals(mContext.getString(R.string.quick_settings_disclosure_parental_controls),
+ buttonConfig.getText());
+ assertIsIconDrawable(buttonConfig.getIcon(), testDrawable);
+
+ // Ensure the primary icon is back to default after parental controls are gone
+ when(mSecurityController.isParentalControlsEnabled()).thenReturn(false);
+ buttonConfig = getButtonConfig();
+ assertNotNull(buttonConfig);
+ assertIsDefaultIcon(buttonConfig.getIcon());
+ }
+
+ @Test
+ @DisableFlags(android.app.supervision.flags.Flags.FLAG_DEPRECATE_DPM_SUPERVISION_APIS)
public void testParentalControlsDialog() {
when(mSecurityController.isParentalControlsEnabled()).thenReturn(true);
when(mSecurityController.getLabel(any())).thenReturn(PARENTAL_CONTROLS_LABEL);
View view = mFooterUtils.createDialogView(getContext());
TextView textView = (TextView) view.findViewById(R.id.parental_controls_title);
- assertEquals(PARENTAL_CONTROLS_LABEL, textView.getText());
+ assertEquals(PARENTAL_CONTROLS_LABEL, textView.getText().toString());
+ }
+
+ @Test
+ @EnableFlags(android.app.supervision.flags.Flags.FLAG_DEPRECATE_DPM_SUPERVISION_APIS)
+ public void testParentalControlsDialog_newSupervisionApis() {
+ when(mSecurityController.isParentalControlsEnabled()).thenReturn(true);
+ when(mSecurityController.getLabel()).thenReturn(PARENTAL_CONTROLS_LABEL);
+
+ View view = mFooterUtils.createDialogView(getContext());
+ TextView textView = (TextView) view.findViewById(R.id.parental_controls_title);
+ assertEquals(PARENTAL_CONTROLS_LABEL, textView.getText().toString());
}
@Test
diff --git a/packages/SystemUI/res/drawable/ic_supervision.xml b/packages/SystemUI/res/drawable/ic_supervision.xml
new file mode 100644
index 000000000000..6c297aed6999
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_supervision.xml
@@ -0,0 +1,11 @@
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="960"
+ android:viewportHeight="960"
+ android:tint="?attr/colorControlNormal">
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M390,920Q339,920 299.5,889.5Q260,859 246,811Q240,788 221,774Q202,760 178,760Q162,760 148,766.5Q134,773 124,785L63,734Q84,708 114.5,694Q145,680 178,680Q229,680 269,710Q309,740 323,789Q329,812 348,826Q367,840 390,840Q409,840 424,830Q439,820 450,805L451,803L175,422Q167,411 163.5,399Q160,387 160,375Q160,359 166,344.5Q172,330 184,318L444,63Q455,52 470,46Q485,40 500,40Q515,40 530,46Q545,52 556,63L816,318Q828,330 834,344.5Q840,359 840,375Q840,387 836.5,399Q833,411 825,422L500,872Q482,897 452,908.5Q422,920 390,920ZM500,735L760,375Q760,375 760,375Q760,375 760,375L500,120Q500,120 500,120Q500,120 500,120L241,376Q241,376 241,376Q241,376 241,376L500,735ZM501,427L501,427Q501,427 501,427Q501,427 501,427L501,427Q501,427 501,427Q501,427 501,427L501,427Q501,427 501,427Q501,427 501,427Z"/>
+</vector>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 414d3f1d17d5..752b71c2c4a0 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -1930,6 +1930,9 @@
<!-- Name of the airplane status bar icon. -->
<string name="status_bar_airplane">Airplane mode</string>
+ <!-- Name of the supervision status bar icon. -->
+ <string name="status_bar_supervision">Parental controls</string>
+
<!-- Description for adding a quick settings tile -->
<!-- Name of a quick settings tile controlled by broadcast -->
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/FrameworkServicesModule.java b/packages/SystemUI/src/com/android/systemui/dagger/FrameworkServicesModule.java
index 35c0149fb7ac..1125d2ccdd97 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/FrameworkServicesModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/FrameworkServicesModule.java
@@ -41,6 +41,7 @@ import android.app.ambientcontext.AmbientContextManager;
import android.app.job.JobScheduler;
import android.app.role.RoleManager;
import android.app.smartspace.SmartspaceManager;
+import android.app.supervision.SupervisionManager;
import android.app.trust.TrustManager;
import android.app.usage.UsageStatsManager;
import android.appwidget.AppWidgetManager;
@@ -836,4 +837,11 @@ public class FrameworkServicesModule {
static ViewCapture provideViewCapture(Context context) {
return ViewCaptureFactory.getInstance(context);
}
+
+ @Provides
+ @Singleton
+ @Nullable
+ static SupervisionManager provideSupervisionManager(Context context) {
+ return (SupervisionManager) context.getSystemService(Context.SUPERVISION_SERVICE);
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooterUtils.java b/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooterUtils.java
index 88f0318c2fbf..4f26483d9d38 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooterUtils.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooterUtils.java
@@ -90,6 +90,7 @@ import com.android.systemui.settings.UserTracker;
import com.android.systemui.shade.ShadeDisplayAware;
import com.android.systemui.statusbar.phone.SystemUIDialog;
import com.android.systemui.statusbar.policy.SecurityController;
+import com.android.systemui.supervision.shared.DeprecateDpmSupervisionApis;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Supplier;
@@ -585,8 +586,17 @@ public class QSSecurityFooterUtils implements DialogInterface.OnClickListener {
View dialogView = LayoutInflater.from(quickSettingsContext)
.inflate(R.layout.quick_settings_footer_dialog_parental_controls, null, false);
- DeviceAdminInfo info = mSecurityController.getDeviceAdminInfo();
- Drawable icon = mSecurityController.getIcon(info);
+ Drawable icon;
+ CharSequence label;
+ if (DeprecateDpmSupervisionApis.isEnabled()) {
+ icon = mSecurityController.getIcon();
+ label = mSecurityController.getLabel();
+ } else {
+ DeviceAdminInfo info = mSecurityController.getDeviceAdminInfo();
+ icon = mSecurityController.getIcon(info);
+ label = mSecurityController.getLabel(info);
+ }
+
if (icon != null) {
ImageView imageView = (ImageView) dialogView.findViewById(R.id.parental_controls_icon);
imageView.setImageDrawable(icon);
@@ -594,7 +604,7 @@ public class QSSecurityFooterUtils implements DialogInterface.OnClickListener {
TextView parentalControlsTitle =
(TextView) dialogView.findViewById(R.id.parental_controls_title);
- parentalControlsTitle.setText(mSecurityController.getLabel(info));
+ parentalControlsTitle.setText(label);
return dialogView;
}
diff --git a/packages/SystemUI/src/com/android/systemui/security/data/model/SecurityModel.kt b/packages/SystemUI/src/com/android/systemui/security/data/model/SecurityModel.kt
index 1cf5a8fe5f97..1fd3d336411c 100644
--- a/packages/SystemUI/src/com/android/systemui/security/data/model/SecurityModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/security/data/model/SecurityModel.kt
@@ -20,6 +20,7 @@ import android.graphics.drawable.Drawable
import androidx.annotation.VisibleForTesting
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.statusbar.policy.SecurityController
+import com.android.systemui.supervision.shared.DeprecateDpmSupervisionApis
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.withContext
@@ -59,12 +60,18 @@ data class SecurityModel(
@JvmStatic
@VisibleForTesting
fun create(securityController: SecurityController): SecurityModel {
- val deviceAdminInfo =
- if (securityController.isParentalControlsEnabled) {
- securityController.deviceAdminInfo
- } else {
- null
- }
+ val icon: Drawable?
+ if (DeprecateDpmSupervisionApis.isEnabled) {
+ icon = securityController.getIcon()
+ } else {
+ val deviceAdminInfo =
+ if (securityController.isParentalControlsEnabled) {
+ securityController.deviceAdminInfo
+ } else {
+ null
+ }
+ icon = securityController.getIcon(deviceAdminInfo)
+ }
return SecurityModel(
isDeviceManaged = securityController.isDeviceManaged,
@@ -83,7 +90,7 @@ data class SecurityModel(
hasCACertInCurrentUser = securityController.hasCACertInCurrentUser(),
hasCACertInWorkProfile = securityController.hasCACertInWorkProfile(),
isParentalControlsEnabled = securityController.isParentalControlsEnabled,
- deviceAdminIcon = securityController.getIcon(deviceAdminInfo),
+ deviceAdminIcon = icon,
)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityController.java
index 10bf0680b567..f732c20a4e79 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityController.java
@@ -15,6 +15,7 @@
*/
package com.android.systemui.statusbar.policy;
+import android.annotation.Nullable;
import android.app.admin.DeviceAdminInfo;
import android.content.ComponentName;
import android.graphics.drawable.Drawable;
@@ -59,12 +60,36 @@ public interface SecurityController extends CallbackController<SecurityControlle
void onUserSwitched(int newUserId);
/** Whether or not parental controls is enabled */
boolean isParentalControlsEnabled();
- /** DeviceAdminInfo for active admin */
+
+ // TODO(b/382034839): Remove during the cleanup of deprecate_dpm_supervision_apis.
+ /**
+ * DeviceAdminInfo for active admin
+ * @deprecated No longer needed.
+ */
+ @Deprecated
DeviceAdminInfo getDeviceAdminInfo();
- /** Icon for admin */
+
+ // TODO(b/382034839): Remove during the cleanup of deprecate_dpm_supervision_apis.
+ /**
+ * Icon for admin
+ * @deprecated Use {@link #getIcon()} instead.
+ */
+ @Deprecated
Drawable getIcon(DeviceAdminInfo info);
- /** Label for admin */
+ /** Icon for admin */
+ @Nullable
+ Drawable getIcon();
+
+ // TODO(b/382034839): Remove during the cleanup of deprecate_dpm_supervision_apis.
+ /**
+ * Label for admin
+ * @deprecated Use {@link #getLabel()} instead.
+ */
+ @Deprecated
CharSequence getLabel(DeviceAdminInfo info);
+ /** Label for admin */
+ @Nullable
+ CharSequence getLabel();
public interface SecurityControllerCallback {
void onStateChanged();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java
index f39762766633..d41ef97f4664 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java
@@ -22,6 +22,7 @@ import android.annotation.Nullable;
import android.app.admin.DeviceAdminInfo;
import android.app.admin.DevicePolicyManager;
import android.app.admin.DevicePolicyManager.DeviceOwnerType;
+import android.app.supervision.SupervisionManager;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
@@ -62,6 +63,7 @@ import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.res.R;
import com.android.systemui.settings.UserTracker;
+import com.android.systemui.supervision.shared.DeprecateDpmSupervisionApis;
import org.xmlpull.v1.XmlPullParserException;
@@ -71,6 +73,7 @@ import java.util.ArrayList;
import java.util.concurrent.Executor;
import javax.inject.Inject;
+import javax.inject.Provider;
/**
*/
@@ -97,6 +100,7 @@ public class SecurityControllerImpl implements SecurityController {
private final VpnManager mVpnManager;
private final DevicePolicyManager mDevicePolicyManager;
private final PackageManager mPackageManager;
+ private final SupervisionManager mSupervisionManager;
private final UserManager mUserManager;
private final Executor mMainExecutor;
private final Executor mBgExecutor;
@@ -132,7 +136,8 @@ public class SecurityControllerImpl implements SecurityController {
BroadcastDispatcher broadcastDispatcher,
@Main Executor mainExecutor,
@Background Executor bgExecutor,
- DumpManager dumpManager
+ DumpManager dumpManager,
+ Provider<SupervisionManager> supervisionManagerProvider
) {
mContext = context;
mUserTracker = userTracker;
@@ -142,6 +147,11 @@ public class SecurityControllerImpl implements SecurityController {
context.getSystemService(Context.CONNECTIVITY_SERVICE);
mVpnManager = context.getSystemService(VpnManager.class);
mPackageManager = context.getPackageManager();
+ if (DeprecateDpmSupervisionApis.isEnabled()) {
+ mSupervisionManager = supervisionManagerProvider.get();
+ } else {
+ mSupervisionManager = null;
+ }
mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
mMainExecutor = mainExecutor;
mBgExecutor = bgExecutor;
@@ -395,12 +405,16 @@ public class SecurityControllerImpl implements SecurityController {
@Override
public boolean isParentalControlsEnabled() {
- return getProfileOwnerOrDeviceOwnerSupervisionComponent() != null;
+ if (DeprecateDpmSupervisionApis.isEnabled() && mSupervisionManager != null) {
+ return mSupervisionManager.isSupervisionEnabledForUser(mCurrentUserId);
+ } else {
+ return getProfileOwnerOrDeviceOwnerSupervisionComponent() != null;
+ }
}
@Override
public DeviceAdminInfo getDeviceAdminInfo() {
- return getDeviceAdminInfo(getProfileOwnerOrDeviceOwnerComponent());
+ return getSupervisionDeviceAdminInfo();
}
@Override
@@ -409,24 +423,36 @@ public class SecurityControllerImpl implements SecurityController {
}
@Override
+ @Nullable
+ public Drawable getIcon() {
+ DeprecateDpmSupervisionApis.assertInNewMode();
+ return isParentalControlsEnabled()
+ ? mContext.getDrawable(R.drawable.ic_supervision)
+ : null;
+ }
+
+ @Override
public CharSequence getLabel(DeviceAdminInfo info) {
return (info == null) ? null : info.loadLabel(mPackageManager);
}
+ @Override
+ @Nullable
+ public CharSequence getLabel() {
+ DeprecateDpmSupervisionApis.assertInNewMode();
+ return isParentalControlsEnabled()
+ ? mContext.getString(R.string.status_bar_supervision)
+ : null;
+ }
+
private ComponentName getProfileOwnerOrDeviceOwnerSupervisionComponent() {
UserHandle currentUser = new UserHandle(mCurrentUserId);
return mDevicePolicyManager
.getProfileOwnerOrDeviceOwnerSupervisionComponent(currentUser);
}
- // Returns the ComponentName of the current DO/PO. Right now it only checks the supervision
- // component but can be changed to check for other DO/POs. This change would make getIcon()
- // and getLabel() work for all admins.
- private ComponentName getProfileOwnerOrDeviceOwnerComponent() {
- return getProfileOwnerOrDeviceOwnerSupervisionComponent();
- }
-
- private DeviceAdminInfo getDeviceAdminInfo(ComponentName componentName) {
+ private DeviceAdminInfo getSupervisionDeviceAdminInfo() {
+ ComponentName componentName = getProfileOwnerOrDeviceOwnerSupervisionComponent();
try {
ResolveInfo resolveInfo = new ResolveInfo();
resolveInfo.activityInfo = mPackageManager.getReceiverInfo(componentName,
diff --git a/packages/SystemUI/src/com/android/systemui/supervision/shared/DeprecateDpmSupervisionApis.kt b/packages/SystemUI/src/com/android/systemui/supervision/shared/DeprecateDpmSupervisionApis.kt
new file mode 100644
index 000000000000..cbd3dc73c6c0
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/supervision/shared/DeprecateDpmSupervisionApis.kt
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2023 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.systemui.supervision.shared
+
+import android.app.supervision.flags.Flags
+import com.android.systemui.flags.FlagToken
+import com.android.systemui.flags.RefactorFlagUtils
+
+/** Helper for reading or using the deprecate DPM supervision APIs flag state. */
+@Suppress("NOTHING_TO_INLINE")
+object DeprecateDpmSupervisionApis {
+ /** The aconfig flag name */
+ const val FLAG_NAME = Flags.FLAG_DEPRECATE_DPM_SUPERVISION_APIS
+
+ /** A token used for dependency declaration */
+ val token: FlagToken
+ get() = FlagToken(FLAG_NAME, isEnabled)
+
+ /** Is the refactor enabled */
+ @JvmStatic
+ inline val isEnabled
+ get() = Flags.deprecateDpmSupervisionApis()
+
+ /**
+ * Called to ensure code is only run when the flag is enabled. This protects users from the
+ * unintended behaviors caused by accidentally running new logic, while also crashing on an eng
+ * build to ensure that the refactor author catches issues in testing.
+ */
+ @JvmStatic
+ inline fun isUnexpectedlyInLegacyMode() =
+ RefactorFlagUtils.isUnexpectedlyInLegacyMode(isEnabled, FLAG_NAME)
+
+ /**
+ * Called to ensure code is only run when the flag is enabled. This will throw an exception if
+ * the flag is not enabled to ensure that the refactor author catches issues in testing.
+ * Caution!! Using this check incorrectly will cause crashes in nextfood builds!
+ */
+ @JvmStatic
+ inline fun assertInNewMode() = RefactorFlagUtils.assertInNewMode(isEnabled, FLAG_NAME)
+
+ /**
+ * Called to ensure code is only run when the flag is disabled. This will throw an exception if
+ * the flag is enabled to ensure that the refactor author catches issues in testing.
+ */
+ @JvmStatic
+ inline fun assertInLegacyMode() = RefactorFlagUtils.assertInLegacyMode(isEnabled, FLAG_NAME)
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SecurityControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SecurityControllerTest.java
index f91f373dfc2c..32458413f17e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SecurityControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SecurityControllerTest.java
@@ -25,12 +25,12 @@ import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.app.admin.DevicePolicyManager;
+import android.app.supervision.SupervisionManager;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
@@ -42,6 +42,10 @@ import android.net.ConnectivityManager.NetworkCallback;
import android.net.NetworkRequest;
import android.os.Handler;
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 android.security.IKeyChainService;
import androidx.test.filters.SmallTest;
@@ -55,10 +59,14 @@ import com.android.systemui.util.concurrency.FakeExecutor;
import com.android.systemui.util.time.FakeSystemClock;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
import org.mockito.Mockito;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import java.util.ArrayList;
import java.util.Arrays;
@@ -68,17 +76,22 @@ import java.util.concurrent.atomic.AtomicBoolean;
@SmallTest
@RunWith(AndroidJUnit4.class)
public class SecurityControllerTest extends SysuiTestCase {
+ @Rule public final MockitoRule mockito = MockitoJUnit.rule();
+ @Rule public final CheckFlagsRule checkFlags = DeviceFlagsValueProvider.createCheckFlagsRule();
+
private static final ComponentName DEVICE_OWNER_COMPONENT =
new ComponentName("com.android.foo", "bar");
- private final DevicePolicyManager mDevicePolicyManager = mock(DevicePolicyManager.class);
- private final IKeyChainService.Stub mKeyChainService = mock(IKeyChainService.Stub.class);
- private final UserManager mUserManager = mock(UserManager.class);
- private final UserTracker mUserTracker = mock(UserTracker.class);
- private final BroadcastDispatcher mBroadcastDispatcher = mock(BroadcastDispatcher.class);
- private final Handler mHandler = mock(Handler.class);
+ @Mock private DevicePolicyManager mDevicePolicyManager;
+ @Mock private IKeyChainService.Stub mKeyChainService;
+ @Mock private UserManager mUserManager;
+ @Mock private UserTracker mUserTracker;
+ @Mock private BroadcastDispatcher mBroadcastDispatcher;
+ @Mock private Handler mHandler;
+ @Mock private ConnectivityManager mConnectivityManager;
+ @Mock private SupervisionManager mSupervisionManager;
+
private SecurityControllerImpl mSecurityController;
- private ConnectivityManager mConnectivityManager = mock(ConnectivityManager.class);
private FakeExecutor mMainExecutor;
private FakeExecutor mBgExecutor;
private BroadcastReceiver mBroadcastReceiver;
@@ -115,7 +128,8 @@ public class SecurityControllerTest extends SysuiTestCase {
mBroadcastDispatcher,
mMainExecutor,
mBgExecutor,
- Mockito.mock(DumpManager.class));
+ Mockito.mock(DumpManager.class),
+ () -> mSupervisionManager);
verify(mBroadcastDispatcher).registerReceiverWithHandler(
brCaptor.capture(),
@@ -241,6 +255,42 @@ public class SecurityControllerTest extends SysuiTestCase {
mBgExecutor.runAllReady();
}
+ @Test
+ @RequiresFlagsDisabled(android.app.supervision.flags.Flags.FLAG_DEPRECATE_DPM_SUPERVISION_APIS)
+ public void isParentalControlsEnabled_usingDpm_supervisionIsProfileOwner() {
+ when(mDevicePolicyManager.getProfileOwnerOrDeviceOwnerSupervisionComponent(any()))
+ .thenReturn(DEVICE_OWNER_COMPONENT);
+
+ assertTrue(mSecurityController.isParentalControlsEnabled());
+ }
+
+ @Test
+ @RequiresFlagsDisabled(android.app.supervision.flags.Flags.FLAG_DEPRECATE_DPM_SUPERVISION_APIS)
+ public void isParentalControlsEnabled_usingDpm_supervisionIsNotProfileOwner() {
+ when(mDevicePolicyManager.getProfileOwnerOrDeviceOwnerSupervisionComponent(any()))
+ .thenReturn(null);
+
+ assertFalse(mSecurityController.isParentalControlsEnabled());
+ }
+
+ @Test
+ @RequiresFlagsEnabled(android.app.supervision.flags.Flags.FLAG_DEPRECATE_DPM_SUPERVISION_APIS)
+ public void isParentalControlsEnabled_usingSupervisionManager_supervisionIsEnabled() {
+ when(mSupervisionManager.isSupervisionEnabledForUser(anyInt()))
+ .thenReturn(true);
+
+ assertTrue(mSecurityController.isParentalControlsEnabled());
+ }
+
+ @Test
+ @RequiresFlagsEnabled(android.app.supervision.flags.Flags.FLAG_DEPRECATE_DPM_SUPERVISION_APIS)
+ public void isParentalControlsEnabled_usingSupervisionManager_supervisionIsNotEnabled() {
+ when(mSupervisionManager.isSupervisionEnabledForUser(anyInt()))
+ .thenReturn(false);
+
+ assertFalse(mSecurityController.isParentalControlsEnabled());
+ }
+
/**
* refresh CA certs by sending a user unlocked broadcast for the desired user
*/
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/FakeSecurityController.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/FakeSecurityController.kt
index ac90a45450d0..b794b24776a8 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/FakeSecurityController.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/FakeSecurityController.kt
@@ -22,9 +22,7 @@ import android.graphics.drawable.Drawable
import java.io.PrintWriter
/** A fake [SecurityController] to be used in tests. */
-class FakeSecurityController(
- private val fakeState: FakeState = FakeState(),
-) : SecurityController {
+class FakeSecurityController(private val fakeState: FakeState = FakeState()) : SecurityController {
private val callbacks = LinkedHashSet<SecurityController.SecurityControllerCallback>()
override fun addCallback(callback: SecurityController.SecurityControllerCallback) {
@@ -91,12 +89,16 @@ class FakeSecurityController(
override fun isParentalControlsEnabled(): Boolean = fakeState.isParentalControlsEnabled
- override fun getDeviceAdminInfo(): DeviceAdminInfo? = fakeState.deviceAdminInfo
+ override fun getDeviceAdminInfo(): DeviceAdminInfo? = null
override fun getIcon(info: DeviceAdminInfo?): Drawable? = null
+ override fun getIcon(): Drawable? = null
+
override fun getLabel(info: DeviceAdminInfo?): CharSequence? = null
+ override fun getLabel(): CharSequence? = null
+
class FakeState(
var isDeviceManaged: Boolean = false,
var hasProfileOwner: Boolean = false,
@@ -118,6 +120,5 @@ class FakeSecurityController(
var hasCACertInCurrentUser: Boolean = false,
var hasCACertInWorkProfile: Boolean = false,
var isParentalControlsEnabled: Boolean = false,
- var deviceAdminInfo: DeviceAdminInfo? = null,
)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/SecurityControllerKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/SecurityControllerKosmos.kt
index 67a5cc98db98..abd20572ca43 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/SecurityControllerKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/SecurityControllerKosmos.kt
@@ -24,6 +24,7 @@ import com.android.systemui.dump.dumpManager
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.Kosmos.Fixture
import com.android.systemui.settings.userTracker
+import com.android.systemui.supervision.supervisionManager
val Kosmos.securityController by Fixture {
SecurityControllerImpl(
@@ -34,5 +35,6 @@ val Kosmos.securityController by Fixture {
fakeExecutor,
fakeExecutor,
dumpManager,
+ { supervisionManager },
)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/supervision/SupervisionManagerKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/supervision/SupervisionManagerKosmos.kt
new file mode 100644
index 000000000000..b8cf5096ba30
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/supervision/SupervisionManagerKosmos.kt
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2023 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.systemui.supervision
+
+import android.app.supervision.SupervisionManager
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.Kosmos.Fixture
+import com.android.systemui.util.mockito.mock
+
+var Kosmos.supervisionManager by Fixture { mock<SupervisionManager>() }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeSecurityController.java b/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeSecurityController.java
index 791165d97795..a3036fc305e3 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeSecurityController.java
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeSecurityController.java
@@ -154,7 +154,17 @@ public class FakeSecurityController extends BaseLeakChecker<SecurityControllerCa
}
@Override
+ public Drawable getIcon() {
+ return null;
+ }
+
+ @Override
public CharSequence getLabel(DeviceAdminInfo info) {
return null;
}
+
+ @Override
+ public CharSequence getLabel() {
+ return null;
+ }
}