From a89d02598fdf6c1d03dbbf0dcb0bf8c045796fe0 Mon Sep 17 00:00:00 2001 From: Ting Yu Date: Thu, 18 Oct 2018 16:56:22 +0800 Subject: [PATCH] Settings: Phone ringtone setting for Multi SIM device [2/3] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Support displaying phone ringtone setting for each slot as follows: "Phone ringtone - SIM 1" "Phone ringtone - SIM 2" The purpose is to distinguish incoming call from each slot by ringtone. Depends-On: I9c6ccff938122332d222853d469ad9a623c7d193 Bug: 118735436 Test: Manual Change-Id: I06c59016e9b6da51ed8a4678a66674fc48c20e40 Signed-off-by: Hưng Phan Signed-off-by: Pranav Vashi --- res/values/evolution_strings.xml | 3 + res/values/strings.xml | 6 ++ res/xml/sound_settings.xml | 10 ++ .../settings/DefaultRingtonePreference.java | 6 +- .../android/settings/RingtonePreference.java | 25 ++++- .../PhoneRingtone2PreferenceController.java | 62 ++++++++++++ .../PhoneRingtonePreferenceController.java | 21 ++++ .../RingtonePreferenceControllerBase.java | 5 +- .../settings/notification/SoundSettings.java | 1 + ...honeRingtone2PreferenceControllerTest.java | 98 +++++++++++++++++++ ...PhoneRingtonePreferenceControllerTest.java | 19 ++++ .../settings/ui/SoundSettingsTest.java | 41 ++++++-- 12 files changed, 285 insertions(+), 12 deletions(-) create mode 100644 src/com/android/settings/notification/PhoneRingtone2PreferenceController.java create mode 100644 tests/robotests/src/com/android/settings/notification/PhoneRingtone2PreferenceControllerTest.java diff --git a/res/values/evolution_strings.xml b/res/values/evolution_strings.xml index b71608f4036..7e4a179b8f9 100644 --- a/res/values/evolution_strings.xml +++ b/res/values/evolution_strings.xml @@ -240,4 +240,7 @@ Vibrate on connect Vibrate on call waiting Vibrate on disconnect + + + SIM %1$d diff --git a/res/values/strings.xml b/res/values/strings.xml index e60455a52c4..0b54f9f0b23 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -8417,6 +8417,12 @@ Data usage charges may apply. Phone ringtone + + Phone ringtone - SIM 1 + + + Phone ringtone - SIM 2 + Default notification sound diff --git a/res/xml/sound_settings.xml b/res/xml/sound_settings.xml index dcd005b6c4f..85a703f1e4f 100644 --- a/res/xml/sound_settings.xml +++ b/res/xml/sound_settings.xml @@ -116,6 +116,16 @@ android:order="-120" settings:keywords="@string/sound_settings"/> + + + diff --git a/src/com/android/settings/DefaultRingtonePreference.java b/src/com/android/settings/DefaultRingtonePreference.java index 4c654887227..e6d5ced14b8 100644 --- a/src/com/android/settings/DefaultRingtonePreference.java +++ b/src/com/android/settings/DefaultRingtonePreference.java @@ -62,12 +62,14 @@ public class DefaultRingtonePreference extends RingtonePreference { @VisibleForTesting void setActualDefaultRingtoneUri(Uri ringtoneUri) { - RingtoneManager.setActualDefaultRingtoneUri(mUserContext, getRingtoneType(), ringtoneUri); + RingtoneManager.setActualDefaultRingtoneUriBySlot(mUserContext, getRingtoneType(), + ringtoneUri, getSlotId()); } @Override protected Uri onRestoreRingtone() { - return RingtoneManager.getActualDefaultRingtoneUri(mUserContext, getRingtoneType()); + return RingtoneManager.getActualDefaultRingtoneUriBySlot(mUserContext, getRingtoneType(), + getSlotId()); } } diff --git a/src/com/android/settings/RingtonePreference.java b/src/com/android/settings/RingtonePreference.java index e35f24da9c5..852d893897d 100644 --- a/src/com/android/settings/RingtonePreference.java +++ b/src/com/android/settings/RingtonePreference.java @@ -40,6 +40,7 @@ import androidx.preference.PreferenceManager; *

