android:targetClass="com.android.cellbroadcastreceiver.CellBroadcastSettings" />
</com.android.settingslib.RestrictedPreference>
+ <com.android.settings.WorkOnlyCategory
+ android:key="sound_work_settings_section"
+ android:title="@string/sound_work_settings">
+
+ <!-- Use the same sounds of the work profile -->
+ <SwitchPreference
+ android:key="work_use_personal_sounds"
+ android:title="@string/work_use_personal_sounds_title"
+ android:summary="@string/work_use_personal_sounds_summary"
+ android:disableDependentsState="true" />
+
+ <!-- Work phone ringtone -->
+ <com.android.settings.DefaultRingtonePreference
+ android:key="work_ringtone"
+ android:title="@string/work_ringtone_title"
+ android:dialogTitle="@string/work_alarm_ringtone_title"
+ android:ringtoneType="ringtone"
+ android:dependency="work_use_personal_sounds" />
+
+ <!-- Default work notification ringtone -->
+ <com.android.settings.DefaultRingtonePreference
+ android:key="work_notification_ringtone"
+ android:title="@string/work_notification_ringtone_title"
+ android:dialogTitle="@string/work_alarm_ringtone_title"
+ android:ringtoneType="notification"
+ android:dependency="work_use_personal_sounds" />
+
+ <!-- Default work alarm ringtone -->
+ <com.android.settings.DefaultRingtonePreference
+ android:key="work_alarm_ringtone"
+ android:title="@string/work_alarm_ringtone_title"
+ android:dialogTitle="@string/work_alarm_ringtone_title"
+ android:persistent="false"
+ android:ringtoneType="alarm"
+ android:dependency="work_use_personal_sounds" />
+
+ </com.android.settings.WorkOnlyCategory>
</PreferenceScreen>
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2016 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:settings="http://schemas.android.com/apk/res/com.android.settings"
- android:title="@string/sound_work_settings"
- android:key="sound_work_settings">
-
- <PreferenceCategory
- android:key="sound_work_settings_section"
- android:title="@string/sound_work_settings">
-
- <!-- Use the same sounds of the work profile -->
- <SwitchPreference
- android:key="work_use_personal_sounds"
- android:title="@string/work_use_personal_sounds_title"
- android:summary="@string/work_use_personal_sounds_summary"
- android:disableDependentsState="true" />
-
- <!-- Work phone ringtone -->
- <com.android.settings.DefaultRingtonePreference
- android:key="work_ringtone"
- android:title="@string/work_ringtone_title"
- android:dialogTitle="@string/work_alarm_ringtone_title"
- android:ringtoneType="ringtone"
- android:dependency="work_use_personal_sounds" />
-
- <!-- Default work notification ringtone -->
- <com.android.settings.DefaultRingtonePreference
- android:key="work_notification_ringtone"
- android:title="@string/work_notification_ringtone_title"
- android:dialogTitle="@string/work_alarm_ringtone_title"
- android:ringtoneType="notification"
- android:dependency="work_use_personal_sounds" />
-
- <!-- Default work alarm ringtone -->
- <com.android.settings.DefaultRingtonePreference
- android:key="work_alarm_ringtone"
- android:title="@string/work_alarm_ringtone_title"
- android:dialogTitle="@string/work_alarm_ringtone_title"
- android:persistent="false"
- android:ringtoneType="alarm"
- android:dependency="work_use_personal_sounds" />
-
- </PreferenceCategory>
-
-</PreferenceScreen>
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;
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;
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";
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);
@Override
public void displayPreference(PreferenceScreen screen) {
- // do nothing
+ mWorkPreferenceCategory = (PreferenceGroup) screen.findPreference(KEY_WORK_CATEGORY);
+ if (mWorkPreferenceCategory != null) {
+ mWorkPreferenceCategory.setVisible(isAvailable());
+ }
}
@Override
mContext.registerReceiver(mManagedProfileReceiver, managedProfileFilter);
mManagedProfileId = mHelper.getManagedProfileId(mUserManager);
- initWorkPreferences();
+ updateWorkPreferences();
}
@Override
}
Uri ringtoneUri = RingtoneManager.getActualDefaultRingtoneUri(context, type);
return Ringtone.getTitle(context, ringtoneUri, false /* followSettingsUri */,
- true /* allowRemote */);
+ true /* allowRemote */);
}
private Context getManagedProfileContext() {
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
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);
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();
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() {
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();
}
}
};
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;
@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) {
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;
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;
@Mock
private PreferenceScreen mScreen;
@Mock
+ private PreferenceCategory mWorkCategory;
+ @Mock
private TelephonyManager mTelephonyManager;
@Mock
private AudioHelper mAudioHelper;
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);
}
}
@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.
- mController.onResume();
+ // When the fragment first displays, the category should not appear.
+ mController.displayPreference(mScreen);
+ verify(mWorkCategory).setVisible(false);
- verify(mFragment, never()).addPreferencesFromResource(R.xml.sound_work_settings);
- // However, when a managed profile is added after resuming, the category should appear.
+ // However, when a managed profile is added later, the category should appear.
+ mController.onResume();
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);
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 onResume_notAvailable_shouldNotAddPreferenceCategory() {
+ public void displayPreference_isAvailable_shouldShowPreferenceCategory() {
when(mAudioHelper.getManagedProfileId(any(UserManager.class)))
- .thenReturn(UserHandle.USER_NULL);
- when(mAudioHelper.isSingleVolume()).thenReturn(true);
+ .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.onResume();
+ mController.displayPreference(mScreen);
+ verify(mWorkCategory).setVisible(true);
+ }
+
+ @Test
+ public void displayPreference_notAvailable_shouldHidePreferenceCategory() {
+ when(mAudioHelper.getManagedProfileId(any(UserManager.class)))
+ .thenReturn(UserHandle.USER_NULL);
+ when(mAudioHelper.isSingleVolume()).thenReturn(true);
+ when(mFragment.getPreferenceScreen()).thenReturn(mScreen);
- verify(mFragment, never()).addPreferencesFromResource(anyInt());
+ mController.displayPreference(mScreen);
+ verify(mWorkCategory).setVisible(false);
}
@Test
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));
}
}