Merge "Volume policy updates."

This commit is contained in:
John Spurlock
2015-03-13 00:59:33 +00:00
committed by Android (Google) Code Review
10 changed files with 179 additions and 33 deletions

View File

@@ -3216,6 +3216,18 @@ public class AudioManager {
}
}
/**
* Only useful for volume controllers.
* @hide
*/
public void setVolumePolicy(VolumePolicy policy) {
try {
getService().setVolumePolicy(policy);
} catch (RemoteException e) {
Log.w(TAG, "Error calling setVolumePolicy", e);
}
}
/**
* Set Hdmi Cec system audio mode.
*

View File

@@ -46,10 +46,10 @@ public abstract class AudioManagerInternal {
public interface RingerModeDelegate {
/** Called when external ringer mode is evaluated, returns the new internal ringer mode */
int onSetRingerModeExternal(int ringerModeOld, int ringerModeNew, String caller,
int ringerModeInternal);
int ringerModeInternal, VolumePolicy policy);
/** Called when internal ringer mode is evaluated, returns the new external ringer mode */
int onSetRingerModeInternal(int ringerModeOld, int ringerModeNew, String caller,
int ringerModeExternal);
int ringerModeExternal, VolumePolicy policy);
}
}

View File

@@ -29,6 +29,7 @@ import android.media.IRemoteVolumeObserver;
import android.media.IRingtonePlayer;
import android.media.IVolumeController;
import android.media.Rating;
import android.media.VolumePolicy;
import android.media.audiopolicy.AudioPolicyConfig;
import android.media.audiopolicy.IAudioPolicyCallback;
import android.net.Uri;
@@ -204,9 +205,12 @@ interface IAudioService {
boolean isHdmiSystemAudioSupported();
String registerAudioPolicy(in AudioPolicyConfig policyConfig,
in IAudioPolicyCallback pcb, boolean hasFocusListener);
String registerAudioPolicy(in AudioPolicyConfig policyConfig,
in IAudioPolicyCallback pcb, boolean hasFocusListener);
oneway void unregisterAudioPolicyAsync(in IAudioPolicyCallback pcb);
int setFocusPropertiesForPolicy(int duckingBehavior, in IAudioPolicyCallback pcb);
int setFocusPropertiesForPolicy(int duckingBehavior, in IAudioPolicyCallback pcb);
void setVolumePolicy(in VolumePolicy policy);
}

View File

@@ -0,0 +1,19 @@
/*
* Copyright (C) 2015 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 android.media;
parcelable VolumePolicy;

View File

@@ -0,0 +1,68 @@
/*
* Copyright (C) 2015 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 android.media;
import android.os.Parcel;
import android.os.Parcelable;
/** @hide */
public final class VolumePolicy implements Parcelable {
public static final VolumePolicy DEFAULT = new VolumePolicy(false, false, true);
public final boolean volumeDownToEnterSilent;
public final boolean volumeUpToExitSilent;
public final boolean doNotDisturbWhenSilent;
public VolumePolicy(boolean volumeDownToEnterSilent, boolean volumeUpToExitSilent,
boolean doNotDisturbWhenSilent) {
this.volumeDownToEnterSilent = volumeDownToEnterSilent;
this.volumeUpToExitSilent = volumeUpToExitSilent;
this.doNotDisturbWhenSilent = doNotDisturbWhenSilent;
}
@Override
public String toString() {
return "VolumePolicy[volumeDownToEnterSilent=" + volumeDownToEnterSilent
+ ",volumeUpToExitSilent=" + volumeUpToExitSilent
+ ",doNotDisturbWhenSilent=" + doNotDisturbWhenSilent + "]";
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(volumeDownToEnterSilent ? 1 : 0);
dest.writeInt(volumeUpToExitSilent ? 1 : 0);
dest.writeInt(doNotDisturbWhenSilent ? 1 : 0);
}
public static final Parcelable.Creator<VolumePolicy> CREATOR
= new Parcelable.Creator<VolumePolicy>() {
@Override
public VolumePolicy createFromParcel(Parcel p) {
return new VolumePolicy(p.readInt() != 0, p.readInt() != 0, p.readInt() != 0);
}
@Override
public VolumePolicy[] newArray(int size) {
return new VolumePolicy[size];
}
};
}

View File