* If the user chooses the "Default" item, the saved string will be one of * {@link System#DEFAULT_RINGTONE_URI}, + * {@link System#DEFAULT_RINGTONE2_URI}, * {@link System#DEFAULT_NOTIFICATION_URI}, or * {@link System#DEFAULT_ALARM_ALERT_URI}. If the user chooses the "Silent" * item, the saved string will be an empty string. @@ -56,6 +57,9 @@ public class RingtonePreference extends Preference { private static final String TAG = "RingtonePreference"; private static final String GOOGLE_SP_PKG_NAME = "com.google.android.soundpicker"; + // Default is slot0 + private int mSlotId = 0; + private int mRingtoneType; private boolean mShowDefault; private boolean mShowSilent; @@ -97,6 +101,25 @@ public class RingtonePreference extends Preference { return mUserId; } + /** + * Sets the slot id that this preference belongs to. + * + * @param slotId The slot id that this preference belongs to. + */ + public void setSlotId(int slotId) { + mSlotId = slotId; + } + + /** + * Returns the slot id that this preference belongs to. + * + * @return The slot id that this preference belongs to. + * @see #setSlotId(int) + */ + public int getSlotId() { + return mSlotId; + } + /** * Returns the sound type(s) that are shown in the picker. * @@ -175,7 +198,7 @@ public class RingtonePreference extends Preference { ringtonePickerIntent.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_DEFAULT, mShowDefault); if (mShowDefault) { ringtonePickerIntent.putExtra(RingtoneManager.EXTRA_RINGTONE_DEFAULT_URI, - RingtoneManager.getDefaultUri(getRingtoneType())); + RingtoneManager.getDefaultUriBySlot(getRingtoneType(), getSlotId())); } ringtonePickerIntent.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_SILENT, mShowSilent); diff --git a/src/com/android/settings/notification/PhoneRingtone2PreferenceController.java b/src/com/android/settings/notification/PhoneRingtone2PreferenceController.java new file mode 100644 index 00000000000..6215936d3af --- /dev/null +++ b/src/com/android/settings/notification/PhoneRingtone2PreferenceController.java @@ -0,0 +1,62 @@ +/* + * 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.notification; + +import android.content.Context; +import android.media.RingtoneManager; +import android.telephony.TelephonyManager; + +import androidx.preference.PreferenceScreen; + +import com.android.settings.DefaultRingtonePreference; +import com.android.settings.Utils; + +public class PhoneRingtone2PreferenceController extends RingtonePreferenceControllerBase { + + private static final int SLOT_ID = 1; + private static final String KEY_PHONE_RINGTONE2 = "ringtone2"; + + public PhoneRingtone2PreferenceController(Context context) { + super(context); + } + + @Override + public void displayPreference(PreferenceScreen screen) { + super.displayPreference(screen); + + DefaultRingtonePreference ringtonePreference = + (DefaultRingtonePreference) screen.findPreference(KEY_PHONE_RINGTONE2); + ringtonePreference.setSlotId(SLOT_ID); + } + + @Override + public String getPreferenceKey() { + return KEY_PHONE_RINGTONE2; + } + + @Override + public boolean isAvailable() { + TelephonyManager telephonyManager = + (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE); + return Utils.isVoiceCapable(mContext) && telephonyManager.isMultiSimEnabled(); + } + + @Override + public int getRingtoneType() { + return RingtoneManager.TYPE_RINGTONE; + } +} diff --git a/src/com/android/settings/notification/PhoneRingtonePreferenceController.java b/src/com/android/settings/notification/PhoneRingtonePreferenceController.java index 2944b7da459..c8611b437c7 100644 --- a/src/com/android/settings/notification/PhoneRingtonePreferenceController.java +++ b/src/com/android/settings/notification/PhoneRingtonePreferenceController.java @@ -20,6 +20,13 @@ import android.content.Context; import android.media.RingtoneManager; import android.media.audio.Flags; +import android.telephony.TelephonyManager; + +import androidx.preference.PreferenceScreen; + +import com.android.settings.DefaultRingtonePreference; +import com.android.settings.R; + import com.android.settings.Utils; public class PhoneRingtonePreferenceController extends RingtonePreferenceControllerBase { @@ -30,6 +37,20 @@ public class PhoneRingtonePreferenceController extends RingtonePreferenceControl super(context); } + @Override + public void displayPreference(PreferenceScreen screen) { + super.displayPreference(screen); + + TelephonyManager telephonyManager = + (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE); + if (telephonyManager.isMultiSimEnabled()) { + // For Multi SIM device, shoud show "Phone ringtone - SIM 1" for slot1 ringtone setting. + DefaultRingtonePreference ringtonePreference = + (DefaultRingtonePreference) screen.findPreference(KEY_PHONE_RINGTONE); + ringtonePreference.setTitle(mContext.getString(R.string.ringtone1_title)); + } + } + @Override public String getPreferenceKey() { return KEY_PHONE_RINGTONE; diff --git a/src/com/android/settings/notification/RingtonePreferenceControllerBase.java b/src/com/android/settings/notification/RingtonePreferenceControllerBase.java index 29b9266335d..359ea71abdf 100644 --- a/src/com/android/settings/notification/RingtonePreferenceControllerBase.java +++ b/src/com/android/settings/notification/RingtonePreferenceControllerBase.java @@ -24,6 +24,7 @@ import android.util.Log; import androidx.preference.Preference; +import com.android.settings.RingtonePreference; import com.android.settings.core.PreferenceControllerMixin; import com.android.settingslib.core.AbstractPreferenceController; import com.android.settingslib.utils.ThreadUtils; @@ -51,8 +52,8 @@ public abstract class RingtonePreferenceControllerBase extends AbstractPreferenc } private void updateSummary(Preference preference) { - final Uri ringtoneUri = RingtoneManager.getActualDefaultRingtoneUri( - mContext, getRingtoneType()); + final Uri ringtoneUri = RingtoneManager.getActualDefaultRingtoneUriBySlot(mContext, + getRingtoneType(), ((RingtonePreference)preference).getSlotId()); final CharSequence summary; try { diff --git a/src/com/android/settings/notification/SoundSettings.java b/src/com/android/settings/notification/SoundSettings.java index a09a3539e1e..8f5a74be075 100644 --- a/src/com/android/settings/notification/SoundSettings.java +++ b/src/com/android/settings/notification/SoundSettings.java @@ -273,6 +273,7 @@ public class SoundSettings extends DashboardFragment implements OnActivityResult // === Phone & notification ringtone === controllers.add(new PhoneRingtonePreferenceController(context)); + controllers.add(new PhoneRingtone2PreferenceController(context)); controllers.add(new AlarmRingtonePreferenceController(context)); controllers.add(new NotificationRingtonePreferenceController(context)); diff --git a/tests/robotests/src/com/android/settings/notification/PhoneRingtone2PreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/PhoneRingtone2PreferenceControllerTest.java new file mode 100644 index 00000000000..87fa6a5038c --- /dev/null +++ b/tests/robotests/src/com/android/settings/notification/PhoneRingtone2PreferenceControllerTest.java @@ -0,0 +1,98 @@ +/* + * 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.notification; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import android.content.Context; +import android.media.RingtoneManager; +import android.telephony.TelephonyManager; + +import android.support.v7.preference.PreferenceScreen; + +import com.android.settings.DefaultRingtonePreference; +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; +import org.robolectric.shadows.ShadowApplication; + +@RunWith(SettingsRobolectricTestRunner.class) +public class PhoneRingtone2PreferenceControllerTest { + + @Mock + private TelephonyManager mTelephonyManager; + @Mock + private PreferenceScreen mPreferenceScreen; + @Mock + private DefaultRingtonePreference mPreference; + + private Context mContext; + private PhoneRingtone2PreferenceController mController; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + ShadowApplication shadowContext = ShadowApplication.getInstance(); + shadowContext.setSystemService(Context.TELEPHONY_SERVICE, mTelephonyManager); + mContext = RuntimeEnvironment.application; + mController = new PhoneRingtone2PreferenceController(mContext); + } + + @Test + public void displayPreference_shouldSetSlotId() { + when(mPreferenceScreen.findPreference(mController.getPreferenceKey())) + .thenReturn(mPreference); + mController.displayPreference(mPreferenceScreen); + + verify(mPreference).setSlotId(1); + } + + @Test + public void isAvailable_notVoiceCapable_shouldReturnFalse() { + when(mTelephonyManager.isVoiceCapable()).thenReturn(false); + + assertThat(mController.isAvailable()).isFalse(); + } + + @Test + public void isAvailable_notMultiSimEnabled_shouldReturnFalse() { + when(mTelephonyManager.isMultiSimEnabled()).thenReturn(false); + + assertThat(mController.isAvailable()).isFalse(); + } + + @Test + public void isAvailable_VoiceCapable_and_MultiSimEnabled_shouldReturnTrue() { + when(mTelephonyManager.isVoiceCapable()).thenReturn(true); + when(mTelephonyManager.isMultiSimEnabled()).thenReturn(true); + + assertThat(mController.isAvailable()).isTrue(); + } + + @Test + public void getRingtoneType_shouldReturnRingtone() { + assertThat(mController.getRingtoneType()).isEqualTo(RingtoneManager.TYPE_RINGTONE); + } +} diff --git a/tests/robotests/src/com/android/settings/notification/PhoneRingtonePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/PhoneRingtonePreferenceControllerTest.java index 9e49653c233..fca98e42aa0 100644 --- a/tests/robotests/src/com/android/settings/notification/PhoneRingtonePreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/notification/PhoneRingtonePreferenceControllerTest.java @@ -18,6 +18,7 @@ package com.android.settings.notification; import static com.google.common.truth.Truth.assertThat; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.content.Context; @@ -29,6 +30,10 @@ import android.platform.test.annotations.EnableFlags; import android.platform.test.flag.junit.SetFlagsRule; import android.telephony.TelephonyManager; +import androidx.preference.PreferenceScreen; + +import com.android.settings.DefaultRingtonePreference; +import com.android.settings.R; import org.junit.Before; import org.junit.Rule; @@ -43,6 +48,10 @@ public class PhoneRingtonePreferenceControllerTest { @Mock private TelephonyManager mTelephonyManager; + @Mock + private PreferenceScreen mPreferenceScreen; + @Mock + private DefaultRingtonePreference mPreference; @Mock private Context mMockContext; @@ -64,6 +73,16 @@ public class PhoneRingtonePreferenceControllerTest { mController = new PhoneRingtonePreferenceController(mMockContext); } + @Test + public void displayPreference_shouldUpdateTitle_for_MultiSimDevice() { + when(mTelephonyManager.isMultiSimEnabled()).thenReturn(true); + when(mPreferenceScreen.findPreference(mController.getPreferenceKey())) + .thenReturn(mPreference); + mController.displayPreference(mPreferenceScreen); + + verify(mPreference).setTitle(mContext.getString(R.string.ringtone1_title)); + } + @Test @DisableFlags(Flags.FLAG_ENABLE_RINGTONE_HAPTICS_CUSTOMIZATION) public void isAvailable_notVoiceCapable_shouldReturnFalse() { diff --git a/tests/uitests/src/com/android/settings/ui/SoundSettingsTest.java b/tests/uitests/src/com/android/settings/ui/SoundSettingsTest.java index f981f7fe73e..72d4a1140d7 100644 --- a/tests/uitests/src/com/android/settings/ui/SoundSettingsTest.java +++ b/tests/uitests/src/com/android/settings/ui/SoundSettingsTest.java @@ -21,6 +21,7 @@ import android.os.SystemClock; import android.provider.Settings; import android.system.helpers.SettingsHelper; import android.system.helpers.SettingsHelper.SettingsType; +import android.telephony.TelephonyManager; import android.test.InstrumentationTestCase; import androidx.test.filters.MediumTest; @@ -42,6 +43,7 @@ public class SoundSettingsTest extends InstrumentationTestCase { private UiDevice mDevice; private ContentResolver mResolver; private SettingsHelper mHelper; + private TelephonyManager mTelephonyManager; private final Map ringtoneSounds = Map.of( @@ -100,6 +102,8 @@ public class SoundSettingsTest extends InstrumentationTestCase { mDevice.setOrientationNatural(); mResolver = getInstrumentation().getContext().getContentResolver(); mHelper = new SettingsHelper(); + mTelephonyManager = (TelephonyManager) getInstrumentation().getContext() + .getSystemService(Context.TELEPHONY_SERVICE); } @Override @@ -174,26 +178,49 @@ public class SoundSettingsTest extends InstrumentationTestCase { public void testPhoneRingtoneNone() throws Exception { launchSoundSettings(); mHelper.clickSetting("Phone ringtone"); - verifyRingtone(new RingtoneSetting("None", "null"), - Settings.System.RINGTONE); + if (mTelephonyManager.isMultiSimEnabled()) { + mHelper.clickSetting("Phone ringtone - SIM 1"); + verifyRingtone(new RingtoneSetting("None", "null"), Settings.System.RINGTONE); + mHelper.clickSetting("Phone ringtone - SIM 2"); + verifyRingtone(new RingtoneSetting("None", "null"), Settings.System.RINGTONE2); + } else { + mHelper.clickSetting("Phone ringtone"); + verifyRingtone(new RingtoneSetting("None", "null"), Settings.System.RINGTONE); + } } @MediumTest @Suppress public void testPhoneRingtoneHangouts() throws Exception { launchSoundSettings(); - mHelper.clickSetting("Phone ringtone"); - verifyRingtone(new RingtoneSetting("Hangouts Call", "31"), Settings.System.RINGTONE); + if (mTelephonyManager.isMultiSimEnabled()) { + mHelper.clickSetting("Phone ringtone - SIM 1"); + verifyRingtone(new RingtoneSetting("Hangouts Call", "31"), Settings.System.RINGTONE); + mHelper.clickSetting("Phone ringtone - SIM 2"); + verifyRingtone(new RingtoneSetting("Hangouts Call", "31"), Settings.System.RINGTONE2); + } else { + mHelper.clickSetting("Phone ringtone"); + verifyRingtone(new RingtoneSetting("Hangouts Call", "31"), Settings.System.RINGTONE); + } } @MediumTest public void testPhoneRingtone() throws Exception { launchSoundSettings(); - mHelper.clickSetting("Phone ringtone"); String ringtone = ringtoneSounds.get(mDevice.getProductName()).toString(); String ringtoneSettingValue = ringtoneCodes.get(mDevice.getProductName()).toString(); - verifyRingtone(new RingtoneSetting(ringtone, ringtoneSettingValue), - Settings.System.RINGTONE); + if (mTelephonyManager.isMultiSimEnabled()) { + mHelper.clickSetting("Phone ringtone - SIM 1"); + verifyRingtone(new RingtoneSetting(ringtone, ringtoneSettingValue), + Settings.System.RINGTONE); + mHelper.clickSetting("Phone ringtone - SIM 2"); + verifyRingtone(new RingtoneSetting(ringtone, ringtoneSettingValue), + Settings.System.RINGTONE2); + } else { + mHelper.clickSetting("Phone ringtone"); + verifyRingtone(new RingtoneSetting(ringtone, ringtoneSettingValue), + Settings.System.RINGTONE); + } } @MediumTest