diff --git a/res/values/strings.xml b/res/values/strings.xml
index add226ab8f8..9ce5a389ee2 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -5877,12 +5877,8 @@
Add account
Work profile isn\u2019t available yet
-
- Work profile
-
- Managed by your organization
-
- Apps and notifications are off
+
+ Work apps
Remove work profile
@@ -9783,6 +9779,8 @@
Cross-profile calendar
Show work events on your personal calendar
+
+ When work apps are off, they’re paused and can’t be accessed or send you notifications
Manage storage
diff --git a/res/xml/managed_profile_settings.xml b/res/xml/managed_profile_settings.xml
index 20f6d3dc3f3..ddfb86987ca 100644
--- a/res/xml/managed_profile_settings.xml
+++ b/res/xml/managed_profile_settings.xml
@@ -19,10 +19,9 @@
android:key="managed_profile_settings_screen"
android:title="@string/managed_profile_settings_title">
-
+
+
\ No newline at end of file
diff --git a/src/com/android/settings/accounts/ContactSearchPreferenceController.java b/src/com/android/settings/accounts/ContactSearchPreferenceController.java
index 5e4ef48d7c2..87dabd8d9a4 100644
--- a/src/com/android/settings/accounts/ContactSearchPreferenceController.java
+++ b/src/com/android/settings/accounts/ContactSearchPreferenceController.java
@@ -20,37 +20,38 @@ import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
-import androidx.annotation.VisibleForTesting;
+import androidx.lifecycle.DefaultLifecycleObserver;
+import androidx.lifecycle.LifecycleOwner;
import androidx.preference.Preference;
+import androidx.preference.PreferenceScreen;
+import com.android.settings.R;
import com.android.settings.Utils;
-import com.android.settings.core.BasePreferenceController;
+import com.android.settings.core.TogglePreferenceController;
import com.android.settings.slices.SliceData;
import com.android.settingslib.RestrictedLockUtils;
import com.android.settingslib.RestrictedLockUtilsInternal;
import com.android.settingslib.RestrictedSwitchPreference;
-public class ContactSearchPreferenceController extends BasePreferenceController implements
- Preference.OnPreferenceChangeListener {
+import org.jetbrains.annotations.NotNull;
- private UserHandle mManagedUser;
+public class ContactSearchPreferenceController extends TogglePreferenceController implements
+ Preference.OnPreferenceChangeListener, DefaultLifecycleObserver,
+ ManagedProfileQuietModeEnabler.QuietModeChangeListener {
+
+ private final ManagedProfileQuietModeEnabler mQuietModeEnabler;
+ private final UserHandle mManagedUser;
+ private Preference mPreference;
public ContactSearchPreferenceController(Context context, String key) {
super(context, key);
- // Set default managed profile for the current user, otherwise isAvailable will be false and
- // the setting won't be searchable.
- UserManager userManager = context.getSystemService(UserManager.class);
- mManagedUser = Utils.getManagedProfile(userManager);
- }
-
- @VisibleForTesting
- void setManagedUser(UserHandle managedUser) {
- mManagedUser = managedUser;
+ mManagedUser = Utils.getManagedProfile(context.getSystemService(UserManager.class));
+ mQuietModeEnabler = new ManagedProfileQuietModeEnabler(context, this);
}
@Override
public int getAvailabilityStatus() {
- return (mManagedUser != null) ? AVAILABLE : DISABLED_FOR_USER;
+ return mQuietModeEnabler.isAvailable() ? AVAILABLE : DISABLED_FOR_USER;
}
@Override
@@ -59,6 +60,7 @@ public class ContactSearchPreferenceController extends BasePreferenceController
if (preference instanceof RestrictedSwitchPreference) {
final RestrictedSwitchPreference pref = (RestrictedSwitchPreference) preference;
pref.setChecked(isChecked());
+ pref.setEnabled(!mQuietModeEnabler.isQuietModeEnabled());
if (mManagedUser != null) {
final RestrictedLockUtils.EnforcedAdmin enforcedAdmin =
RestrictedLockUtilsInternal.checkIfRemoteContactSearchDisallowed(
@@ -68,26 +70,48 @@ public class ContactSearchPreferenceController extends BasePreferenceController
}
}
- private boolean isChecked() {
- if (mManagedUser == null) {
+ @Override
+ public void displayPreference(PreferenceScreen screen) {
+ super.displayPreference(screen);
+ mPreference = screen.findPreference(getPreferenceKey());
+ updateState(mPreference);
+ }
+
+ @Override
+ public void onStart(@NotNull LifecycleOwner lifecycleOwner) {
+ lifecycleOwner.getLifecycle().addObserver(mQuietModeEnabler);
+ }
+
+ @Override
+ public void onStop(@NotNull LifecycleOwner lifecycleOwner) {
+ lifecycleOwner.getLifecycle().removeObserver(mQuietModeEnabler);
+ }
+
+ @Override
+ public boolean isChecked() {
+ if (mManagedUser == null || mQuietModeEnabler.isQuietModeEnabled()) {
return false;
}
return 0 != Settings.Secure.getIntForUser(mContext.getContentResolver(),
MANAGED_PROFILE_CONTACT_REMOTE_SEARCH, 0, mManagedUser.getIdentifier());
}
- private boolean setChecked(boolean isChecked) {
- if (mManagedUser != null) {
- final int value = isChecked ? 1 : 0;
- Settings.Secure.putIntForUser(mContext.getContentResolver(),
- MANAGED_PROFILE_CONTACT_REMOTE_SEARCH, value, mManagedUser.getIdentifier());
+ @Override
+ public boolean setChecked(boolean isChecked) {
+ if (mManagedUser == null || mQuietModeEnabler.isQuietModeEnabled()) {
+ return false;
}
+ final int value = isChecked ? 1 : 0;
+ Settings.Secure.putIntForUser(mContext.getContentResolver(),
+ MANAGED_PROFILE_CONTACT_REMOTE_SEARCH, value, mManagedUser.getIdentifier());
return true;
}
@Override
- public final boolean onPreferenceChange(Preference preference, Object newValue) {
- return setChecked((boolean) newValue);
+ public void onQuietModeChanged() {
+ if (mPreference != null) {
+ updateState(mPreference);
+ }
}
@Override
@@ -95,4 +119,9 @@ public class ContactSearchPreferenceController extends BasePreferenceController
public int getSliceType() {
return SliceData.SliceType.SWITCH;
}
-}
\ No newline at end of file
+
+ @Override
+ public int getSliceHighlightMenuRes() {
+ return R.string.menu_key_accounts;
+ }
+}
diff --git a/src/com/android/settings/accounts/ManagedProfileQuietModeEnabler.java b/src/com/android/settings/accounts/ManagedProfileQuietModeEnabler.java
new file mode 100644
index 00000000000..989be09565c
--- /dev/null
+++ b/src/com/android/settings/accounts/ManagedProfileQuietModeEnabler.java
@@ -0,0 +1,122 @@
+/*
+ * 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.settings.accounts;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.util.Log;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.VisibleForTesting;
+import androidx.lifecycle.DefaultLifecycleObserver;
+import androidx.lifecycle.LifecycleOwner;
+
+import com.android.settings.Utils;
+
+import javax.annotation.Nullable;
+
+/**
+ * A class that controls the managed profile's quiet mode, listens to quiet mode changes and
+ * modifies managed profile settings. The user facing term for quiet mode is "work apps".
+ */
+final class ManagedProfileQuietModeEnabler implements DefaultLifecycleObserver {
+
+ private static final String TAG = "QuietModeEnabler";
+ private final Context mContext;
+ private final QuietModeChangeListener mListener;
+ @Nullable private final UserHandle mManagedProfile;
+ private final UserManager mUserManager;
+
+ public interface QuietModeChangeListener {
+ /** Called when quiet mode has changed. */
+ void onQuietModeChanged();
+ }
+
+ ManagedProfileQuietModeEnabler(Context context, QuietModeChangeListener listener) {
+ mContext = context;
+ mListener = listener;
+ mUserManager = context.getSystemService(UserManager.class);
+ mManagedProfile = Utils.getManagedProfile(mUserManager);
+ }
+
+ public void setQuietModeEnabled(boolean enabled) {
+ if (mManagedProfile != null) {
+ mUserManager.requestQuietModeEnabled(enabled, mManagedProfile);
+ }
+ }
+
+ public boolean isQuietModeEnabled() {
+ return mManagedProfile != null && mUserManager.isQuietModeEnabled(mManagedProfile);
+ }
+
+ @Override
+ public void onStart(@NonNull LifecycleOwner owner) {
+ IntentFilter intentFilter = new IntentFilter();
+ intentFilter.addAction(Intent.ACTION_MANAGED_PROFILE_AVAILABLE);
+ intentFilter.addAction(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE);
+ mContext.registerReceiver(mReceiver, intentFilter, Context.RECEIVER_NOT_EXPORTED);
+ }
+
+ @Override
+ public void onStop(@NonNull LifecycleOwner owner) {
+ mContext.unregisterReceiver(mReceiver);
+ }
+
+ public boolean isAvailable() {
+ return (mManagedProfile != null);
+ }
+
+ private void refreshQuietMode() {
+ if (mListener != null) {
+ mListener.onQuietModeChanged();
+ }
+ }
+
+ /**
+ * Receiver that listens to {@link Intent#ACTION_MANAGED_PROFILE_AVAILABLE} and
+ * {@link Intent#ACTION_MANAGED_PROFILE_UNAVAILABLE}, and updates the work mode
+ */
+ @VisibleForTesting
+ final BroadcastReceiver mReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (intent == null) {
+ return;
+ }
+ String action = intent.getAction();
+ Log.v(TAG, "Received broadcast: " + action);
+
+ if (Intent.ACTION_MANAGED_PROFILE_AVAILABLE.equals(action)
+ || Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE.equals(action)) {
+ int intentUserIdentifier = intent.getIntExtra(Intent.EXTRA_USER_HANDLE,
+ UserHandle.USER_NULL);
+ if (intentUserIdentifier == mManagedProfile.getIdentifier()) {
+ refreshQuietMode();
+ } else {
+ Log.w(TAG, "Managed profile broadcast ID: " + intentUserIdentifier
+ + " does not match managed user: " + mManagedProfile);
+ }
+ } else {
+ Log.w(TAG, "Cannot handle received broadcast: " + intent.getAction());
+ }
+ }
+ };
+}
diff --git a/src/com/android/settings/accounts/WorkModePreferenceController.java b/src/com/android/settings/accounts/WorkModePreferenceController.java
index 1941de45c4d..a261afccaa6 100644
--- a/src/com/android/settings/accounts/WorkModePreferenceController.java
+++ b/src/com/android/settings/accounts/WorkModePreferenceController.java
@@ -1,165 +1,90 @@
/*
* Copyright (C) 2018 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
+ * 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.
+ * 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.accounts;
-import static android.app.admin.DevicePolicyResources.Strings.Settings.WORK_PROFILE_SETTING_OFF_SUMMARY;
-import static android.app.admin.DevicePolicyResources.Strings.Settings.WORK_PROFILE_SETTING_ON_SUMMARY;
-
-import android.app.admin.DevicePolicyManager;
-import android.content.BroadcastReceiver;
import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.os.UserHandle;
-import android.os.UserManager;
-import android.util.Log;
-import androidx.annotation.VisibleForTesting;
+import androidx.lifecycle.DefaultLifecycleObserver;
+import androidx.lifecycle.LifecycleOwner;
import androidx.preference.Preference;
-import androidx.preference.PreferenceScreen;
-import androidx.preference.TwoStatePreference;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.settings.R;
-import com.android.settings.Utils;
-import com.android.settings.core.BasePreferenceController;
import com.android.settings.slices.SliceData;
-import com.android.settingslib.core.lifecycle.LifecycleObserver;
-import com.android.settingslib.core.lifecycle.events.OnStart;
-import com.android.settingslib.core.lifecycle.events.OnStop;
+import com.android.settings.widget.SettingsMainSwitchPreferenceController;
+import com.android.settingslib.widget.MainSwitchPreference;
-public class WorkModePreferenceController extends BasePreferenceController implements
- Preference.OnPreferenceChangeListener, LifecycleObserver, OnStart, OnStop {
+import org.jetbrains.annotations.NotNull;
- private static final String TAG = "WorkModeController";
- private UserManager mUserManager;
- private UserHandle mManagedUser;
- private DevicePolicyManager mDevicePolicyManager;
+public class WorkModePreferenceController extends SettingsMainSwitchPreferenceController
+ implements Preference.OnPreferenceChangeListener, DefaultLifecycleObserver,
+ ManagedProfileQuietModeEnabler.QuietModeChangeListener {
- private Preference mPreference;
- private IntentFilter mIntentFilter;
+ private final ManagedProfileQuietModeEnabler mQuietModeEnabler;
public WorkModePreferenceController(Context context, String key) {
super(context, key);
- mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
- mDevicePolicyManager = mContext.getSystemService(DevicePolicyManager.class);
- mIntentFilter = new IntentFilter();
- mIntentFilter.addAction(Intent.ACTION_MANAGED_PROFILE_AVAILABLE);
- mIntentFilter.addAction(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE);
- // Set default managed profile for the current user, otherwise isAvailable will be false and
- // the setting won't be searchable.
- mManagedUser = Utils.getManagedProfile(mUserManager);
- }
-
- @VisibleForTesting
- void setManagedUser(UserHandle managedUser) {
- mManagedUser = managedUser;
- }
-
- @Override
- public void onStart() {
- mContext.registerReceiver(mReceiver, mIntentFilter,
- Context.RECEIVER_EXPORTED_UNAUDITED);
- }
-
- @Override
- public void onStop() {
- mContext.unregisterReceiver(mReceiver);
+ mQuietModeEnabler = new ManagedProfileQuietModeEnabler(context, this);
}
@Override
public int getAvailabilityStatus() {
- return (mManagedUser != null) ? AVAILABLE : DISABLED_FOR_USER;
+ return (mQuietModeEnabler.isAvailable()) ? AVAILABLE : DISABLED_FOR_USER;
}
@Override
- public void displayPreference(PreferenceScreen screen) {
- super.displayPreference(screen);
- mPreference = screen.findPreference(getPreferenceKey());
+ public void onStart(@NotNull LifecycleOwner lifecycleOwner) {
+ lifecycleOwner.getLifecycle().addObserver(mQuietModeEnabler);
}
@Override
- public CharSequence getSummary() {
- if (isChecked()) {
- return mDevicePolicyManager.getResources().getString(
- WORK_PROFILE_SETTING_ON_SUMMARY,
- () -> mContext.getString(R.string.work_mode_on_summary));
- }
-
- return mDevicePolicyManager.getResources().getString(
- WORK_PROFILE_SETTING_OFF_SUMMARY,
- () -> mContext.getString(R.string.work_mode_off_summary));
+ public void onStop(@NotNull LifecycleOwner lifecycleOwner) {
+ lifecycleOwner.getLifecycle().removeObserver(mQuietModeEnabler);
}
- private boolean isChecked() {
- boolean isWorkModeOn = false;
- if (mUserManager != null && mManagedUser != null) {
- isWorkModeOn = !mUserManager.isQuietModeEnabled(mManagedUser);
- }
- return isWorkModeOn;
+ @Override
+ public boolean isChecked() {
+ return !mQuietModeEnabler.isQuietModeEnabled();
}
- private boolean setChecked(boolean isChecked) {
- if (mUserManager != null && mManagedUser != null) {
- final boolean quietModeEnabled = !isChecked;
- mUserManager.requestQuietModeEnabled(quietModeEnabled, mManagedUser);
- }
+ @Override
+ public boolean setChecked(boolean isChecked) {
+ mQuietModeEnabler.setQuietModeEnabled(!isChecked);
return true;
}
@Override
- public void updateState(Preference preference) {
- super.updateState(preference);
- if (preference instanceof TwoStatePreference) {
- ((TwoStatePreference) preference).setChecked(isChecked());
- }
+ public void onQuietModeChanged() {
+ updateState(mSwitchPreference);
}
- @Override
- public final boolean onPreferenceChange(Preference preference, Object newValue) {
- return setChecked((boolean) newValue);
- }
-
- /**
- * Receiver that listens to {@link Intent#ACTION_MANAGED_PROFILE_AVAILABLE} and
- * {@link Intent#ACTION_MANAGED_PROFILE_UNAVAILABLE}, and updates the work mode
- */
- @VisibleForTesting
- final BroadcastReceiver mReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- if (intent == null) {
- return;
- }
- final String action = intent.getAction();
- Log.v(TAG, "Received broadcast: " + action);
-
- if (Intent.ACTION_MANAGED_PROFILE_AVAILABLE.equals(action)
- || Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE.equals(action)) {
- if (intent.getIntExtra(Intent.EXTRA_USER_HANDLE,
- UserHandle.USER_NULL) == mManagedUser.getIdentifier()) {
- updateState(mPreference);
- }
- return;
- }
- Log.w(TAG, "Cannot handle received broadcast: " + intent.getAction());
- }
- };
-
@Override
@SliceData.SliceType
public int getSliceType() {
return SliceData.SliceType.SWITCH;
}
-}
\ No newline at end of file
+
+ @Override
+ public int getSliceHighlightMenuRes() {
+ return R.string.menu_key_accounts;
+ }
+
+ @VisibleForTesting
+ void setPreference(MainSwitchPreference preference) {
+ mSwitchPreference = preference;
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/accounts/ContactSearchPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accounts/ContactSearchPreferenceControllerTest.java
index c8606e134a5..bc65563650f 100644
--- a/tests/robotests/src/com/android/settings/accounts/ContactSearchPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/accounts/ContactSearchPreferenceControllerTest.java
@@ -20,13 +20,19 @@ import static android.provider.Settings.Secure.MANAGED_PROFILE_CONTACT_REMOTE_SE
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
import android.content.Context;
+import android.content.pm.UserInfo;
import android.os.UserHandle;
+import android.os.UserManager;
import android.provider.Settings;
+import androidx.test.core.app.ApplicationProvider;
+
import com.android.settingslib.RestrictedSwitchPreference;
import org.junit.Before;
@@ -35,39 +41,51 @@ import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
+
+import java.util.Collections;
@RunWith(RobolectricTestRunner.class)
public class ContactSearchPreferenceControllerTest {
private static final String PREF_KEY = "contacts_search";
-
- @Mock
- private UserHandle mManagedUser;
+ private static final int MANAGED_USER_ID = 10;
private Context mContext;
private ContactSearchPreferenceController mController;
private RestrictedSwitchPreference mPreference;
+ @Mock
+ private UserHandle mManagedUser;
+ @Mock
+ private UserManager mUserManager;
+ @Mock
+ private UserInfo mUserInfo;
+
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
- mContext = RuntimeEnvironment.application;
- mController = new ContactSearchPreferenceController(mContext, PREF_KEY);
- mController.setManagedUser(mManagedUser);
+ mContext = spy(ApplicationProvider.getApplicationContext());
+ when(mContext.getSystemService(UserManager.class)).thenReturn(mUserManager);
mPreference = spy(new RestrictedSwitchPreference(mContext));
+ when(mUserInfo.isManagedProfile()).thenReturn(true);
+ when(mUserManager.getUserInfo(anyInt())).thenReturn(mUserInfo);
+ when(mUserManager.getProcessUserId()).thenReturn(0);
+ when(mUserManager.getUserProfiles()).thenReturn(Collections.singletonList(mManagedUser));
+ when(mManagedUser.getIdentifier()).thenReturn(MANAGED_USER_ID);
+ mController = new ContactSearchPreferenceController(mContext, PREF_KEY);
}
@Test
public void getAvailabilityStatus_noManagedUser_DISABLED() {
- mController.setManagedUser(null);
+ when(mUserManager.getProcessUserId()).thenReturn(MANAGED_USER_ID);
+ mController = new ContactSearchPreferenceController(mContext, PREF_KEY);
+
assertThat(mController.getAvailabilityStatus())
.isNotEqualTo(ContactSearchPreferenceController.AVAILABLE);
}
@Test
public void getAvailabilityStatus_hasManagedUser_AVAILABLE() {
- mController.setManagedUser(mManagedUser);
assertThat(mController.getAvailabilityStatus())
.isEqualTo(ContactSearchPreferenceController.AVAILABLE);
}
@@ -75,32 +93,96 @@ public class ContactSearchPreferenceControllerTest {
@Test
public void updateState_shouldRefreshContent() {
Settings.Secure.putIntForUser(mContext.getContentResolver(),
- MANAGED_PROFILE_CONTACT_REMOTE_SEARCH, 0, mManagedUser.getIdentifier());
+ MANAGED_PROFILE_CONTACT_REMOTE_SEARCH, 0, MANAGED_USER_ID);
+
mController.updateState(mPreference);
+
assertThat(mPreference.isChecked()).isFalse();
Settings.Secure.putIntForUser(mContext.getContentResolver(),
- MANAGED_PROFILE_CONTACT_REMOTE_SEARCH, 1, mManagedUser.getIdentifier());
+ MANAGED_PROFILE_CONTACT_REMOTE_SEARCH, 1, MANAGED_USER_ID);
+
mController.updateState(mPreference);
+
assertThat(mPreference.isChecked()).isTrue();
}
@Test
public void updateState_preferenceShouldBeDisabled() {
mController.updateState(mPreference);
+
verify(mPreference).setDisabledByAdmin(any());
}
@Test
public void onPreferenceChange_shouldUpdateProviderValue() {
mController.onPreferenceChange(mPreference, false);
+
assertThat(Settings.Secure.getIntForUser(mContext.getContentResolver(),
- MANAGED_PROFILE_CONTACT_REMOTE_SEARCH, 1, mManagedUser.getIdentifier()))
+ MANAGED_PROFILE_CONTACT_REMOTE_SEARCH, 1, MANAGED_USER_ID))
.isEqualTo(0);
mController.onPreferenceChange(mPreference, true);
+
assertThat(Settings.Secure.getIntForUser(mContext.getContentResolver(),
- MANAGED_PROFILE_CONTACT_REMOTE_SEARCH, 0, mManagedUser.getIdentifier()))
+ MANAGED_PROFILE_CONTACT_REMOTE_SEARCH, 0, MANAGED_USER_ID))
.isEqualTo(1);
}
-}
\ No newline at end of file
+
+ @Test
+ public void onQuietModeDisabled_preferenceEnabled() {
+ when(mUserManager.isQuietModeEnabled(any(UserHandle.class))).thenReturn(false);
+
+ mController.updateState(mPreference);
+
+ assertThat(mPreference.isEnabled()).isTrue();
+ }
+
+ @Test
+ public void onQuietModeEnabled_preferenceDisabledAndUnchecked() {
+ when(mUserManager.isQuietModeEnabled(any(UserHandle.class))).thenReturn(true);
+
+ mController.updateState(mPreference);
+
+ assertThat(mPreference.isEnabled()).isFalse();
+ assertThat(mPreference.isChecked()).isFalse();
+ }
+
+ @Test
+ public void afterQuietModeTurnedOnAndOffWhenPreferenceChecked_toggleCheckedAndEnabled() {
+ Settings.Secure.putIntForUser(mContext.getContentResolver(),
+ MANAGED_PROFILE_CONTACT_REMOTE_SEARCH, 1, MANAGED_USER_ID);
+ when(mUserManager.isQuietModeEnabled(any(UserHandle.class))).thenReturn(true);
+
+ mController.updateState(mPreference);
+
+ assertThat(mPreference.isEnabled()).isFalse();
+ assertThat(mPreference.isChecked()).isFalse();
+
+ when(mUserManager.isQuietModeEnabled(any(UserHandle.class))).thenReturn(false);
+
+ mController.updateState(mPreference);
+
+ assertThat(mPreference.isEnabled()).isTrue();
+ assertThat(mPreference.isChecked()).isTrue();
+ }
+
+ @Test
+ public void afterQuietModeTurnedOnAndOffWhenPreferenceUnchecked_toggleUncheckedAndEnabled() {
+ Settings.Secure.putIntForUser(mContext.getContentResolver(),
+ MANAGED_PROFILE_CONTACT_REMOTE_SEARCH, 0, MANAGED_USER_ID);
+ when(mUserManager.isQuietModeEnabled(any(UserHandle.class))).thenReturn(true);
+
+ mController.updateState(mPreference);
+
+ assertThat(mPreference.isEnabled()).isFalse();
+ assertThat(mPreference.isChecked()).isFalse();
+
+ when(mUserManager.isQuietModeEnabled(any(UserHandle.class))).thenReturn(false);
+
+ mController.updateState(mPreference);
+
+ assertThat(mPreference.isEnabled()).isTrue();
+ assertThat(mPreference.isChecked()).isFalse();
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/accounts/ManagedProfileQuietModeEnablerTest.java b/tests/robotests/src/com/android/settings/accounts/ManagedProfileQuietModeEnablerTest.java
new file mode 100644
index 00000000000..2698efa4bd8
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/accounts/ManagedProfileQuietModeEnablerTest.java
@@ -0,0 +1,126 @@
+/*
+ * 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.settings.accounts;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.UserInfo;
+import android.os.UserHandle;
+import android.os.UserManager;
+
+import androidx.lifecycle.Lifecycle;
+import androidx.lifecycle.LifecycleOwner;
+import androidx.lifecycle.LifecycleRegistry;
+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;
+
+import java.util.Collections;
+
+
+@RunWith(RobolectricTestRunner.class)
+public class ManagedProfileQuietModeEnablerTest {
+ private static final int MANAGED_USER_ID = 10;
+ private Context mContext;
+ private ManagedProfileQuietModeEnabler mQuietModeEnabler;
+ private LifecycleOwner mLifecycleOwner = new LifecycleOwner() {
+ public LifecycleRegistry registry = new LifecycleRegistry(this);
+
+ @Override
+ public Lifecycle getLifecycle() {
+ return registry;
+ }
+ };
+
+ @Mock
+ private ManagedProfileQuietModeEnabler.QuietModeChangeListener mOnQuietModeChangeListener;
+ @Mock
+ private UserManager mUserManager;
+ @Mock
+ private UserHandle mManagedUser;
+ @Mock
+ private UserInfo mUserInfo;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ mContext = spy(ApplicationProvider.getApplicationContext());
+ when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager);
+ when(mUserInfo.isManagedProfile()).thenReturn(true);
+ when(mUserManager.getUserInfo(anyInt())).thenReturn(mUserInfo);
+ when(mUserManager.getProcessUserId()).thenReturn(0);
+ when(mManagedUser.getIdentifier()).thenReturn(MANAGED_USER_ID);
+ when(mUserManager.getUserProfiles()).thenReturn(Collections.singletonList(mManagedUser));
+ mQuietModeEnabler = new ManagedProfileQuietModeEnabler(mContext,
+ mOnQuietModeChangeListener);
+ }
+
+ @Test
+ public void onSetQuietMode_shouldRequestQuietModeEnabled() {
+ mQuietModeEnabler.setQuietModeEnabled(false);
+ verify(mUserManager).requestQuietModeEnabled(false, mManagedUser);
+ mQuietModeEnabler.setQuietModeEnabled(true);
+ verify(mUserManager).requestQuietModeEnabled(true, mManagedUser);
+ }
+
+ @Test
+ public void onIsQuietModeEnabled_shouldCallIsQuietModeEnabled() {
+ assertThat(mQuietModeEnabler.isQuietModeEnabled()).isEqualTo(
+ verify(mUserManager).isQuietModeEnabled(any()));
+ }
+
+ @Test
+ public void onQuietModeChanged_listenerNotified() {
+ mQuietModeEnabler.onStart(mLifecycleOwner);
+ mContext.sendBroadcast(new Intent(Intent.ACTION_MANAGED_PROFILE_AVAILABLE).putExtra(
+ Intent.EXTRA_USER_HANDLE, MANAGED_USER_ID));
+ mContext.sendBroadcast(new Intent(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE).putExtra(
+ Intent.EXTRA_USER_HANDLE, MANAGED_USER_ID));
+ verify(mOnQuietModeChangeListener, times(2)).onQuietModeChanged();
+ }
+
+ @Test
+ public void onStart_shouldRegisterReceiver() {
+ mQuietModeEnabler.onStart(mLifecycleOwner);
+ verify(mContext).registerReceiver(eq(mQuietModeEnabler.mReceiver), any(), anyInt());
+ }
+
+ @Test
+ public void onStop_shouldUnregisterReceiver() {
+ // register it first
+ mContext.registerReceiver(mQuietModeEnabler.mReceiver, null,
+ Context.RECEIVER_EXPORTED/*UNAUDITED*/);
+
+ mQuietModeEnabler.onStop(mLifecycleOwner);
+ verify(mContext).unregisterReceiver(mQuietModeEnabler.mReceiver);
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/accounts/WorkModePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accounts/WorkModePreferenceControllerTest.java
index 2a283181b1c..e862d108c7c 100644
--- a/tests/robotests/src/com/android/settings/accounts/WorkModePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/accounts/WorkModePreferenceControllerTest.java
@@ -19,18 +19,18 @@ import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.Context;
+import android.content.pm.UserInfo;
import android.os.UserHandle;
import android.os.UserManager;
-import androidx.preference.SwitchPreference;
+import androidx.test.core.app.ApplicationProvider;
-import com.android.settings.R;
+import com.android.settingslib.widget.MainSwitchPreference;
import org.junit.Before;
import org.junit.Test;
@@ -38,43 +38,51 @@ import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
+
+import java.util.Collections;
@RunWith(RobolectricTestRunner.class)
public class WorkModePreferenceControllerTest {
private static final String PREF_KEY = "work_mode";
+ private static final int MANAGED_USER_ID = 10;
+
+ private Context mContext;
+ private WorkModePreferenceController mController;
+ private MainSwitchPreference mPreference;
@Mock
private UserManager mUserManager;
@Mock
private UserHandle mManagedUser;
-
- private Context mContext;
- private WorkModePreferenceController mController;
- private SwitchPreference mPreference;
+ @Mock
+ private UserInfo mUserInfo;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
- mContext = spy(RuntimeEnvironment.application);
- when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager);
-
+ mContext = spy(ApplicationProvider.getApplicationContext());
+ when(mContext.getSystemService(UserManager.class)).thenReturn(mUserManager);
+ mPreference = new MainSwitchPreference(mContext);
+ when(mUserInfo.isManagedProfile()).thenReturn(true);
+ when(mUserManager.getUserInfo(anyInt())).thenReturn(mUserInfo);
+ when(mUserManager.getProcessUserId()).thenReturn(0);
+ when(mUserManager.getUserProfiles()).thenReturn(Collections.singletonList(mManagedUser));
+ when(mManagedUser.getIdentifier()).thenReturn(MANAGED_USER_ID);
mController = new WorkModePreferenceController(mContext, PREF_KEY);
- mController.setManagedUser(mManagedUser);
- mPreference = new SwitchPreference(mContext);
}
@Test
public void getAvailabilityStatus_noManagedUser_DISABLED() {
- mController.setManagedUser(null);
+ when(mUserManager.getProcessUserId()).thenReturn(MANAGED_USER_ID);
+ mController = new WorkModePreferenceController(mContext, PREF_KEY);
+
assertThat(mController.getAvailabilityStatus())
.isNotEqualTo(WorkModePreferenceController.AVAILABLE);
}
@Test
public void getAvailabilityStatus_hasManagedUser_AVAILABLE() {
- mController.setManagedUser(mManagedUser);
assertThat(mController.getAvailabilityStatus())
.isEqualTo(WorkModePreferenceController.AVAILABLE);
}
@@ -83,41 +91,29 @@ public class WorkModePreferenceControllerTest {
public void updateState_shouldRefreshContent() {
when(mUserManager.isQuietModeEnabled(any(UserHandle.class)))
.thenReturn(false);
+
mController.updateState(mPreference);
+
assertThat(mPreference.isChecked()).isTrue();
- assertThat(mPreference.getSummary())
- .isEqualTo(mContext.getText(R.string.work_mode_on_summary));
when(mUserManager.isQuietModeEnabled(any(UserHandle.class)))
.thenReturn(true);
+
mController.updateState(mPreference);
+
assertThat(mPreference.isChecked()).isFalse();
- assertThat(mPreference.getSummary())
- .isEqualTo(mContext.getText(R.string.work_mode_off_summary));
}
@Test
public void onPreferenceChange_shouldRequestQuietModeEnabled() {
+ mController.setPreference(mPreference);
+
mController.onPreferenceChange(mPreference, true);
+
verify(mUserManager).requestQuietModeEnabled(false, mManagedUser);
mController.onPreferenceChange(mPreference, false);
+
verify(mUserManager).requestQuietModeEnabled(true, mManagedUser);
}
-
- @Test
- public void onStart_shouldRegisterReceiver() {
- mController.onStart();
- verify(mContext).registerReceiver(eq(mController.mReceiver), any(), anyInt());
- }
-
- @Test
- public void onStop_shouldUnregisterReceiver() {
- // register it first
- mContext.registerReceiver(mController.mReceiver, null,
- Context.RECEIVER_EXPORTED/*UNAUDITED*/);
-
- mController.onStop();
- verify(mContext).unregisterReceiver(mController.mReceiver);
- }
}
\ No newline at end of file