@@ -0,0 +1,27 @@
<!--
Copyright (C) 2015 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.
-->
<inset xmlns:android="http://schemas.android.com/apk/res/android"
android:insetLeft="3dp"
android:insetRight="3dp">
<vector android:width="18dp"
android:height="18dp"
android:viewportWidth="48.0"
android:viewportHeight="48.0">
<path
android:fillColor="#FFFFFFFF"
android:pathData="M23.000000,44.000000c2.200000,0.000000 4.000000,-1.800000 4.000000,-4.000000l-8.000000,0.000000C19.000000,42.200001 20.799999,44.000000 23.000000,44.000000zM36.000000,21.000000c0.000000,-6.100000 -4.300000,-11.300000 -10.000000,-12.600000L26.000000,7.000000c0.000000,-1.700000 -1.300000,-3.000000 -3.000000,-3.000000c-1.700000,0.000000 -3.000000,1.300000 -3.000000,3.000000l0.000000,1.400000c-1.000000,0.200000 -2.000000,0.600000 -2.900000,1.100000L36.000000,28.400000L36.000000,21.000000zM35.500000,38.000000l4.000000,4.000000l2.500000,-2.500000L8.500000,6.000000L6.000000,8.500000l5.800000,5.800000C10.700000,16.299999 10.000000,18.600000 10.000000,21.000000l0.000000,11.000000l-4.000000,4.000000l0.000000,2.000000L35.500000,38.000000z"/>
</vector>
</inset>

View File

