Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6a56b8fe authored by Fan Zhang's avatar Fan Zhang Committed by Android (Google) Code Review
Browse files

Merge "Refactor sound setting -> work profile initialization logic."

parents f11c1671 3515cc82
Loading
Loading
Loading
Loading
+37 −0
Original line number Diff line number Diff line
@@ -151,4 +151,41 @@
                  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>

res/xml/sound_work_settings.xml

deleted100644 → 0
+0 −60
Original line number Diff line number Diff line
<?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>
+59 −67
Original line number Diff line number Diff line
@@ -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;
@@ -62,18 +60,19 @@ 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) {
@@ -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
@@ -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,14 +208,25 @@ public class WorkSoundPreferenceController extends PreferenceController implemen
                    return true;
                }
            });

        }
        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) {
            enableWorkSyncSettings();
@@ -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() {
@@ -274,28 +278,17 @@ public class WorkSoundPreferenceController extends PreferenceController implemen
                updateRingtoneName(managedProfileContext, RingtoneManager.TYPE_ALARM));
    }

    private void maybeRemoveWorkPreferences() {
        if (mWorkPreferenceCategory == null) {
            return;
        }
        mParent.getPreferenceScreen().removePreference(mWorkPreferenceCategory);
        mWorkPreferenceCategory = null;
        mWorkPhoneRingtonePreference = null;
        mWorkNotificationRingtonePreference = null;
        mWorkAlarmRingtonePreference = null;
    }

    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();
        }
    }

@@ -329,10 +322,9 @@ 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)
                    .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();
        }
+55 −53
Original line number Diff line number Diff line
@@ -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.
        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);
@@ -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);
        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));
    }
}