From c69102d24e2e36d92a7548b5f92cf26adf6ce13b Mon Sep 17 00:00:00 2001 From: jason_chiu Date: Tue, 3 Apr 2018 11:37:09 +0800 Subject: [PATCH] Migrate ManagedProfileSettings to DashboardFragment - Move preference related logic to Controllers. - Add some test cases for controllers. Test: manual Test: make RunSettingsRoboTests -j ROBOTEST_FILTER=com.android.settings.accounts make RunSettingsRoboTests -j ROBOTEST_FILTER=com.android.settings.core atest SettingsGatewayTest UniquePreferenceTest Change-Id: If4fcd7bf572672c886d5c91b2d15013817d1aa67 --- res/xml/managed_profile_settings.xml | 7 +- .../ContactSearchPreferenceController.java | 88 +++++++++++ .../accounts/ManagedProfileSettings.java | 114 ++++---------- .../WorkModePreferenceController.java | 146 ++++++++++++++++++ ...randfather_not_implementing_index_provider | 1 + .../grandfather_not_implementing_indexable | 1 - ...ContactSearchPreferenceControllerTest.java | 104 +++++++++++++ .../WorkModePreferenceControllerTest.java | 119 ++++++++++++++ 8 files changed, 491 insertions(+), 89 deletions(-) create mode 100644 src/com/android/settings/accounts/ContactSearchPreferenceController.java create mode 100644 src/com/android/settings/accounts/WorkModePreferenceController.java create mode 100644 tests/robotests/src/com/android/settings/accounts/ContactSearchPreferenceControllerTest.java create mode 100644 tests/robotests/src/com/android/settings/accounts/WorkModePreferenceControllerTest.java diff --git a/res/xml/managed_profile_settings.xml b/res/xml/managed_profile_settings.xml index c283e13ca52..ee1e4fadec3 100644 --- a/res/xml/managed_profile_settings.xml +++ b/res/xml/managed_profile_settings.xml @@ -16,17 +16,20 @@ + android:summary="@string/summary_placeholder" + settings:controller="com.android.settings.accounts.WorkModePreferenceController"/> + settings:useAdditionalSummary="true" + settings:controller="com.android.settings.accounts.ContactSearchPreferenceController"/> \ No newline at end of file diff --git a/src/com/android/settings/accounts/ContactSearchPreferenceController.java b/src/com/android/settings/accounts/ContactSearchPreferenceController.java new file mode 100644 index 00000000000..578a5cb3a77 --- /dev/null +++ b/src/com/android/settings/accounts/ContactSearchPreferenceController.java @@ -0,0 +1,88 @@ +/* + * 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 + * + * 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 android.provider.Settings.Secure.MANAGED_PROFILE_CONTACT_REMOTE_SEARCH; + +import android.content.Context; +import android.os.UserHandle; +import android.provider.Settings; +import android.support.v7.preference.Preference; + +import com.android.settings.core.BasePreferenceController; +import com.android.settings.slices.SliceData; +import com.android.settingslib.RestrictedLockUtils; +import com.android.settingslib.RestrictedSwitchPreference; + +public class ContactSearchPreferenceController extends BasePreferenceController implements + Preference.OnPreferenceChangeListener { + + private UserHandle mManagedUser; + + public ContactSearchPreferenceController(Context context, String key) { + super(context, key); + } + + public void setManagedUser(UserHandle managedUser) { + mManagedUser = managedUser; + } + + @Override + public int getAvailabilityStatus() { + return (mManagedUser != null) ? AVAILABLE : DISABLED_FOR_USER; + } + + @Override + public void updateState(Preference preference) { + super.updateState(preference); + if (preference instanceof RestrictedSwitchPreference) { + final RestrictedSwitchPreference pref = (RestrictedSwitchPreference) preference; + pref.setChecked(isChecked()); + if (mManagedUser != null) { + final RestrictedLockUtils.EnforcedAdmin enforcedAdmin = + RestrictedLockUtils.checkIfRemoteContactSearchDisallowed( + mContext, mManagedUser.getIdentifier()); + pref.setDisabledByAdmin(enforcedAdmin); + } + } + } + + private boolean isChecked() { + if (mManagedUser == null) { + 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()); + } + return true; + } + + @Override + public final boolean onPreferenceChange(Preference preference, Object newValue) { + return setChecked((boolean) newValue); + } + + @Override + @SliceData.SliceType + public int getSliceType() { + return SliceData.SliceType.SWITCH; + } +} \ No newline at end of file diff --git a/src/com/android/settings/accounts/ManagedProfileSettings.java b/src/com/android/settings/accounts/ManagedProfileSettings.java index 8a519658b92..07e58458983 100644 --- a/src/com/android/settings/accounts/ManagedProfileSettings.java +++ b/src/com/android/settings/accounts/ManagedProfileSettings.java @@ -16,8 +16,6 @@ package com.android.settings.accounts; -import static android.provider.Settings.Secure.MANAGED_PROFILE_CONTACT_REMOTE_SEARCH; - import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; @@ -25,67 +23,61 @@ import android.content.IntentFilter; import android.os.Bundle; import android.os.UserHandle; import android.os.UserManager; -import android.provider.Settings; -import android.support.v14.preference.SwitchPreference; -import android.support.v7.preference.Preference; import android.util.Log; import com.android.internal.logging.nano.MetricsProto; import com.android.settings.R; -import com.android.settings.SettingsPreferenceFragment; import com.android.settings.Utils; -import com.android.settingslib.RestrictedLockUtils; -import com.android.settingslib.RestrictedSwitchPreference; +import com.android.settings.dashboard.DashboardFragment; /** * Setting page for managed profile. * FIXME: It currently assumes there is only one managed profile. */ -public class ManagedProfileSettings extends SettingsPreferenceFragment - implements Preference.OnPreferenceChangeListener { - - private SwitchPreference mWorkModePreference; - private RestrictedSwitchPreference mContactPrefrence; +public class ManagedProfileSettings extends DashboardFragment { private UserManager mUserManager; private UserHandle mManagedUser; - private Context mContext; private ManagedProfileBroadcastReceiver mManagedProfileBroadcastReceiver; - private static final String KEY_WORK_MODE = "work_mode"; - private static final String KEY_CONTACT = "contacts_search"; - private static final String TAG = "ManagedProfileSettings"; @Override - public void onCreate(Bundle icicle) { - super.onCreate(icicle); - addPreferencesFromResource(R.xml.managed_profile_settings); - mWorkModePreference = (SwitchPreference) findPreference(KEY_WORK_MODE); - mWorkModePreference.setOnPreferenceChangeListener(this); - mContactPrefrence = (RestrictedSwitchPreference) findPreference(KEY_CONTACT); - mContactPrefrence.setOnPreferenceChangeListener(this); - mContext = getActivity().getApplicationContext(); + protected String getLogTag() { + return TAG; + } + + @Override + protected int getPreferenceScreenResId() { + return R.xml.managed_profile_settings; + } + + @Override + public void onAttach(Context context) { + super.onAttach(context); mUserManager = (UserManager) getSystemService(Context.USER_SERVICE); mManagedUser = getManagedUserFromArgument(); if (mManagedUser == null) { getActivity().finish(); } + use(WorkModePreferenceController.class).setManagedUser(mManagedUser); + use(ContactSearchPreferenceController.class).setManagedUser(mManagedUser); + } + + @Override + public void onCreate(Bundle icicle) { + super.onCreate(icicle); mManagedProfileBroadcastReceiver = new ManagedProfileBroadcastReceiver(); mManagedProfileBroadcastReceiver.register(getActivity()); } - @Override - public void onResume() { - super.onResume(); - loadDataAndPopulateUi(); - } - @Override public void onDestroy() { super.onDestroy(); - mManagedProfileBroadcastReceiver.unregister(getActivity()); + if (mManagedProfileBroadcastReceiver != null) { + mManagedProfileBroadcastReceiver.unregister(getActivity()); + } } private UserHandle getManagedUserFromArgument() { @@ -102,59 +94,21 @@ public class ManagedProfileSettings extends SettingsPreferenceFragment return Utils.getManagedProfile(mUserManager); } - private void loadDataAndPopulateUi() { - if (mWorkModePreference != null) { - updateWorkModePreference(); - } - - if (mContactPrefrence != null) { - int value = Settings.Secure.getIntForUser(getContentResolver(), - MANAGED_PROFILE_CONTACT_REMOTE_SEARCH, 0, mManagedUser.getIdentifier()); - mContactPrefrence.setChecked(value != 0); - RestrictedLockUtils.EnforcedAdmin enforcedAdmin = - RestrictedLockUtils.checkIfRemoteContactSearchDisallowed( - mContext, mManagedUser.getIdentifier()); - mContactPrefrence.setDisabledByAdmin(enforcedAdmin); - } - } - @Override public int getMetricsCategory() { return MetricsProto.MetricsEvent.ACCOUNTS_WORK_PROFILE_SETTINGS; } - private void updateWorkModePreference() { - boolean isWorkModeOn = !mUserManager.isQuietModeEnabled(mManagedUser); - mWorkModePreference.setChecked(isWorkModeOn); - mWorkModePreference.setSummary(isWorkModeOn - ? R.string.work_mode_on_summary - : R.string.work_mode_off_summary); - } - - - @Override - public boolean onPreferenceChange(Preference preference, Object newValue) { - if (preference == mWorkModePreference) { - boolean quietModeEnabled = !(boolean) newValue; - mUserManager.requestQuietModeEnabled(quietModeEnabled, mManagedUser); - return true; - } - if (preference == mContactPrefrence) { - int value = ((boolean) newValue == true) ? 1 : 0; - Settings.Secure.putIntForUser(getContentResolver(), - MANAGED_PROFILE_CONTACT_REMOTE_SEARCH, value, mManagedUser.getIdentifier()); - return true; - } - return false; - } - private class ManagedProfileBroadcastReceiver extends 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 (action.equals(Intent.ACTION_MANAGED_PROFILE_REMOVED)) { + if (Intent.ACTION_MANAGED_PROFILE_REMOVED.equals(action)) { if (intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL) == mManagedUser.getIdentifier()) { getActivity().finish(); @@ -162,23 +116,12 @@ public class ManagedProfileSettings extends SettingsPreferenceFragment return; } - if (action.equals(Intent.ACTION_MANAGED_PROFILE_AVAILABLE) - || action.equals(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE)) { - if (intent.getIntExtra(Intent.EXTRA_USER_HANDLE, - UserHandle.USER_NULL) == mManagedUser.getIdentifier()) { - updateWorkModePreference(); - } - return; - } Log.w(TAG, "Cannot handle received broadcast: " + intent.getAction()); } - public void register(Context context) { IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(Intent.ACTION_MANAGED_PROFILE_REMOVED); - intentFilter.addAction(Intent.ACTION_MANAGED_PROFILE_AVAILABLE); - intentFilter.addAction(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE); context.registerReceiver(this, intentFilter); } @@ -186,5 +129,4 @@ public class ManagedProfileSettings extends SettingsPreferenceFragment context.unregisterReceiver(this); } } - } diff --git a/src/com/android/settings/accounts/WorkModePreferenceController.java b/src/com/android/settings/accounts/WorkModePreferenceController.java new file mode 100644 index 00000000000..e3fb15d5e8a --- /dev/null +++ b/src/com/android/settings/accounts/WorkModePreferenceController.java @@ -0,0 +1,146 @@ +/* + * 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 + * + * 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.support.annotation.VisibleForTesting; +import android.support.v7.preference.Preference; +import android.support.v7.preference.PreferenceScreen; +import android.support.v7.preference.TwoStatePreference; +import android.util.Log; + +import com.android.settings.R; +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; + +public class WorkModePreferenceController extends BasePreferenceController implements + Preference.OnPreferenceChangeListener, LifecycleObserver, OnStart, OnStop { + + private static final String TAG = "WorkModeController"; + + private UserManager mUserManager; + private UserHandle mManagedUser; + + private Preference mPreference; + private IntentFilter mIntentFilter; + + public WorkModePreferenceController(Context context, String key) { + super(context, key); + mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE); + mIntentFilter = new IntentFilter(); + mIntentFilter.addAction(Intent.ACTION_MANAGED_PROFILE_AVAILABLE); + mIntentFilter.addAction(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE); + } + + public void setManagedUser(UserHandle managedUser) { + mManagedUser = managedUser; + } + + @Override + public void onStart() { + mContext.registerReceiver(mReceiver, mIntentFilter); + } + + @Override + public void onStop() { + mContext.unregisterReceiver(mReceiver); + } + + @Override + public int getAvailabilityStatus() { + return (mManagedUser != null) ? AVAILABLE : DISABLED_FOR_USER; + } + + @Override + public void displayPreference(PreferenceScreen screen) { + super.displayPreference(screen); + mPreference = screen.findPreference(getPreferenceKey()); + } + + @Override + public CharSequence getSummary() { + return mContext.getText(isChecked() + ? R.string.work_mode_on_summary + : R.string.work_mode_off_summary); + } + + private boolean isChecked() { + boolean isWorkModeOn = false; + if (mUserManager != null && mManagedUser != null) { + isWorkModeOn = !mUserManager.isQuietModeEnabled(mManagedUser); + } + return isWorkModeOn; + } + + private boolean setChecked(boolean isChecked) { + if (mUserManager != null && mManagedUser != null) { + final boolean quietModeEnabled = !isChecked; + mUserManager.requestQuietModeEnabled(quietModeEnabled, mManagedUser); + } + return true; + } + + @Override + public void updateState(Preference preference) { + super.updateState(preference); + if (preference instanceof TwoStatePreference) { + ((TwoStatePreference) preference).setChecked(isChecked()); + } + } + + @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 diff --git a/tests/robotests/assets/grandfather_not_implementing_index_provider b/tests/robotests/assets/grandfather_not_implementing_index_provider index 39e63d4baa7..4c9bf60eaf4 100644 --- a/tests/robotests/assets/grandfather_not_implementing_index_provider +++ b/tests/robotests/assets/grandfather_not_implementing_index_provider @@ -3,6 +3,7 @@ com.android.settings.bluetooth.DevicePickerFragment com.android.settings.bluetooth.BluetoothDeviceDetailsFragment com.android.settings.bluetooth.BluetoothPairingDetail com.android.settings.accounts.AccountDetailDashboardFragment +com.android.settings.accounts.ManagedProfileSettings com.android.settings.fuelgauge.PowerUsageAnomalyDetails com.android.settings.fuelgauge.AdvancedPowerUsageDetail com.android.settings.development.featureflags.FeatureFlagsDashboard diff --git a/tests/robotests/assets/grandfather_not_implementing_indexable b/tests/robotests/assets/grandfather_not_implementing_indexable index 5a89072b2ef..918cb4c788d 100644 --- a/tests/robotests/assets/grandfather_not_implementing_indexable +++ b/tests/robotests/assets/grandfather_not_implementing_indexable @@ -21,7 +21,6 @@ com.android.settings.applications.appinfo.WriteSettingsDetails com.android.settings.applications.ProcessStatsSummary com.android.settings.users.RestrictedProfileSettings com.android.settings.accounts.ChooseAccountActivity -com.android.settings.accounts.ManagedProfileSettings com.android.settings.accessibility.ToggleAutoclickPreferenceFragment com.android.settings.applications.AppLaunchSettings com.android.settings.applications.ProcessStatsUi diff --git a/tests/robotests/src/com/android/settings/accounts/ContactSearchPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accounts/ContactSearchPreferenceControllerTest.java new file mode 100644 index 00000000000..ba25f207ed3 --- /dev/null +++ b/tests/robotests/src/com/android/settings/accounts/ContactSearchPreferenceControllerTest.java @@ -0,0 +1,104 @@ +/* + * 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 + * + * 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 android.provider.Settings.Secure.MANAGED_PROFILE_CONTACT_REMOTE_SEARCH; +import static com.google.common.truth.Truth.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; + +import android.content.Context; +import android.provider.Settings; +import android.os.UserHandle; + +import com.android.settings.testutils.SettingsRobolectricTestRunner; +import com.android.settingslib.RestrictedSwitchPreference; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.robolectric.RuntimeEnvironment; + +@RunWith(SettingsRobolectricTestRunner.class) +public class ContactSearchPreferenceControllerTest { + + private static final String PREF_KEY = "contacts_search"; + + @Mock + private UserHandle mManagedUser; + + private Context mContext; + private ContactSearchPreferenceController mController; + private RestrictedSwitchPreference mPreference; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + mContext = RuntimeEnvironment.application; + mController = new ContactSearchPreferenceController(mContext, PREF_KEY); + mController.setManagedUser(mManagedUser); + mPreference = spy(new RestrictedSwitchPreference(mContext)); + } + + @Test + public void getAvailabilityStatus_noManagedUser_DISABLED() { + mController.setManagedUser(null); + assertThat(mController.getAvailabilityStatus()) + .isNotEqualTo(ContactSearchPreferenceController.AVAILABLE); + } + + @Test + public void getAvailabilityStatus_hasManagedUser_AVAILABLE() { + mController.setManagedUser(mManagedUser); + assertThat(mController.getAvailabilityStatus()) + .isEqualTo(ContactSearchPreferenceController.AVAILABLE); + } + + @Test + public void updateState_shouldRefreshContent() { + Settings.Secure.putIntForUser(mContext.getContentResolver(), + MANAGED_PROFILE_CONTACT_REMOTE_SEARCH, 0, mManagedUser.getIdentifier()); + mController.updateState(mPreference); + assertThat(mPreference.isChecked()).isFalse(); + + Settings.Secure.putIntForUser(mContext.getContentResolver(), + MANAGED_PROFILE_CONTACT_REMOTE_SEARCH, 1, mManagedUser.getIdentifier()); + 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())) + .isEqualTo(0); + + mController.onPreferenceChange(mPreference, true); + assertThat(Settings.Secure.getIntForUser(mContext.getContentResolver(), + MANAGED_PROFILE_CONTACT_REMOTE_SEARCH, 0, mManagedUser.getIdentifier())) + .isEqualTo(1); + } +} \ No newline at end of file diff --git a/tests/robotests/src/com/android/settings/accounts/WorkModePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accounts/WorkModePreferenceControllerTest.java new file mode 100644 index 00000000000..3755d644ee6 --- /dev/null +++ b/tests/robotests/src/com/android/settings/accounts/WorkModePreferenceControllerTest.java @@ -0,0 +1,119 @@ +/* + * 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 + * + * 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.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.os.UserHandle; +import android.os.UserManager; +import android.support.v14.preference.SwitchPreference; + +import com.android.settings.R; +import com.android.settings.testutils.SettingsRobolectricTestRunner; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.robolectric.RuntimeEnvironment; + +@RunWith(SettingsRobolectricTestRunner.class) +public class WorkModePreferenceControllerTest { + + private static final String PREF_KEY = "work_mode"; + + @Mock + private UserManager mUserManager; + @Mock + private UserHandle mManagedUser; + + private Context mContext; + private WorkModePreferenceController mController; + private SwitchPreference mPreference; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + mContext = spy(RuntimeEnvironment.application); + when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager); + + mController = new WorkModePreferenceController(mContext, PREF_KEY); + mController.setManagedUser(mManagedUser); + mPreference = new SwitchPreference(mContext); + } + + @Test + public void getAvailabilityStatus_noManagedUser_DISABLED() { + mController.setManagedUser(null); + assertThat(mController.getAvailabilityStatus()) + .isNotEqualTo(WorkModePreferenceController.AVAILABLE); + } + + @Test + public void getAvailabilityStatus_hasManagedUser_AVAILABLE() { + mController.setManagedUser(mManagedUser); + assertThat(mController.getAvailabilityStatus()) + .isEqualTo(WorkModePreferenceController.AVAILABLE); + } + + @Test + 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.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()); + } + + @Test + public void onStop_shouldUnregisterReceiver() { + // register it first + mContext.registerReceiver(mController.mReceiver, null); + + mController.onStop(); + verify(mContext).unregisterReceiver(mController.mReceiver); + } +} \ No newline at end of file