@@ -213,7 +213,12 @@ public class PhoneStatusBarPolicy {
zenDescription = mContext.getString(R.string.zen_important_interruptions);
}
if (mZen != Global.ZEN_MODE_NO_INTERRUPTIONS &&
if (DndTile.isVisible(mContext)
&& audioManager.getRingerModeInternal() == AudioManager.RINGER_MODE_SILENT) {
volumeVisible = true;
volumeIconId = R.drawable.stat_sys_ringer_silent;
volumeDescription = mContext.getString(R.string.accessibility_ringer_silent);
} else if (mZen != Global.ZEN_MODE_NO_INTERRUPTIONS &&
audioManager.getRingerModeInternal() == AudioManager.RINGER_MODE_VIBRATE) {
volumeVisible = true;
volumeIconId = R.drawable.stat_sys_ringer_vibrate;

View File

@@ -31,6 +31,7 @@ import android.content.res.Configuration;
import android.media.AudioManager;
import android.media.IRemoteVolumeController;
import android.media.IVolumeController;
import android.media.VolumePolicy;
import android.media.session.ISessionController;
import android.media.session.MediaController;
import android.media.session.MediaSessionManager;
@@ -114,6 +115,7 @@ public class VolumeUI extends SystemUI {
if (register) {
if (LOGD) Log.d(TAG, "Registering default volume controller");
mAudioManager.setVolumeController(mVolumeController);
mAudioManager.setVolumePolicy(VolumePolicy.DEFAULT);
mMediaSessionManager.setRemoteVolumeController(mRemoteVolumeController);
DndTile.setVisible(mContext, false);
} else {

View File

@@ -62,6 +62,7 @@ import android.media.IRingtonePlayer;
import android.media.IVolumeController;
import android.media.MediaPlayer;
import android.media.SoundPool;
import android.media.VolumePolicy;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnErrorListener;
import android.media.audiopolicy.AudioPolicy;
@@ -145,12 +146,6 @@ public class AudioService extends IAudioService.Stub {
/** debug calls to devices APIs */
protected static final boolean DEBUG_DEVICES = Log.isLoggable(TAG + ".DEVICES", Log.DEBUG);
/** Allow volume changes to set ringer mode to silent? */
private static final boolean VOLUME_SETS_RINGER_MODE_SILENT = false;
/** In silent mode, are volume adjustments (raises) prevented? */
private static final boolean PREVENT_VOLUME_ADJUSTMENT_IF_SILENT = true;
/** How long to delay before persisting a change in volume/ringer mode. */
private static final int PERSIST_DELAY = 500;
@@ -534,6 +529,7 @@ public class AudioService extends IAudioService.Stub {
private static Long mLastDeviceConnectMsgTime = new Long(0);
private AudioManagerInternal.RingerModeDelegate mRingerModeDelegate;
private VolumePolicy mVolumePolicy = VolumePolicy.DEFAULT;
// Intent "extra" data keys.
public static final String CONNECT_INTENT_KEY_PORT_NAME = "portName";
@@ -1133,8 +1129,10 @@ public class AudioService extends IAudioService.Stub {
// unmute immediately for volume up
streamState.mute(false);
} else if (direction == AudioManager.ADJUST_LOWER) {
sendMsg(mAudioHandler, MSG_UNMUTE_STREAM, SENDMSG_QUEUE,
streamTypeAlias, flags, null, UNMUTE_STREAM_DELAY);
if (mPlatformType == AudioSystem.PLATFORM_TELEVISION) {
sendMsg(mAudioHandler, MSG_UNMUTE_STREAM, SENDMSG_QUEUE,
streamTypeAlias, flags, null, UNMUTE_STREAM_DELAY);
}
}
}
sendMsg(mAudioHandler,
@@ -1234,7 +1232,7 @@ public class AudioService extends IAudioService.Stub {
int newRingerMode;
if (index == 0) {
newRingerMode = mHasVibrator ? AudioManager.RINGER_MODE_VIBRATE
: VOLUME_SETS_RINGER_MODE_SILENT ? AudioManager.RINGER_MODE_SILENT
: mVolumePolicy.volumeDownToEnterSilent ? AudioManager.RINGER_MODE_SILENT
: AudioManager.RINGER_MODE_NORMAL;
} else {
newRingerMode = AudioManager.RINGER_MODE_NORMAL;
@@ -1730,7 +1728,7 @@ public class AudioService extends IAudioService.Stub {
setRingerModeExt(ringerMode);
if (mRingerModeDelegate != null) {
ringerMode = mRingerModeDelegate.onSetRingerModeExternal(ringerModeExternal,
ringerMode, caller, ringerModeInternal);
ringerMode, caller, ringerModeInternal, mVolumePolicy);
}
if (ringerMode != ringerModeInternal) {
setRingerModeInt(ringerMode, true /*persist*/);
@@ -1741,7 +1739,7 @@ public class AudioService extends IAudioService.Stub {
}
if (mRingerModeDelegate != null) {
ringerMode = mRingerModeDelegate.onSetRingerModeInternal(ringerModeInternal,
ringerMode, caller, ringerModeExternal);
ringerMode, caller, ringerModeExternal, mVolumePolicy);
}
setRingerModeExt(ringerMode);
}
@@ -1785,12 +1783,12 @@ public class AudioService extends IAudioService.Stub {
if ((isPlatformVoice() || mHasVibrator) &&
mStreamVolumeAlias[streamType] == AudioSystem.STREAM_RING) {
synchronized (VolumeStreamState.class) {
SparseIntArray indexMap = mStreamStates[streamType].mIndexMap;
for (int i = 0; i < indexMap.size(); i++) {
int device = indexMap.keyAt(i);
int value = indexMap.valueAt(i);
final VolumeStreamState vss = mStreamStates[streamType];
for (int i = 0; i < vss.mIndexMap.size(); i++) {
int device = vss.mIndexMap.keyAt(i);
int value = vss.mIndexMap.valueAt(i);
if (value == 0) {
indexMap.put(device, 10);
vss.setIndex(10, device, TAG);
}
}
// Persist volume for stream ring when it is changed here
@@ -2933,7 +2931,8 @@ public class AudioService extends IAudioService.Stub {
* adjusting volume. If so, this will set the proper ringer mode and volume
* indices on the stream states.
*/
private int checkForRingerModeChange(int oldIndex, int direction, int step, boolean isMuted) {
private int checkForRingerModeChange(int oldIndex, int direction, int step, boolean isMuted) {
final boolean isTv = mPlatformType == AudioSystem.PLATFORM_TELEVISION;
int result = FLAG_ADJUST_VOLUME;
int ringerMode = getRingerModeInternal();
@@ -2952,13 +2951,13 @@ public class AudioService extends IAudioService.Stub {
} else {
// (oldIndex < step) is equivalent to (old UI index == 0)
if ((oldIndex < step)
&& VOLUME_SETS_RINGER_MODE_SILENT
&& mVolumePolicy.volumeDownToEnterSilent
&& mPrevVolDirection != AudioManager.ADJUST_LOWER) {
ringerMode = RINGER_MODE_SILENT;
}
}
} else if (direction == AudioManager.ADJUST_TOGGLE_MUTE
|| direction == AudioManager.ADJUST_MUTE) {
} else if (isTv && (direction == AudioManager.ADJUST_TOGGLE_MUTE
|| direction == AudioManager.ADJUST_MUTE)) {
if (mHasVibrator) {
ringerMode = RINGER_MODE_VIBRATE;
} else {
@@ -2976,10 +2975,10 @@ public class AudioService extends IAudioService.Stub {
}
if ((direction == AudioManager.ADJUST_LOWER)) {
// This is the case we were muted with the volume turned up
if (oldIndex >= 2 * step && isMuted) {
if (isTv && oldIndex >= 2 * step && isMuted) {
ringerMode = RINGER_MODE_NORMAL;
} else if (mPrevVolDirection != AudioManager.ADJUST_LOWER) {
if (VOLUME_SETS_RINGER_MODE_SILENT) {
if (mVolumePolicy.volumeDownToEnterSilent) {
ringerMode = RINGER_MODE_SILENT;
} else {
result |= AudioManager.FLAG_SHOW_VIBRATE_HINT;
@@ -2993,13 +2992,13 @@ public class AudioService extends IAudioService.Stub {
result &= ~FLAG_ADJUST_VOLUME;
break;
case RINGER_MODE_SILENT:
if (direction == AudioManager.ADJUST_LOWER && oldIndex >= 2 * step && isMuted) {
if (isTv && direction == AudioManager.ADJUST_LOWER && oldIndex >= 2 * step && isMuted) {
// This is the case we were muted with the volume turned up
ringerMode = RINGER_MODE_NORMAL;
} else if (direction == AudioManager.ADJUST_RAISE
|| direction == AudioManager.ADJUST_TOGGLE_MUTE
|| direction == AudioManager.ADJUST_UNMUTE) {
if (PREVENT_VOLUME_ADJUSTMENT_IF_SILENT) {
if (!mVolumePolicy.volumeUpToExitSilent) {
result |= AudioManager.FLAG_SHOW_SILENT_HINT;
} else {
if (mHasVibrator && direction == AudioManager.ADJUST_RAISE) {
@@ -5418,6 +5417,7 @@ public class AudioService extends IAudioService.Stub {
pw.print(" mCameraSoundForced="); pw.println(mCameraSoundForced);
pw.print(" mHasVibrator="); pw.println(mHasVibrator);
pw.print(" mControllerService="); pw.println(mControllerService);
pw.print(" mVolumePolicy="); pw.println(mVolumePolicy);
dumpAudioPolicies(pw);
}
@@ -5493,6 +5493,14 @@ public class AudioService extends IAudioService.Stub {
if (DEBUG_VOL) Log.d(TAG, "Volume controller visible: " + visible);
}
@Override
public void setVolumePolicy(VolumePolicy policy) {
enforceVolumeController("set volume policy");
if (policy != null) {
mVolumePolicy = policy;
}
}
public static class VolumeController {
private static final String TAG = "VolumeController";

View File

@@ -31,6 +31,7 @@ import android.database.ContentObserver;
import android.media.AudioAttributes;
import android.media.AudioManager;
import android.media.AudioManagerInternal;
import android.media.VolumePolicy;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
@@ -334,7 +335,7 @@ public class ZenModeHelper implements AudioManagerInternal.RingerModeDelegate {
@Override // RingerModeDelegate
public int onSetRingerModeInternal(int ringerModeOld, int ringerModeNew, String caller,
int ringerModeExternal) {
int ringerModeExternal, VolumePolicy policy) {
final boolean isChange = ringerModeOld != ringerModeNew;
int ringerModeExternalOut = ringerModeNew;
@@ -342,7 +343,7 @@ public class ZenModeHelper implements AudioManagerInternal.RingerModeDelegate {
int newZen = -1;
switch (ringerModeNew) {
case AudioManager.RINGER_MODE_SILENT:
if (isChange) {
if (isChange && policy.doNotDisturbWhenSilent) {
if (mZenMode != Global.ZEN_MODE_NO_INTERRUPTIONS) {
newZen = Global.ZEN_MODE_NO_INTERRUPTIONS;
}
@@ -371,7 +372,7 @@ public class ZenModeHelper implements AudioManagerInternal.RingerModeDelegate {
@Override // RingerModeDelegate
public int onSetRingerModeExternal(int ringerModeOld, int ringerModeNew, String caller,
int ringerModeInternal) {
int ringerModeInternal, VolumePolicy policy) {
int ringerModeInternalOut = ringerModeNew;
final boolean isChange = ringerModeOld != ringerModeNew;
final boolean isVibrate = ringerModeInternal == AudioManager.RINGER_MODE_VIBRATE;