Merge "Add call volume in sound settings" into pi-dev am: b46389a588

am: 71b333f162

Change-Id: If69203fa5c4158f609484e6c3bbc0ca5bd6e0f58
This commit is contained in:
Ryan Lin
2018-05-11 15:44:53 -07:00
committed by android-build-merger
10 changed files with 219 additions and 19 deletions

View File

@@ -0,0 +1,28 @@
<!--
Copyright 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.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?android:attr/colorControlNormal">
<path
android:fillColor="#000000"
android:pathData="M16.01,14.48l-2.62,2.62c-2.75-1.49-5.01-3.75-6.5-6.5l2.62-2.62c0.24-0.24,0.34-0.58,0.27-0.9L9.13,3.82 c-0.09-0.47-0.5-0.8-0.98-0.8L4,3.01c-0.56,0-1.03,0.47-1,1.03c0.17,2.91,1.04,5.63,2.43,8.01c1.57,2.69,3.81,4.93,6.5,6.5 c2.38,1.39,5.1,2.26,8.01,2.43c0.56,0.03,1.03-0.44,1.03-1l0-4.15c0-0.48-0.34-0.89-0.8-0.98l-3.26-0.65 C16.58,14.14,16.24,14.24,16.01,14.48z" />
<path
android:pathData="M0,0h24v24H0V0z" />
</vector>

View File

@@ -45,8 +45,8 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical" android:orientation="vertical"
android:layout_marginTop="8dip" android:layout_marginTop="16dip"
android:layout_marginBottom="8dip"> android:layout_marginBottom="16dip">
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"

View File

@@ -78,6 +78,9 @@
<!-- Whether alarm_volume should be shown or not. --> <!-- Whether alarm_volume should be shown or not. -->
<bool name="config_show_alarm_volume">true</bool> <bool name="config_show_alarm_volume">true</bool>
<!-- Whether call_volume should be shown or not. -->
<bool name="config_show_call_volume">true</bool>
<!-- Whether notification_volume should be shown or not. --> <!-- Whether notification_volume should be shown or not. -->
<bool name="config_show_notification_volume">true</bool> <bool name="config_show_notification_volume">true</bool>

View File

@@ -38,12 +38,29 @@
android:order="-175" android:order="-175"
settings:controller="com.android.settings.sound.MediaOutputPreferenceController"/> settings:controller="com.android.settings.sound.MediaOutputPreferenceController"/>
<!-- Call volume -->
<com.android.settings.notification.VolumeSeekBarPreference
android:key="call_volume"
android:icon="@drawable/ic_local_phone_24_lib"
android:title="@string/call_volume_option_title"
android:order="-170"
settings:allowDividerAbove="true"
settings:controller="com.android.settings.notification.CallVolumePreferenceController"/>
<!-- Hands free profile output switcher -->
<ListPreference
android:key="take_call_on_output"
android:title="@string/take_call_on_title"
android:dialogTitle="@string/take_call_on_title"
android:order="-165"
settings:controller="com.android.settings.sound.HandsFreeProfileOutputPreferenceController"/>
<!-- Ring volume --> <!-- Ring volume -->
<com.android.settings.notification.VolumeSeekBarPreference <com.android.settings.notification.VolumeSeekBarPreference
android:key="ring_volume" android:key="ring_volume"
android:icon="@*android:drawable/ic_audio_ring_notif" android:icon="@*android:drawable/ic_audio_ring_notif"
android:title="@string/ring_volume_option_title" android:title="@string/ring_volume_option_title"
android:order="-170" android:order="-160"
settings:controller="com.android.settings.notification.RingVolumePreferenceController" settings:controller="com.android.settings.notification.RingVolumePreferenceController"
settings:allowDividerAbove="true"/> settings:allowDividerAbove="true"/>
@@ -51,15 +68,7 @@
<SwitchPreference <SwitchPreference
android:key="vibrate_when_ringing" android:key="vibrate_when_ringing"
android:title="@string/vibrate_when_ringing_title" android:title="@string/vibrate_when_ringing_title"
android:order="-160"/> android:order="-155"/>
<!-- Hands free profile output switcher -->
<ListPreference
android:key="take_call_on_output"
android:title="@string/take_call_on_title"
android:dialogTitle="@string/take_call_on_title"
android:order="-155"
settings:controller="com.android.settings.sound.HandsFreeProfileOutputPreferenceController"/>
<!-- Alarm volume --> <!-- Alarm volume -->
<com.android.settings.notification.VolumeSeekBarPreference <com.android.settings.notification.VolumeSeekBarPreference

