diff --git a/res/xml/ia_sound_settings.xml b/res/xml/ia_sound_settings.xml index 27fcddad9e8..a34d8759fad 100644 --- a/res/xml/ia_sound_settings.xml +++ b/res/xml/ia_sound_settings.xml @@ -151,4 +151,41 @@ android:targetClass="com.android.cellbroadcastreceiver.CellBroadcastSettings" /> + + + + + + + + + + + + + + + diff --git a/res/xml/sound_work_settings.xml b/res/xml/sound_work_settings.xml deleted file mode 100644 index b63ec75bf1f..00000000000 --- a/res/xml/sound_work_settings.xml +++ /dev/null @@ -1,60 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/com/android/settings/notification/WorkSoundPreferenceController.java b/src/com/android/settings/notification/WorkSoundPreferenceController.java index 5ffb30bf6b2..a4d7b8d7c28 100644 --- a/src/com/android/settings/notification/WorkSoundPreferenceController.java +++ b/src/com/android/settings/notification/WorkSoundPreferenceController.java @@ -25,7 +25,6 @@ import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.IntentFilter; -import android.media.AudioSystem; import android.media.Ringtone; import android.media.RingtoneManager; import android.net.Uri; @@ -38,7 +37,6 @@ import android.support.v7.preference.Preference.OnPreferenceChangeListener; import android.support.v7.preference.PreferenceGroup; import android.support.v7.preference.PreferenceScreen; import android.support.v7.preference.TwoStatePreference; -import android.util.Log; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; @@ -53,7 +51,7 @@ import com.android.settings.core.lifecycle.events.OnPause; import com.android.settings.core.lifecycle.events.OnResume; public class WorkSoundPreferenceController extends PreferenceController implements - OnPreferenceChangeListener, LifecycleObserver, OnResume, OnPause { + OnPreferenceChangeListener, LifecycleObserver, OnResume, OnPause { private static final String TAG = "WorkSoundPrefController"; private static final String KEY_WORK_CATEGORY = "sound_work_settings_section"; @@ -62,27 +60,28 @@ public class WorkSoundPreferenceController extends PreferenceController implemen private static final String KEY_WORK_NOTIFICATION_RINGTONE = "work_notification_ringtone"; private static final String KEY_WORK_ALARM_RINGTONE = "work_alarm_ringtone"; + private final boolean mVoiceCapable; + private final UserManager mUserManager; + private final SoundSettings mParent; + private final AudioHelper mHelper; + private PreferenceGroup mWorkPreferenceCategory; private TwoStatePreference mWorkUsePersonalSounds; private Preference mWorkPhoneRingtonePreference; private Preference mWorkNotificationRingtonePreference; private Preference mWorkAlarmRingtonePreference; - private boolean mVoiceCapable; - private UserManager mUserManager; - private SoundSettings mParent; - private AudioHelper mHelper; - private @UserIdInt - int mManagedProfileId; + @UserIdInt + private int mManagedProfileId; public WorkSoundPreferenceController(Context context, SoundSettings parent, - Lifecycle lifecycle) { + Lifecycle lifecycle) { this(context, parent, lifecycle, new AudioHelper(context)); } @VisibleForTesting WorkSoundPreferenceController(Context context, SoundSettings parent, Lifecycle lifecycle, - AudioHelper helper) { + AudioHelper helper) { super(context); mUserManager = UserManager.get(context); mVoiceCapable = Utils.isVoiceCapable(mContext); @@ -95,7 +94,10 @@ public class WorkSoundPreferenceController extends PreferenceController implemen @Override public void displayPreference(PreferenceScreen screen) { - // do nothing + mWorkPreferenceCategory = (PreferenceGroup) screen.findPreference(KEY_WORK_CATEGORY); + if (mWorkPreferenceCategory != null) { + mWorkPreferenceCategory.setVisible(isAvailable()); + } } @Override @@ -106,7 +108,7 @@ public class WorkSoundPreferenceController extends PreferenceController implemen mContext.registerReceiver(mManagedProfileReceiver, managedProfileFilter); mManagedProfileId = mHelper.getManagedProfileId(mUserManager); - initWorkPreferences(); + updateWorkPreferences(); } @Override @@ -165,7 +167,7 @@ public class WorkSoundPreferenceController extends PreferenceController implemen } Uri ringtoneUri = RingtoneManager.getActualDefaultRingtoneUri(context, type); return Ringtone.getTitle(context, ringtoneUri, false /* followSettingsUri */, - true /* allowRemote */); + true /* allowRemote */); } private Context getManagedProfileContext() { @@ -175,9 +177,9 @@ public class WorkSoundPreferenceController extends PreferenceController implemen return mHelper.createPackageContextAsUser(mManagedProfileId); } - private DefaultRingtonePreference initWorkPreference(String key) { + private DefaultRingtonePreference initWorkPreference(PreferenceGroup root, String key) { DefaultRingtonePreference pref = - (DefaultRingtonePreference) mParent.getPreferenceScreen().findPreference(key); + (DefaultRingtonePreference) root.findPreference(key); pref.setOnPreferenceChangeListener(this); // Required so that RingtonePickerActivity lists the work profile ringtones @@ -185,24 +187,18 @@ public class WorkSoundPreferenceController extends PreferenceController implemen return pref; } - private void initWorkPreferences() { - if (mManagedProfileId == UserHandle.USER_NULL || !isAvailable()) { - maybeRemoveWorkPreferences(); + private void updateWorkPreferences() { + if (mWorkPreferenceCategory == null) { return; } - - if (mWorkPreferenceCategory == null) { - mParent.addPreferencesFromResource(R.xml.sound_work_settings); - final PreferenceScreen screen = mParent.getPreferenceScreen(); - - mWorkPreferenceCategory = (PreferenceGroup) screen.findPreference(KEY_WORK_CATEGORY); + final boolean isAvailable = isAvailable(); + mWorkPreferenceCategory.setVisible(isAvailable); + if (!isAvailable) { + return; + } + if (mWorkUsePersonalSounds == null) { mWorkUsePersonalSounds = (TwoStatePreference) - screen.findPreference(KEY_WORK_USE_PERSONAL_SOUNDS); - mWorkPhoneRingtonePreference = initWorkPreference(KEY_WORK_PHONE_RINGTONE); - mWorkNotificationRingtonePreference = initWorkPreference( - KEY_WORK_NOTIFICATION_RINGTONE); - mWorkAlarmRingtonePreference = initWorkPreference(KEY_WORK_ALARM_RINGTONE); - + mWorkPreferenceCategory.findPreference(KEY_WORK_USE_PERSONAL_SOUNDS); mWorkUsePersonalSounds.setOnPreferenceChangeListener((Preference p, Object value) -> { if ((boolean) value) { UnifyWorkDialogFragment.show(mParent); @@ -212,16 +208,27 @@ public class WorkSoundPreferenceController extends PreferenceController implemen return true; } }); - - if (!mVoiceCapable) { - mWorkPreferenceCategory.removePreference(mWorkPhoneRingtonePreference); - mWorkPhoneRingtonePreference = null; - } + } + if (mWorkPhoneRingtonePreference == null) { + mWorkPhoneRingtonePreference = initWorkPreference(mWorkPreferenceCategory, + KEY_WORK_PHONE_RINGTONE); + } + if (mWorkNotificationRingtonePreference == null) { + mWorkNotificationRingtonePreference = initWorkPreference(mWorkPreferenceCategory, + KEY_WORK_NOTIFICATION_RINGTONE); + } + if (mWorkAlarmRingtonePreference == null) { + mWorkAlarmRingtonePreference = initWorkPreference(mWorkPreferenceCategory, + KEY_WORK_ALARM_RINGTONE); + } + if (!mVoiceCapable) { + mWorkPreferenceCategory.removePreference(mWorkPhoneRingtonePreference); + mWorkPhoneRingtonePreference = null; } - Context managedProfileContext = getManagedProfileContext(); + final Context managedProfileContext = getManagedProfileContext(); if (Settings.Secure.getIntForUser(managedProfileContext.getContentResolver(), - Settings.Secure.SYNC_PARENT_SOUNDS, 0, mManagedProfileId) == 1) { + Settings.Secure.SYNC_PARENT_SOUNDS, 0, mManagedProfileId) == 1) { enableWorkSyncSettings(); } else { disableWorkSyncSettings(); @@ -237,13 +244,10 @@ public class WorkSoundPreferenceController extends PreferenceController implemen mWorkUsePersonalSounds.setChecked(true); if (mWorkPhoneRingtonePreference != null) { - mWorkPhoneRingtonePreference.setSummary( - com.android.settings.R.string.work_sound_same_as_personal); + mWorkPhoneRingtonePreference.setSummary(R.string.work_sound_same_as_personal); } - mWorkNotificationRingtonePreference.setSummary( - com.android.settings.R.string.work_sound_same_as_personal); - mWorkAlarmRingtonePreference.setSummary( - com.android.settings.R.string.work_sound_same_as_personal); + mWorkNotificationRingtonePreference.setSummary(R.string.work_sound_same_as_personal); + mWorkAlarmRingtonePreference.setSummary(R.string.work_sound_same_as_personal); } private void disableWorkSync() { @@ -266,36 +270,25 @@ public class WorkSoundPreferenceController extends PreferenceController implemen if (mWorkPhoneRingtonePreference != null) { mWorkPhoneRingtonePreference.setSummary( - updateRingtoneName(managedProfileContext, RingtoneManager.TYPE_RINGTONE)); + updateRingtoneName(managedProfileContext, RingtoneManager.TYPE_RINGTONE)); } mWorkNotificationRingtonePreference.setSummary( - updateRingtoneName(managedProfileContext, RingtoneManager.TYPE_NOTIFICATION)); + updateRingtoneName(managedProfileContext, RingtoneManager.TYPE_NOTIFICATION)); mWorkAlarmRingtonePreference.setSummary( - updateRingtoneName(managedProfileContext, RingtoneManager.TYPE_ALARM)); - } - - private void maybeRemoveWorkPreferences() { - if (mWorkPreferenceCategory == null) { - return; - } - mParent.getPreferenceScreen().removePreference(mWorkPreferenceCategory); - mWorkPreferenceCategory = null; - mWorkPhoneRingtonePreference = null; - mWorkNotificationRingtonePreference = null; - mWorkAlarmRingtonePreference = null; + updateRingtoneName(managedProfileContext, RingtoneManager.TYPE_ALARM)); } public void onManagedProfileAdded(@UserIdInt int profileId) { if (mManagedProfileId == UserHandle.USER_NULL) { mManagedProfileId = profileId; - initWorkPreferences(); + updateWorkPreferences(); } } public void onManagedProfileRemoved(@UserIdInt int profileId) { if (mManagedProfileId == profileId) { mManagedProfileId = mHelper.getManagedProfileId(mUserManager); - initWorkPreferences(); + updateWorkPreferences(); } } @@ -317,7 +310,7 @@ public class WorkSoundPreferenceController extends PreferenceController implemen }; public static class UnifyWorkDialogFragment extends InstrumentedDialogFragment - implements DialogInterface.OnClickListener { + implements DialogInterface.OnClickListener { private static final String TAG = "UnifyWorkDialogFragment"; private static final int REQUEST_CODE = 200; @@ -329,12 +322,11 @@ public class WorkSoundPreferenceController extends PreferenceController implemen @Override public Dialog onCreateDialog(Bundle savedInstanceState) { return new AlertDialog.Builder(getActivity()) - .setTitle(com.android.settings.R.string.work_sync_dialog_title) - .setMessage(com.android.settings.R.string.work_sync_dialog_message) - .setPositiveButton(com.android.settings.R.string.work_sync_dialog_yes, - UnifyWorkDialogFragment.this) - .setNegativeButton(android.R.string.no, null) - .create(); + .setTitle(R.string.work_sync_dialog_title) + .setMessage(R.string.work_sync_dialog_message) + .setPositiveButton(R.string.work_sync_dialog_yes, UnifyWorkDialogFragment.this) + .setNegativeButton(android.R.string.no, null) + .create(); } public static void show(SoundSettings parent) { diff --git a/tests/robotests/src/com/android/settings/notification/WorkSoundPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/WorkSoundPreferenceControllerTest.java index acfd400383c..13abd97c394 100644 --- a/tests/robotests/src/com/android/settings/notification/WorkSoundPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/notification/WorkSoundPreferenceControllerTest.java @@ -17,11 +17,10 @@ package com.android.settings.notification; import android.content.Context; -import android.os.Build.VERSION_CODES; import android.os.UserHandle; import android.os.UserManager; import android.support.v7.preference.Preference; -import android.support.v7.preference.PreferenceGroup; +import android.support.v7.preference.PreferenceCategory; import android.support.v7.preference.PreferenceScreen; import android.support.v7.preference.TwoStatePreference; import android.telephony.TelephonyManager; @@ -36,17 +35,15 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; -import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; import static com.google.common.truth.Truth.assertThat; - import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyInt; import static org.mockito.Matchers.anyString; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; +import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -65,6 +62,8 @@ public class WorkSoundPreferenceControllerTest { @Mock private PreferenceScreen mScreen; @Mock + private PreferenceCategory mWorkCategory; + @Mock private TelephonyManager mTelephonyManager; @Mock private AudioHelper mAudioHelper; @@ -78,6 +77,17 @@ public class WorkSoundPreferenceControllerTest { MockitoAnnotations.initMocks(this); when(mContext.getSystemService(Context.TELEPHONY_SERVICE)).thenReturn(mTelephonyManager); when(mTelephonyManager.isVoiceCapable()).thenReturn(true); + when(mScreen.findPreference(KEY_WORK_CATEGORY)) + .thenReturn(mWorkCategory); + when(mWorkCategory.findPreference(KEY_WORK_USE_PERSONAL_SOUNDS)) + .thenReturn(mock(TwoStatePreference.class)); + when(mWorkCategory.findPreference(KEY_WORK_PHONE_RINGTONE)) + .thenReturn(mock(DefaultRingtonePreference.class)); + when(mWorkCategory.findPreference(KEY_WORK_NOTIFICATION_RINGTONE)) + .thenReturn(mock(DefaultRingtonePreference.class)); + when(mWorkCategory.findPreference(KEY_WORK_ALARM_RINGTONE)) + .thenReturn(mock(DefaultRingtonePreference.class)); + mController = new WorkSoundPreferenceController(mContext, mFragment, null, mAudioHelper); } @@ -112,45 +122,30 @@ public class WorkSoundPreferenceControllerTest { } @Test - public void onResume_available_shouldAddPreferenceCategory() { - when(mAudioHelper.getManagedProfileId(any(UserManager.class))) - .thenReturn(UserHandle.myUserId()); - when(mAudioHelper.isUserUnlocked(any(UserManager.class), anyInt())).thenReturn(true); - when(mAudioHelper.isSingleVolume()).thenReturn(false); - when(mFragment.getPreferenceScreen()).thenReturn(mScreen); - when(mAudioHelper.createPackageContextAsUser(anyInt())).thenReturn(mContext); - mockWorkCategory(); - - mController.onResume(); - - verify(mFragment).addPreferencesFromResource(R.xml.sound_work_settings); - } - - @Test - public void onManagedProfileAdded_shouldAddPreferenceCategory() { + public void onManagedProfileAdded_shouldDisplayPreferenceCategory() { // Given a device without any managed profiles: when(mAudioHelper.isSingleVolume()).thenReturn(false); when(mFragment.getPreferenceScreen()).thenReturn(mScreen); when(mAudioHelper.createPackageContextAsUser(anyInt())).thenReturn(mContext); when(mAudioHelper.getManagedProfileId(any(UserManager.class))) .thenReturn(UserHandle.USER_NULL); - mockWorkCategory(); - // When the fragment first resumes, the category should not appear. + // When the fragment first displays, the category should not appear. + mController.displayPreference(mScreen); + verify(mWorkCategory).setVisible(false); + + + // However, when a managed profile is added later, the category should appear. mController.onResume(); - - verify(mFragment, never()).addPreferencesFromResource(R.xml.sound_work_settings); - - // However, when a managed profile is added after resuming, the category should appear. when(mAudioHelper.getManagedProfileId(any(UserManager.class))) .thenReturn(UserHandle.myUserId()); mController.onManagedProfileAdded(UserHandle.myUserId()); - verify(mFragment).addPreferencesFromResource(R.xml.sound_work_settings); + verify(mWorkCategory).setVisible(true); } @Test - public void onManagedProfileRemoved_shouldRemovePreferenceCategory() { + public void onManagedProfileRemoved_shouldHidePreferenceCategory() { // Given a device with a managed profile: when(mAudioHelper.isSingleVolume()).thenReturn(false); when(mFragment.getPreferenceScreen()).thenReturn(mScreen); @@ -158,29 +153,44 @@ public class WorkSoundPreferenceControllerTest { when(mAudioHelper.getManagedProfileId(any(UserManager.class))) .thenReturn(UserHandle.myUserId()); when(mAudioHelper.isUserUnlocked(any(UserManager.class), anyInt())).thenReturn(true); - mockWorkCategory(); // Which is in resumed state: + mController.displayPreference(mScreen); mController.onResume(); - // When a managed profile is removed, the category should be removed. + verify(mWorkCategory, times(2)).setVisible(true); + + // When a managed profile is removed, the category should be hidden. when(mAudioHelper.getManagedProfileId(any(UserManager.class))) .thenReturn(UserHandle.USER_NULL); mController.onManagedProfileRemoved(UserHandle.myUserId()); - verify(mScreen).removePreference(mScreen.findPreference(KEY_WORK_CATEGORY)); + verify(mWorkCategory).setVisible(false); + } + + + @Test + public void displayPreference_isAvailable_shouldShowPreferenceCategory() { + when(mAudioHelper.getManagedProfileId(any(UserManager.class))) + .thenReturn(UserHandle.myUserId()); + when(mAudioHelper.isUserUnlocked(any(UserManager.class), anyInt())).thenReturn(true); + when(mAudioHelper.isSingleVolume()).thenReturn(false); + when(mFragment.getPreferenceScreen()).thenReturn(mScreen); + when(mAudioHelper.createPackageContextAsUser(anyInt())).thenReturn(mContext); + + mController.displayPreference(mScreen); + verify(mWorkCategory).setVisible(true); } @Test - public void onResume_notAvailable_shouldNotAddPreferenceCategory() { + public void displayPreference_notAvailable_shouldHidePreferenceCategory() { when(mAudioHelper.getManagedProfileId(any(UserManager.class))) - .thenReturn(UserHandle.USER_NULL); + .thenReturn(UserHandle.USER_NULL); when(mAudioHelper.isSingleVolume()).thenReturn(true); when(mFragment.getPreferenceScreen()).thenReturn(mScreen); - mController.onResume(); - - verify(mFragment, never()).addPreferencesFromResource(anyInt()); + mController.displayPreference(mScreen); + verify(mWorkCategory).setVisible(false); } @Test @@ -206,27 +216,19 @@ public class WorkSoundPreferenceControllerTest { when(mAudioHelper.getManagedProfileId(any(UserManager.class))) .thenReturn(UserHandle.myUserId()); when(mAudioHelper.isUserUnlocked(any(UserManager.class), anyInt())).thenReturn(false); - mockWorkCategory(); // When resumed: + mController.displayPreference(mScreen); mController.onResume(); - // Sound preferences should explain that the profile isn't available yet. - verify(mScreen.findPreference(KEY_WORK_PHONE_RINGTONE)).setSummary(eq(notAvailable)); - verify(mScreen.findPreference(KEY_WORK_NOTIFICATION_RINGTONE)).setSummary(eq(notAvailable)); - verify(mScreen.findPreference(KEY_WORK_ALARM_RINGTONE)).setSummary(eq(notAvailable)); - } + verify(mWorkCategory, times(2)).setVisible(true); - private void mockWorkCategory() { - when(mScreen.findPreference(KEY_WORK_CATEGORY)) - .thenReturn(mock(PreferenceGroup.class)); - when(mScreen.findPreference(KEY_WORK_USE_PERSONAL_SOUNDS)) - .thenReturn(mock(TwoStatePreference.class)); - when(mScreen.findPreference(KEY_WORK_PHONE_RINGTONE)) - .thenReturn(mock(DefaultRingtonePreference.class)); - when(mScreen.findPreference(KEY_WORK_NOTIFICATION_RINGTONE)) - .thenReturn(mock(DefaultRingtonePreference.class)); - when(mScreen.findPreference(KEY_WORK_ALARM_RINGTONE)) - .thenReturn(mock(DefaultRingtonePreference.class)); + // Sound preferences should explain that the profile isn't available yet. + verify(mWorkCategory.findPreference(KEY_WORK_PHONE_RINGTONE)) + .setSummary(eq(notAvailable)); + verify(mWorkCategory.findPreference(KEY_WORK_NOTIFICATION_RINGTONE)) + .setSummary(eq(notAvailable)); + verify(mWorkCategory.findPreference(KEY_WORK_ALARM_RINGTONE)) + .setSummary(eq(notAvailable)); } }