View File

@@ -0,0 +1,55 @@
/*
* 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.AudioManager;
import com.android.settings.R;
public class CallVolumePreferenceController extends VolumeSeekBarPreferenceController {
private AudioManager mAudioManager;
public CallVolumePreferenceController(Context context, String key) {
super(context, key);
mAudioManager = context.getSystemService(AudioManager.class);
}
@Override
public int getAvailabilityStatus() {
return mContext.getResources().getBoolean(R.bool.config_show_call_volume)
&& !mHelper.isSingleVolume() ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
}
@Override
public int getAudioStream() {
if (mAudioManager.isBluetoothScoOn()) {
return AudioManager.STREAM_BLUETOOTH_SCO;
}
return AudioManager.STREAM_VOICE_CALL;
}
@Override
public int getMuteIcon() {
// User will not be allowed to fully mute the call volume, use original
// icon for mute icon.
return R.drawable.ic_local_phone_24_lib;
}
}

View File

@@ -153,6 +153,7 @@ public class SoundSettings extends DashboardFragment {
volumeControllers.add(use(MediaVolumePreferenceController.class)); volumeControllers.add(use(MediaVolumePreferenceController.class));
volumeControllers.add(use(RingVolumePreferenceController.class)); volumeControllers.add(use(RingVolumePreferenceController.class));
volumeControllers.add(use(NotificationVolumePreferenceController.class)); volumeControllers.add(use(NotificationVolumePreferenceController.class));
volumeControllers.add(use(CallVolumePreferenceController.class));
for (VolumeSeekBarPreferenceController controller : volumeControllers) { for (VolumeSeekBarPreferenceController controller : volumeControllers) {
controller.setCallback(mVolumeCallback); controller.setCallback(mVolumeCallback);

View File

@@ -83,7 +83,9 @@ public class VolumeSeekBarPreference extends SeekBarPreference {
public void setStream(int stream) { public void setStream(int stream) {
mStream = stream; mStream = stream;
setMax(mAudioManager.getStreamMaxVolume(mStream)); setMax(mAudioManager.getStreamMaxVolume(mStream));
setMin(mAudioManager.getStreamMinVolume(mStream)); // Use getStreamMinVolumeInt for non-public stream type
// eg: AudioManager.STREAM_BLUETOOTH_SCO
setMin(mAudioManager.getStreamMinVolumeInt(mStream));
setProgress(mAudioManager.getStreamVolume(mStream)); setProgress(mAudioManager.getStreamVolume(mStream));
} }
@@ -108,10 +110,6 @@ public class VolumeSeekBarPreference extends SeekBarPreference {
@Override @Override
public void onBindViewHolder(PreferenceViewHolder view) { public void onBindViewHolder(PreferenceViewHolder view) {
super.onBindViewHolder(view); super.onBindViewHolder(view);
if (mStream == 0) {
Log.w(TAG, "No stream found, not binding volumizer");
return;
}
mSeekBar = (SeekBar) view.findViewById(com.android.internal.R.id.seekbar); mSeekBar = (SeekBar) view.findViewById(com.android.internal.R.id.seekbar);
mIconView = (ImageView) view.findViewById(com.android.internal.R.id.icon); mIconView = (ImageView) view.findViewById(com.android.internal.R.id.icon);
mSuppressionTextView = (TextView) view.findViewById(R.id.suppression_text); mSuppressionTextView = (TextView) view.findViewById(R.id.suppression_text);

View File

@@ -0,0 +1,95 @@
/*
* 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.android.settings.core.BasePreferenceController.AVAILABLE;
import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_DEVICE;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.media.AudioManager;
import com.android.settings.R;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.testutils.shadow.ShadowAudioManager;
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.annotation.Config;
@RunWith(SettingsRobolectricTestRunner.class)
@Config(shadows = {ShadowAudioManager.class})
public class CallVolumePreferenceControllerTest {
private static final String TEST_KEY = "Test_Key";
@Mock
private AudioHelper mHelper;
private Context mContext;
private CallVolumePreferenceController mController;
private ShadowAudioManager mShadowAudioManager;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mContext = RuntimeEnvironment.application;
mController = new CallVolumePreferenceController(mContext, TEST_KEY);
mController.setAudioHelper(mHelper);
mShadowAudioManager = ShadowAudioManager.getShadow();
}
@Test
public void getAvailabilityStatus_singleVolume_shouldReturnDisable() {
when(mHelper.isSingleVolume()).thenReturn(true);
assertThat(mController.getAvailabilityStatus()).isEqualTo(UNSUPPORTED_ON_DEVICE);
}
@Test
public void getAvailabilityStatus_notSingleVolume_shouldReturnAvailable() {
when(mHelper.isSingleVolume()).thenReturn(false);
assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
}
@Test
public void getMuteIcon_shouldEqualToOriginalIcon() {
assertThat(mController.getMuteIcon()).isEqualTo(R.drawable.ic_local_phone_24_lib);
}
@Test
public void getAudioStream_onBluetoothScoOff_shouldEqualToStreamVoiceCall() {
mShadowAudioManager.setBluetoothScoOn(false);
assertThat(mController.getAudioStream()).isEqualTo(AudioManager.STREAM_VOICE_CALL);
}
@Test
public void getAudioStream_onBluetoothScoOn_shouldEqualToStreamBtSco() {
mShadowAudioManager.setBluetoothScoOn(true);
assertThat(mController.getAudioStream()).isEqualTo(AudioManager.STREAM_BLUETOOTH_SCO);
}
}

View File

@@ -50,17 +50,20 @@ public class VolumeSeekBarPreferenceTest {
} }
@Test @Test
public void setStream_shouldSetMaxAndProgress() { public void setStream_shouldSetMinMaxAndProgress() {
final int stream = 5; final int stream = 5;
final int max = 17; final int max = 17;
final int min = 1;
final int progress = 4; final int progress = 4;
when(mAudioManager.getStreamMaxVolume(stream)).thenReturn(max); when(mAudioManager.getStreamMaxVolume(stream)).thenReturn(max);
when(mAudioManager.getStreamMinVolumeInt(stream)).thenReturn(min);
when(mAudioManager.getStreamVolume(stream)).thenReturn(progress); when(mAudioManager.getStreamVolume(stream)).thenReturn(progress);
doCallRealMethod().when(mPreference).setStream(anyInt()); doCallRealMethod().when(mPreference).setStream(anyInt());
mPreference.setStream(stream); mPreference.setStream(stream);
verify(mPreference).setMax(max); verify(mPreference).setMax(max);
verify(mPreference).setMin(min);
verify(mPreference).setProgress(progress); verify(mPreference).setProgress(progress);
} }
} }

View File

@@ -42,7 +42,8 @@ import java.util.ArrayList;
public class ShadowAudioManager extends org.robolectric.shadows.ShadowAudioManager { public class ShadowAudioManager extends org.robolectric.shadows.ShadowAudioManager {
private int mRingerMode; private int mRingerMode;
private int mDeviceCodes; private int mDeviceCodes;
private boolean mMusicActiveRemotely = false; private boolean mMusicActiveRemotely;
private boolean mBluetoothScoOn;
private ArrayList<AudioDeviceCallback> mDeviceCallbacks = new ArrayList(); private ArrayList<AudioDeviceCallback> mDeviceCallbacks = new ArrayList();
@Implementation @Implementation
@@ -104,4 +105,11 @@ public class ShadowAudioManager extends org.robolectric.shadows.ShadowAudioManag
public void reset() { public void reset() {
mDeviceCallbacks.clear(); mDeviceCallbacks.clear();
} }
public void setBluetoothScoOn(boolean bluetoothScoOn) {
mBluetoothScoOn = bluetoothScoOn;
}
@Implementation
public boolean isBluetoothScoOn() { return mBluetoothScoOn; }
} }