Merge "Fix a doc typo." into jb-mr2-dev
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index a5b3c8f..6207faa 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -9485,17 +9485,26 @@
* <p>Sets the opacity of the view. This is a value from 0 to 1, where 0 means the view is
* completely transparent and 1 means the view is completely opaque.</p>
*
- * <p>If this view overrides {@link #onSetAlpha(int)} to return true, then this view is
- * responsible for applying the opacity itself. Otherwise, calling this method is
- * equivalent to calling {@link #setLayerType(int, android.graphics.Paint)} and
- * setting a hardware layer.</p>
+ * <p> Note that setting alpha to a translucent value (0 < alpha < 1) can have significant
+ * performance implications, especially for large views. It is best to use the alpha property
+ * sparingly and transiently, as in the case of fading animations.</p>
*
- * <p>Note that setting alpha to a translucent value (0 < alpha < 1) may have
- * performance implications. It is generally best to use the alpha property sparingly and
- * transiently, as in the case of fading animations.</p>
+ * <p>For a view with a frequently changing alpha, such as during a fading animation, it is
+ * strongly recommended for performance reasons to either override
+ * {@link #hasOverlappingRendering()} to return false if appropriate, or setting a
+ * {@link #setLayerType(int, android.graphics.Paint) layer type} on the view.</p>
+ *
+ * <p>If this view overrides {@link #onSetAlpha(int)} to return true, then this view is
+ * responsible for applying the opacity itself.</p>
+ *
+ * <p>Note that if the view is backed by a
+ * {@link #setLayerType(int, android.graphics.Paint) layer} and is associated with a
+ * {@link #setLayerPaint(android.graphics.Paint) layer paint}, setting an alpha value less than
+ * 1.0 will supercede the alpha of the layer paint.</p>
*
* @param alpha The opacity of the view.
*
+ * @see #hasOverlappingRendering()
* @see #setLayerType(int, android.graphics.Paint)
*
* @attr ref android.R.styleable#View_alpha
@@ -12365,13 +12374,11 @@
* </ul>
*
* <p>If this view has an alpha value set to < 1.0 by calling
- * {@link #setAlpha(float)}, the alpha value of the layer's paint is replaced by
- * this view's alpha value. Calling {@link #setAlpha(float)} is therefore
- * equivalent to setting a hardware layer on this view and providing a paint with
- * the desired alpha value.</p>
+ * {@link #setAlpha(float)}, the alpha value of the layer's paint is superceded
+ * by this view's alpha value.</p>
*
- * <p>Refer to the documentation of {@link #LAYER_TYPE_NONE disabled},
- * {@link #LAYER_TYPE_SOFTWARE software} and {@link #LAYER_TYPE_HARDWARE hardware}
+ * <p>Refer to the documentation of {@link #LAYER_TYPE_NONE},
+ * {@link #LAYER_TYPE_SOFTWARE} and {@link #LAYER_TYPE_HARDWARE}
* for more information on when and how to use layers.</p>
*
* @param layerType The type of layer to use with this view, must be one of
@@ -12441,11 +12448,8 @@
* <li>{@link android.graphics.Paint#getColorFilter() Color filter}</li>
* </ul>
*
- * <p>If this view has an alpha value set to < 1.0 by calling
- * {@link #setAlpha(float)}, the alpha value of the layer's paint is replaced by
- * this view's alpha value. Calling {@link #setAlpha(float)} is therefore
- * equivalent to setting a hardware layer on this view and providing a paint with
- * the desired alpha value.</p>
+ * <p>If this view has an alpha value set to < 1.0 by calling {@link #setAlpha(float)}, the
+ * alpha value of the layer's paint is superceded by this view's alpha value.</p>
*
* @param paint The paint used to compose the layer. This argument is optional
* and can be null. It is ignored when the layer type is
diff --git a/libs/hwui/DisplayList.cpp b/libs/hwui/DisplayList.cpp
index d985ad0..36c95f9 100644
--- a/libs/hwui/DisplayList.cpp
+++ b/libs/hwui/DisplayList.cpp
@@ -352,7 +352,9 @@
}
}
if (mAlpha < 1) {
- if (mCaching || !mHasOverlappingRendering) {
+ if (mCaching) {
+ ALOGD("%*sSetOverrideLayerAlpha %.2f", level * 2, "", mAlpha);
+ } else if (!mHasOverlappingRendering) {
ALOGD("%*sScaleAlpha %.2f", level * 2, "", mAlpha);
} else {
int flags = SkCanvas::kHasAlphaLayer_SaveFlag;
@@ -400,7 +402,9 @@
}
}
if (mAlpha < 1) {
- if (mCaching || !mHasOverlappingRendering) {
+ if (mCaching) {
+ renderer.setOverrideLayerAlpha(mAlpha);
+ } else if (!mHasOverlappingRendering) {
renderer.scaleAlpha(mAlpha);
} else {
// TODO: should be able to store the size of a DL at record time and not
@@ -513,6 +517,7 @@
DISPLAY_LIST_LOGD("%*sRestoreToCount %d", (level + 1) * 2, "", restoreTo);
handler(mRestoreToCountOp->reinit(restoreTo), PROPERTY_SAVECOUNT);
renderer.restoreToCount(restoreTo);
+ renderer.setOverrideLayerAlpha(1.0f);
}
}; // namespace uirenderer
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 4a5785c..1138998 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -114,6 +114,7 @@
mCaches(Caches::getInstance()), mExtensions(Extensions::getInstance()) {
mDrawModifiers.mShader = NULL;
mDrawModifiers.mColorFilter = NULL;
+ mDrawModifiers.mOverrideLayerAlpha = 1.0f;
mDrawModifiers.mHasShadow = false;
mDrawModifiers.mHasDrawFilter = false;
@@ -1074,7 +1075,7 @@
layer->setFilter(GL_LINEAR, true);
}
- float alpha = layer->getAlpha() / 255.0f * mSnapshot->alpha;
+ float alpha = getLayerAlpha(layer);
bool blend = layer->isBlend() || alpha < 1.0f;
drawTextureMesh(x, y, x + rect.getWidth(), y + rect.getHeight(),
layer->getTexture(), alpha, layer->getMode(), blend,
@@ -1112,7 +1113,7 @@
rects = safeRegion.getArray(&count);
}
- const float alpha = layer->getAlpha() / 255.0f * mSnapshot->alpha;
+ const float alpha = getLayerAlpha(layer);
const float texX = 1.0f / float(layer->getWidth());
const float texY = 1.0f / float(layer->getHeight());
const float height = rect.getHeight();
@@ -2237,7 +2238,7 @@
float left, float top, float right, float bottom, SkPaint* paint) {
int alpha;
SkXfermode::Mode mode;
- getAlphaAndModeDirect(paint, &alpha, &mode);
+ getAlphaAndMode(paint, &alpha, &mode);
return drawPatch(bitmap, xDivs, yDivs, colors, width, height, numColors,
left, top, right, bottom, alpha, mode);
@@ -2990,7 +2991,7 @@
if (layer->region.isRect()) {
composeLayerRect(layer, layer->regionRect);
} else if (layer->mesh) {
- const float a = layer->getAlpha() / 255.0f * mSnapshot->alpha;
+ const float a = getLayerAlpha(layer);
setupDraw();
setupDrawWithTexture();
setupDrawColor(a, a, a, a);
@@ -3446,10 +3447,24 @@
TextureVertex::setUV(v++, u2, v2);
}
-void OpenGLRenderer::getAlphaAndMode(SkPaint* paint, int* alpha, SkXfermode::Mode* mode) {
+void OpenGLRenderer::getAlphaAndMode(SkPaint* paint, int* alpha, SkXfermode::Mode* mode) const {
getAlphaAndModeDirect(paint, alpha, mode);
+ if (mDrawModifiers.mOverrideLayerAlpha < 1.0f) {
+ // if drawing a layer, ignore the paint's alpha
+ *alpha = mDrawModifiers.mOverrideLayerAlpha;
+ }
*alpha *= mSnapshot->alpha;
}
+float OpenGLRenderer::getLayerAlpha(Layer* layer) const {
+ float alpha;
+ if (mDrawModifiers.mOverrideLayerAlpha < 1.0f) {
+ alpha = mDrawModifiers.mOverrideLayerAlpha;
+ } else {
+ alpha = layer->getAlpha() / 255.0f;
+ }
+ return alpha * mSnapshot->alpha;
+}
+
}; // namespace uirenderer
}; // namespace android
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index 04a47fc..dd7a5a2 100644
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -51,6 +51,7 @@
struct DrawModifiers {
SkiaShader* mShader;
SkiaColorFilter* mColorFilter;
+ float mOverrideLayerAlpha;
// Drop shadow
bool mHasShadow;
@@ -275,6 +276,9 @@
virtual void resetPaintFilter();
virtual void setupPaintFilter(int clearBits, int setBits);
+ // If this value is set to < 1.0, it overrides alpha set on layer (see drawBitmap, drawLayer)
+ void setOverrideLayerAlpha(float alpha) { mDrawModifiers.mOverrideLayerAlpha = alpha; }
+
SkPaint* filterPaint(SkPaint* paint);
bool storeDisplayState(DeferredDisplayState& state, int stateDeferFlags);
@@ -283,7 +287,6 @@
const DrawModifiers& getDrawModifiers() { return mDrawModifiers; }
void setDrawModifiers(const DrawModifiers& drawModifiers) { mDrawModifiers = drawModifiers; }
- // TODO: what does this mean? no perspective? no rotate?
ANDROID_API bool isCurrentTransformSimple() {
return mSnapshot->transform->isSimple();
}
@@ -325,7 +328,8 @@
/**
* Gets the alpha and xfermode out of a paint object. If the paint is null
* alpha will be 255 and the xfermode will be SRC_OVER. This method does
- * not multiply the paint's alpha by the current snapshot's alpha.
+ * not multiply the paint's alpha by the current snapshot's alpha, and does
+ * not replace the alpha with the overrideLayerAlpha
*
* @param paint The paint to extract values from
* @param alpha Where to store the resulting alpha
@@ -450,13 +454,21 @@
/**
* Gets the alpha and xfermode out of a paint object. If the paint is null
- * alpha will be 255 and the xfermode will be SRC_OVER.
+ * alpha will be 255 and the xfermode will be SRC_OVER. Accounts for both
+ * snapshot alpha, and overrideLayerAlpha
*
* @param paint The paint to extract values from
* @param alpha Where to store the resulting alpha
* @param mode Where to store the resulting xfermode
*/
- inline void getAlphaAndMode(SkPaint* paint, int* alpha, SkXfermode::Mode* mode);
+ inline void getAlphaAndMode(SkPaint* paint, int* alpha, SkXfermode::Mode* mode) const;
+
+ /**
+ * Gets the alpha from a layer, accounting for snapshot alpha and overrideLayerAlpha
+ *
+ * @param layer The layer from which the alpha is extracted
+ */
+ inline float getLayerAlpha(Layer* layer) const;
/**
* Safely retrieves the mode from the specified xfermode. If the specified
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index 9ded922..e35f47b 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -169,11 +169,6 @@
private static final int MSG_RCC_NEW_PLAYBACK_STATE = 32;
- // flags for MSG_PERSIST_VOLUME indicating if current and/or last audible volume should be
- // persisted
- private static final int PERSIST_CURRENT = 0x1;
- private static final int PERSIST_LAST_AUDIBLE = 0x2;
-
private static final int BTA2DP_DOCK_TIMEOUT_MILLIS = 8000;
// Timeout for connection to bluetooth headset service
private static final int BT_HEADSET_CNCT_TIMEOUT_MS = 3000;
@@ -582,14 +577,10 @@
for (int streamType = 0; streamType < numStreamTypes; streamType++) {
if (streamType != mStreamVolumeAlias[streamType]) {
mStreamStates[streamType].
- setAllIndexes(mStreamStates[mStreamVolumeAlias[streamType]],
- false /*lastAudible*/);
- mStreamStates[streamType].
- setAllIndexes(mStreamStates[mStreamVolumeAlias[streamType]],
- true /*lastAudible*/);
+ setAllIndexes(mStreamStates[mStreamVolumeAlias[streamType]]);
}
// apply stream volume
- if (mStreamStates[streamType].muteCount() == 0) {
+ if (!mStreamStates[streamType].isMuted()) {
mStreamStates[streamType].applyAllVolumes();
}
}
@@ -633,10 +624,7 @@
}
mStreamVolumeAlias[AudioSystem.STREAM_DTMF] = dtmfStreamAlias;
if (updateVolumes) {
- mStreamStates[AudioSystem.STREAM_DTMF].setAllIndexes(mStreamStates[dtmfStreamAlias],
- false /*lastAudible*/);
- mStreamStates[AudioSystem.STREAM_DTMF].setAllIndexes(mStreamStates[dtmfStreamAlias],
- true /*lastAudible*/);
+ mStreamStates[AudioSystem.STREAM_DTMF].setAllIndexes(mStreamStates[dtmfStreamAlias]);
sendMsg(mAudioHandler,
MSG_SET_ALL_VOLUMES,
SENDMSG_QUEUE,
@@ -836,14 +824,9 @@
final int device = getDeviceForStream(streamTypeAlias);
- // get last audible index if stream is muted, current index otherwise
- int aliasIndex = streamState.getIndex(device,
- (streamState.muteCount() != 0) /* lastAudible */);
+ int aliasIndex = streamState.getIndex(device);
boolean adjustVolume = true;
-
int step;
- int index;
- int oldIndex;
// reset any pending volume command
synchronized (mSafeMediaVolumeState) {
@@ -872,64 +855,40 @@
step = rescaleIndex(10, streamType, streamTypeAlias);
}
- if ((direction == AudioManager.ADJUST_RAISE) &&
- !checkSafeMediaVolume(streamTypeAlias, aliasIndex + step, device)) {
- index = mStreamStates[streamType].getIndex(device,
- (streamState.muteCount() != 0) /* lastAudible */);
- oldIndex = index;
- mVolumePanel.postDisplaySafeVolumeWarning(flags);
- } else {
- // If either the client forces allowing ringer modes for this adjustment,
- // or the stream type is one that is affected by ringer modes
- if (((flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0) ||
- (streamTypeAlias == getMasterStreamType())) {
- int ringerMode = getRingerMode();
- // do not vibrate if already in vibrate mode
- if (ringerMode == AudioManager.RINGER_MODE_VIBRATE) {
- flags &= ~AudioManager.FLAG_VIBRATE;
- }
- // Check if the ringer mode changes with this volume adjustment. If
- // it does, it will handle adjusting the volume, so we won't below
- adjustVolume = checkForRingerModeChange(aliasIndex, direction, step);
- if ((streamTypeAlias == getMasterStreamType()) &&
- (mRingerMode == AudioManager.RINGER_MODE_SILENT)) {
- streamState.setLastAudibleIndex(0, device);
- }
+ // If either the client forces allowing ringer modes for this adjustment,
+ // or the stream type is one that is affected by ringer modes
+ if (((flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0) ||
+ (streamTypeAlias == getMasterStreamType())) {
+ int ringerMode = getRingerMode();
+ // do not vibrate if already in vibrate mode
+ if (ringerMode == AudioManager.RINGER_MODE_VIBRATE) {
+ flags &= ~AudioManager.FLAG_VIBRATE;
}
+ // Check if the ringer mode changes with this volume adjustment. If
+ // it does, it will handle adjusting the volume, so we won't below
+ adjustVolume = checkForRingerModeChange(aliasIndex, direction, step);
+ }
- // If stream is muted, adjust last audible index only
- oldIndex = mStreamStates[streamType].getIndex(device,
- (mStreamStates[streamType].muteCount() != 0) /* lastAudible */);
+ int oldIndex = mStreamStates[streamType].getIndex(device);
- if (streamState.muteCount() != 0) {
- if (adjustVolume) {
- // Post a persist volume msg
- // no need to persist volume on all streams sharing the same alias
- streamState.adjustLastAudibleIndex(direction * step, device);
- sendMsg(mAudioHandler,
- MSG_PERSIST_VOLUME,
- SENDMSG_QUEUE,
- PERSIST_LAST_AUDIBLE,
- device,
- streamState,
- PERSIST_DELAY);
- }
- index = mStreamStates[streamType].getIndex(device, true /* lastAudible */);
- } else {
- if (adjustVolume && streamState.adjustIndex(direction * step, device)) {
- // Post message to set system volume (it in turn will post a message
- // to persist). Do not change volume if stream is muted.
- sendMsg(mAudioHandler,
- MSG_SET_DEVICE_VOLUME,
- SENDMSG_QUEUE,
- device,
- 0,
- streamState,
- 0);
- }
- index = mStreamStates[streamType].getIndex(device, false /* lastAudible */);
+ if (adjustVolume && (direction != AudioManager.ADJUST_SAME)) {
+ if ((direction == AudioManager.ADJUST_RAISE) &&
+ !checkSafeMediaVolume(streamTypeAlias, aliasIndex + step, device)) {
+ Log.e(TAG, "adjustStreamVolume() safe volume index = "+oldIndex);
+ mVolumePanel.postDisplaySafeVolumeWarning(flags);
+ } else if (streamState.adjustIndex(direction * step, device)) {
+ // Post message to set system volume (it in turn will post a message
+ // to persist). Do not change volume if stream is muted.
+ sendMsg(mAudioHandler,
+ MSG_SET_DEVICE_VOLUME,
+ SENDMSG_QUEUE,
+ device,
+ 0,
+ streamState,
+ 0);
}
}
+ int index = mStreamStates[streamType].getIndex(device);
sendVolumeUpdate(streamType, oldIndex, index, flags);
}
@@ -969,6 +928,7 @@
};
private void onSetStreamVolume(int streamType, int index, int flags, int device) {
+ setStreamVolumeInt(mStreamVolumeAlias[streamType], index, device, false);
// setting volume on master stream type also controls silent mode
if (((flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0) ||
(mStreamVolumeAlias[streamType] == getMasterStreamType())) {
@@ -976,18 +936,11 @@
if (index == 0) {
newRingerMode = mHasVibrator ? AudioManager.RINGER_MODE_VIBRATE
: AudioManager.RINGER_MODE_SILENT;
- setStreamVolumeInt(mStreamVolumeAlias[streamType],
- index,
- device,
- false,
- true);
} else {
newRingerMode = AudioManager.RINGER_MODE_NORMAL;
}
setRingerMode(newRingerMode);
}
-
- setStreamVolumeInt(mStreamVolumeAlias[streamType], index, device, false, true);
}
/** @see AudioManager#setStreamVolume(int, int, int) */
@@ -1006,9 +959,7 @@
// reset any pending volume command
mPendingVolumeCommand = null;
- // get last audible index if stream is muted, current index otherwise
- oldIndex = streamState.getIndex(device,
- (streamState.muteCount() != 0) /* lastAudible */);
+ oldIndex = streamState.getIndex(device);
index = rescaleIndex(index * 10, streamType, mStreamVolumeAlias[streamType]);
@@ -1034,9 +985,7 @@
streamType, index, flags, device);
} else {
onSetStreamVolume(streamType, index, flags, device);
- // get last audible index if stream is muted, current index otherwise
- index = mStreamStates[streamType].getIndex(device,
- (mStreamStates[streamType].muteCount() != 0) /* lastAudible */);
+ index = mStreamStates[streamType].getIndex(device);
}
}
sendVolumeUpdate(streamType, oldIndex, index, flags);
@@ -1198,41 +1147,23 @@
* @param device the device whose volume must be changed
* @param force If true, set the volume even if the desired volume is same
* as the current volume.
- * @param lastAudible If true, stores new index as last audible one
*/
private void setStreamVolumeInt(int streamType,
int index,
int device,
- boolean force,
- boolean lastAudible) {
+ boolean force) {
VolumeStreamState streamState = mStreamStates[streamType];
- // If stream is muted, set last audible index only
- if (streamState.muteCount() != 0) {
- // Do not allow last audible index to be 0
- if (index != 0) {
- streamState.setLastAudibleIndex(index, device);
- // Post a persist volume msg
- sendMsg(mAudioHandler,
- MSG_PERSIST_VOLUME,
- SENDMSG_QUEUE,
- PERSIST_LAST_AUDIBLE,
- device,
- streamState,
- PERSIST_DELAY);
- }
- } else {
- if (streamState.setIndex(index, device, lastAudible) || force) {
- // Post message to set system volume (it in turn will post a message
- // to persist).
- sendMsg(mAudioHandler,
- MSG_SET_DEVICE_VOLUME,
- SENDMSG_QUEUE,
- device,
- 0,
- streamState,
- 0);
- }
+ if (streamState.setIndex(index, device) || force) {
+ // Post message to set system volume (it in turn will post a message
+ // to persist).
+ sendMsg(mAudioHandler,
+ MSG_SET_DEVICE_VOLUME,
+ SENDMSG_QUEUE,
+ device,
+ 0,
+ streamState,
+ 0);
}
}
@@ -1244,7 +1175,6 @@
for (int stream = 0; stream < mStreamStates.length; stream++) {
if (!isStreamAffectedByMute(stream) || stream == streamType) continue;
- // Bring back last audible volume
mStreamStates[stream].mute(cb, state);
}
}
@@ -1262,7 +1192,7 @@
/** get stream mute state. */
public boolean isStreamMute(int streamType) {
- return (mStreamStates[streamType].muteCount() != 0);
+ return mStreamStates[streamType].isMuted();
}
/** @see AudioManager#setMasterMute(boolean, int) */
@@ -1289,8 +1219,12 @@
public int getStreamVolume(int streamType) {
ensureValidStreamType(streamType);
int device = getDeviceForStream(streamType);
- int index = mStreamStates[streamType].getIndex(device, false /* lastAudible */);
+ int index = mStreamStates[streamType].getIndex(device);
+ // by convention getStreamVolume() returns 0 when a stream is muted.
+ if (mStreamStates[streamType].isMuted()) {
+ index = 0;
+ }
if (index != 0 && (mStreamVolumeAlias[streamType] == AudioSystem.STREAM_MUSIC) &&
(device & mFixedVolumeDevices) != 0) {
index = mStreamStates[streamType].getMaxIndex();
@@ -1347,7 +1281,7 @@
public int getLastAudibleStreamVolume(int streamType) {
ensureValidStreamType(streamType);
int device = getDeviceForStream(streamType);
- return (mStreamStates[streamType].getIndex(device, true /* lastAudible */) + 5) / 10;
+ return (mStreamStates[streamType].getIndex(device) + 5) / 10;
}
/** Get last audible master volume before it was muted. */
@@ -1412,7 +1346,7 @@
if (mVoiceCapable &&
mStreamVolumeAlias[streamType] == AudioSystem.STREAM_RING) {
synchronized (mStreamStates[streamType]) {
- Set set = mStreamStates[streamType].mLastAudibleIndex.entrySet();
+ Set set = mStreamStates[streamType].mIndex.entrySet();
Iterator i = set.iterator();
while (i.hasNext()) {
Map.Entry entry = (Map.Entry)i.next();
@@ -1661,8 +1595,8 @@
streamType = AudioManager.STREAM_MUSIC;
}
int device = getDeviceForStream(streamType);
- int index = mStreamStates[mStreamVolumeAlias[streamType]].getIndex(device, false);
- setStreamVolumeInt(mStreamVolumeAlias[streamType], index, device, true, false);
+ int index = mStreamStates[mStreamVolumeAlias[streamType]].getIndex(device);
+ setStreamVolumeInt(mStreamVolumeAlias[streamType], index, device, true);
updateStreamVolumeAlias(true /*updateVolumes*/);
}
@@ -1896,7 +1830,7 @@
streamState.readSettings();
// unmute stream that was muted but is not affect by mute anymore
- if (streamState.muteCount() != 0 && ((!isStreamAffectedByMute(streamType) &&
+ if (streamState.isMuted() && ((!isStreamAffectedByMute(streamType) &&
!isStreamMutedByRingerMode(streamType)) || mUseFixedVolume)) {
int size = streamState.mDeathHandlers.size();
for (int i = 0; i < size; i++) {
@@ -2396,8 +2330,7 @@
0,
null,
MUSIC_ACTIVE_POLL_PERIOD_MS);
- int index = mStreamStates[AudioSystem.STREAM_MUSIC].getIndex(device,
- false /*lastAudible*/);
+ int index = mStreamStates[AudioSystem.STREAM_MUSIC].getIndex(device);
if (AudioSystem.isStreamActive(AudioSystem.STREAM_MUSIC, 0) &&
(index > mSafeMediaVolumeIndex)) {
// Approximate cumulative active music time
@@ -2742,18 +2675,14 @@
private final int mStreamType;
private String mVolumeIndexSettingName;
- private String mLastAudibleVolumeIndexSettingName;
private int mIndexMax;
private final ConcurrentHashMap<Integer, Integer> mIndex =
new ConcurrentHashMap<Integer, Integer>(8, 0.75f, 4);
- private final ConcurrentHashMap<Integer, Integer> mLastAudibleIndex =
- new ConcurrentHashMap<Integer, Integer>(8, 0.75f, 4);
private ArrayList<VolumeDeathHandler> mDeathHandlers; //handles mute/solo clients death
private VolumeStreamState(String settingName, int streamType) {
mVolumeIndexSettingName = settingName;
- mLastAudibleVolumeIndexSettingName = settingName + System.APPEND_FOR_LAST_AUDIBLE;
mStreamType = streamType;
mIndexMax = MAX_STREAM_VOLUME[streamType];
@@ -2766,10 +2695,8 @@
readSettings();
}
- public String getSettingNameForDevice(boolean lastAudible, int device) {
- String name = lastAudible ?
- mLastAudibleVolumeIndexSettingName :
- mVolumeIndexSettingName;
+ public String getSettingNameForDevice(int device) {
+ String name = mVolumeIndexSettingName;
String suffix = AudioSystem.getDeviceName(device);
if (suffix.isEmpty()) {
return name;
@@ -2781,14 +2708,11 @@
// force maximum volume on all streams if fixed volume property is set
if (mUseFixedVolume) {
mIndex.put(AudioSystem.DEVICE_OUT_DEFAULT, mIndexMax);
- mLastAudibleIndex.put(AudioSystem.DEVICE_OUT_DEFAULT, mIndexMax);
return;
}
// do not read system stream volume from settings: this stream is always aliased
// to another stream type and its volume is never persisted. Values in settings can
// only be stale values
- // on first call to readSettings() at init time, muteCount() is always 0 so we will
- // always create entries for default device
if ((mStreamType == AudioSystem.STREAM_SYSTEM) ||
(mStreamType == AudioSystem.STREAM_SYSTEM_ENFORCED)) {
int index = 10 * AudioManager.DEFAULT_STREAM_VOLUME[mStreamType];
@@ -2797,10 +2721,7 @@
index = mIndexMax;
}
}
- if (muteCount() == 0) {
- mIndex.put(AudioSystem.DEVICE_OUT_DEFAULT, index);
- }
- mLastAudibleIndex.put(AudioSystem.DEVICE_OUT_DEFAULT, index);
+ mIndex.put(AudioSystem.DEVICE_OUT_DEFAULT, index);
return;
}
@@ -2814,7 +2735,7 @@
remainingDevices &= ~device;
// retrieve current volume for device
- String name = getSettingNameForDevice(false /* lastAudible */, device);
+ String name = getSettingNameForDevice(device);
// if no volume stored for current stream and device, use default volume if default
// device, continue otherwise
int defaultIndex = (device == AudioSystem.DEVICE_OUT_DEFAULT) ?
@@ -2828,72 +2749,33 @@
// ignore settings for fixed volume devices: volume should always be at max or 0
if ((mStreamVolumeAlias[mStreamType] == AudioSystem.STREAM_MUSIC) &&
((device & mFixedVolumeDevices) != 0)) {
- if ((muteCount()) == 0 && (index != 0)) {
- mIndex.put(device, mIndexMax);
- } else {
- mIndex.put(device, 0);
- }
- mLastAudibleIndex.put(device, mIndexMax);
- continue;
- }
-
- // retrieve last audible volume for device
- name = getSettingNameForDevice(true /* lastAudible */, device);
- // use stored last audible index if present, otherwise use current index if not 0
- // or default index
- defaultIndex = (index > 0) ?
- index : AudioManager.DEFAULT_STREAM_VOLUME[mStreamType];
- int lastAudibleIndex = Settings.System.getIntForUser(
- mContentResolver, name, defaultIndex, UserHandle.USER_CURRENT);
-
- // a last audible index of 0 should never be stored for ring and notification
- // streams on phones (voice capable devices).
- if ((lastAudibleIndex == 0) && mVoiceCapable &&
- (mStreamVolumeAlias[mStreamType] == AudioSystem.STREAM_RING)) {
- lastAudibleIndex = AudioManager.DEFAULT_STREAM_VOLUME[mStreamType];
- // Correct the data base
- sendMsg(mAudioHandler,
- MSG_PERSIST_VOLUME,
- SENDMSG_QUEUE,
- PERSIST_LAST_AUDIBLE,
- device,
- this,
- PERSIST_DELAY);
- }
- mLastAudibleIndex.put(device, getValidIndex(10 * lastAudibleIndex));
- // the initial index should never be 0 for ring and notification streams on phones
- // (voice capable devices) if not in silent or vibrate mode.
- if ((index == 0) && (mRingerMode == AudioManager.RINGER_MODE_NORMAL) &&
- mVoiceCapable &&
- (mStreamVolumeAlias[mStreamType] == AudioSystem.STREAM_RING)) {
- index = lastAudibleIndex;
- // Correct the data base
- sendMsg(mAudioHandler,
- MSG_PERSIST_VOLUME,
- SENDMSG_QUEUE,
- PERSIST_CURRENT,
- device,
- this,
- PERSIST_DELAY);
- }
- if (muteCount() == 0) {
+ mIndex.put(device, (index != 0) ? mIndexMax : 0);
+ } else {
mIndex.put(device, getValidIndex(10 * index));
}
}
}
public void applyDeviceVolume(int device) {
- AudioSystem.setStreamVolumeIndex(mStreamType,
- (getIndex(device, false /* lastAudible */) + 5)/10,
- device);
+ int index;
+ if (isMuted()) {
+ index = 0;
+ } else {
+ index = (getIndex(device) + 5)/10;
+ }
+ AudioSystem.setStreamVolumeIndex(mStreamType, index, device);
}
public synchronized void applyAllVolumes() {
// apply default volume first: by convention this will reset all
// devices volumes in audio policy manager to the supplied value
- AudioSystem.setStreamVolumeIndex(mStreamType,
- (getIndex(AudioSystem.DEVICE_OUT_DEFAULT, false /* lastAudible */) + 5)/10,
- AudioSystem.DEVICE_OUT_DEFAULT);
+ int index;
+ if (isMuted()) {
+ index = 0;
+ } else {
+ index = (getIndex(AudioSystem.DEVICE_OUT_DEFAULT) + 5)/10;
+ }
+ AudioSystem.setStreamVolumeIndex(mStreamType, index, AudioSystem.DEVICE_OUT_DEFAULT);
// then apply device specific volumes
Set set = mIndex.entrySet();
Iterator i = set.iterator();
@@ -2901,22 +2783,23 @@
Map.Entry entry = (Map.Entry)i.next();
int device = ((Integer)entry.getKey()).intValue();
if (device != AudioSystem.DEVICE_OUT_DEFAULT) {
- AudioSystem.setStreamVolumeIndex(mStreamType,
- ((Integer)entry.getValue() + 5)/10,
- device);
+ if (isMuted()) {
+ index = 0;
+ } else {
+ index = ((Integer)entry.getValue() + 5)/10;
+ }
+ AudioSystem.setStreamVolumeIndex(mStreamType, index, device);
}
}
}
public boolean adjustIndex(int deltaIndex, int device) {
- return setIndex(getIndex(device,
- false /* lastAudible */) + deltaIndex,
- device,
- true /* lastAudible */);
+ return setIndex(getIndex(device) + deltaIndex,
+ device);
}
- public synchronized boolean setIndex(int index, int device, boolean lastAudible) {
- int oldIndex = getIndex(device, false /* lastAudible */);
+ public synchronized boolean setIndex(int index, int device) {
+ int oldIndex = getIndex(device);
index = getValidIndex(index);
synchronized (mCameraSoundForced) {
if ((mStreamType == AudioSystem.STREAM_SYSTEM_ENFORCED) && mCameraSoundForced) {
@@ -2926,9 +2809,6 @@
mIndex.put(device, index);
if (oldIndex != index) {
- if (lastAudible) {
- mLastAudibleIndex.put(device, index);
- }
// Apply change to all streams using this one as alias
// if changing volume of current device, also change volume of current
// device on aliased stream
@@ -2939,12 +2819,10 @@
mStreamVolumeAlias[streamType] == mStreamType) {
int scaledIndex = rescaleIndex(index, mStreamType, streamType);
mStreamStates[streamType].setIndex(scaledIndex,
- device,
- lastAudible);
+ device);
if (currentDevice) {
mStreamStates[streamType].setIndex(scaledIndex,
- getDeviceForStream(streamType),
- lastAudible);
+ getDeviceForStream(streamType));
}
}
}
@@ -2954,63 +2832,21 @@
}
}
- public synchronized int getIndex(int device, boolean lastAudible) {
- ConcurrentHashMap <Integer, Integer> indexes;
- if (lastAudible) {
- indexes = mLastAudibleIndex;
- } else {
- indexes = mIndex;
- }
- Integer index = indexes.get(device);
+ public synchronized int getIndex(int device) {
+ Integer index = mIndex.get(device);
if (index == null) {
// there is always an entry for AudioSystem.DEVICE_OUT_DEFAULT
- index = indexes.get(AudioSystem.DEVICE_OUT_DEFAULT);
+ index = mIndex.get(AudioSystem.DEVICE_OUT_DEFAULT);
}
return index.intValue();
}
- public synchronized void setLastAudibleIndex(int index, int device) {
- // Apply change to all streams using this one as alias
- // if changing volume of current device, also change volume of current
- // device on aliased stream
- boolean currentDevice = (device == getDeviceForStream(mStreamType));
- int numStreamTypes = AudioSystem.getNumStreamTypes();
- for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) {
- if (streamType != mStreamType &&
- mStreamVolumeAlias[streamType] == mStreamType) {
- int scaledIndex = rescaleIndex(index, mStreamType, streamType);
- mStreamStates[streamType].setLastAudibleIndex(scaledIndex, device);
- if (currentDevice) {
- mStreamStates[streamType].setLastAudibleIndex(scaledIndex,
- getDeviceForStream(streamType));
- }
- }
- }
- mLastAudibleIndex.put(device, getValidIndex(index));
- }
-
- public synchronized void adjustLastAudibleIndex(int deltaIndex, int device) {
- setLastAudibleIndex(getIndex(device,
- true /* lastAudible */) + deltaIndex,
- device);
- }
-
public int getMaxIndex() {
return mIndexMax;
}
- // only called by setAllIndexes() which is already synchronized
- public ConcurrentHashMap <Integer, Integer> getAllIndexes(boolean lastAudible) {
- if (lastAudible) {
- return mLastAudibleIndex;
- } else {
- return mIndex;
- }
- }
-
- public synchronized void setAllIndexes(VolumeStreamState srcStream, boolean lastAudible) {
- ConcurrentHashMap <Integer, Integer> indexes = srcStream.getAllIndexes(lastAudible);
- Set set = indexes.entrySet();
+ public synchronized void setAllIndexes(VolumeStreamState srcStream) {
+ Set set = srcStream.mIndex.entrySet();
Iterator i = set.iterator();
while (i.hasNext()) {
Map.Entry entry = (Map.Entry)i.next();
@@ -3018,11 +2854,7 @@
int index = ((Integer)entry.getValue()).intValue();
index = rescaleIndex(index, srcStream.getStreamType(), mStreamType);
- if (lastAudible) {
- setLastAudibleIndex(index, device);
- } else {
- setIndex(index, device, false /* lastAudible */);
- }
+ setIndex(index, device);
}
}
@@ -3033,12 +2865,6 @@
Map.Entry entry = (Map.Entry)i.next();
entry.setValue(mIndexMax);
}
- set = mLastAudibleIndex.entrySet();
- i = set.iterator();
- while (i.hasNext()) {
- Map.Entry entry = (Map.Entry)i.next();
- entry.setValue(mIndexMax);
- }
}
public synchronized void mute(IBinder cb, boolean state) {
@@ -3074,6 +2900,7 @@
// must be called while synchronized on parent VolumeStreamState
public void mute(boolean state) {
+ boolean updateVolume = false;
if (state) {
if (mMuteCount == 0) {
// Register for client death notification
@@ -3082,22 +2909,10 @@
if (mICallback != null) {
mICallback.linkToDeath(this, 0);
}
- mDeathHandlers.add(this);
+ VolumeStreamState.this.mDeathHandlers.add(this);
// If the stream is not yet muted by any client, set level to 0
- if (muteCount() == 0) {
- Set set = mIndex.entrySet();
- Iterator i = set.iterator();
- while (i.hasNext()) {
- Map.Entry entry = (Map.Entry)i.next();
- int device = ((Integer)entry.getKey()).intValue();
- setIndex(0, device, false /* lastAudible */);
- }
- sendMsg(mAudioHandler,
- MSG_SET_ALL_VOLUMES,
- SENDMSG_QUEUE,
- 0,
- 0,
- VolumeStreamState.this, 0);
+ if (!VolumeStreamState.this.isMuted()) {
+ updateVolume = true;
}
} catch (RemoteException e) {
// Client has died!
@@ -3115,37 +2930,25 @@
mMuteCount--;
if (mMuteCount == 0) {
// Unregister from client death notification
- mDeathHandlers.remove(this);
+ VolumeStreamState.this.mDeathHandlers.remove(this);
// mICallback can be 0 if muted by AudioService
if (mICallback != null) {
mICallback.unlinkToDeath(this, 0);
}
- if (muteCount() == 0) {
- // If the stream is not muted any more, restore its volume if
- // ringer mode allows it
- if (!isStreamAffectedByRingerMode(mStreamType) ||
- mRingerMode == AudioManager.RINGER_MODE_NORMAL) {
- Set set = mIndex.entrySet();
- Iterator i = set.iterator();
- while (i.hasNext()) {
- Map.Entry entry = (Map.Entry)i.next();
- int device = ((Integer)entry.getKey()).intValue();
- setIndex(getIndex(device,
- true /* lastAudible */),
- device,
- false /* lastAudible */);
- }
- sendMsg(mAudioHandler,
- MSG_SET_ALL_VOLUMES,
- SENDMSG_QUEUE,
- 0,
- 0,
- VolumeStreamState.this, 0);
- }
+ if (!VolumeStreamState.this.isMuted()) {
+ updateVolume = true;
}
}
}
}
+ if (updateVolume) {
+ sendMsg(mAudioHandler,
+ MSG_SET_ALL_VOLUMES,
+ SENDMSG_QUEUE,
+ 0,
+ 0,
+ VolumeStreamState.this, 0);
+ }
}
public void binderDied() {
@@ -3167,6 +2970,10 @@
return count;
}
+ private synchronized boolean isMuted() {
+ return muteCount() != 0;
+ }
+
// only called by mute() which is already synchronized
private VolumeDeathHandler getDeathHandler(IBinder cb, boolean state) {
VolumeDeathHandler handler;
@@ -3199,14 +3006,6 @@
pw.print(Integer.toHexString(((Integer)entry.getKey()).intValue())
+ ": " + ((((Integer)entry.getValue()).intValue() + 5) / 10)+", ");
}
- pw.print("\n Last audible: ");
- set = mLastAudibleIndex.entrySet();
- i = set.iterator();
- while (i.hasNext()) {
- Map.Entry entry = (Map.Entry)i.next();
- pw.print(Integer.toHexString(((Integer)entry.getKey()).intValue())
- + ": " + ((((Integer)entry.getValue()).intValue() + 5) / 10)+", ");
- }
}
}
@@ -3254,8 +3053,8 @@
sendMsg(mAudioHandler,
MSG_PERSIST_VOLUME,
SENDMSG_QUEUE,
- PERSIST_CURRENT|PERSIST_LAST_AUDIBLE,
device,
+ 0,
streamState,
PERSIST_DELAY);
@@ -3276,24 +3075,14 @@
}
}
- private void persistVolume(VolumeStreamState streamState,
- int persistType,
- int device) {
+ private void persistVolume(VolumeStreamState streamState, int device) {
if (mUseFixedVolume) {
return;
}
- if ((persistType & PERSIST_CURRENT) != 0) {
- System.putIntForUser(mContentResolver,
- streamState.getSettingNameForDevice(false /* lastAudible */, device),
- (streamState.getIndex(device, false /* lastAudible */) + 5)/ 10,
- UserHandle.USER_CURRENT);
- }
- if ((persistType & PERSIST_LAST_AUDIBLE) != 0) {
- System.putIntForUser(mContentResolver,
- streamState.getSettingNameForDevice(true /* lastAudible */, device),
- (streamState.getIndex(device, true /* lastAudible */) + 5) / 10,
- UserHandle.USER_CURRENT);
- }
+ System.putIntForUser(mContentResolver,
+ streamState.getSettingNameForDevice(device),
+ (streamState.getIndex(device) + 5)/ 10,
+ UserHandle.USER_CURRENT);
}
private void persistRingerMode(int ringerMode) {
@@ -3545,7 +3334,7 @@
break;
case MSG_PERSIST_VOLUME:
- persistVolume((VolumeStreamState) msg.obj, msg.arg1, msg.arg2);
+ persistVolume((VolumeStreamState) msg.obj, msg.arg1);
break;
case MSG_PERSIST_MASTER_VOLUME:
@@ -6391,10 +6180,7 @@
mRingerModeAffectedStreams &=
~(1 << AudioSystem.STREAM_SYSTEM_ENFORCED);
} else {
- s.setAllIndexes(mStreamStates[AudioSystem.STREAM_SYSTEM],
- false /*lastAudible*/);
- s.setAllIndexes(mStreamStates[AudioSystem.STREAM_SYSTEM],
- true /*lastAudible*/);
+ s.setAllIndexes(mStreamStates[AudioSystem.STREAM_SYSTEM]);
mRingerModeAffectedStreams |=
(1 << AudioSystem.STREAM_SYSTEM_ENFORCED);
}
@@ -6540,7 +6326,6 @@
private void enforceSafeMediaVolume() {
VolumeStreamState streamState = mStreamStates[AudioSystem.STREAM_MUSIC];
- boolean lastAudible = (streamState.muteCount() != 0);
int devices = mSafeMediaVolumeDevices;
int i = 0;
@@ -6549,27 +6334,16 @@
if ((device & devices) == 0) {
continue;
}
- int index = streamState.getIndex(device, lastAudible);
+ int index = streamState.getIndex(device);
if (index > mSafeMediaVolumeIndex) {
- if (lastAudible) {
- streamState.setLastAudibleIndex(mSafeMediaVolumeIndex, device);
- sendMsg(mAudioHandler,
- MSG_PERSIST_VOLUME,
- SENDMSG_QUEUE,
- PERSIST_LAST_AUDIBLE,
- device,
- streamState,
- PERSIST_DELAY);
- } else {
- streamState.setIndex(mSafeMediaVolumeIndex, device, true);
- sendMsg(mAudioHandler,
- MSG_SET_DEVICE_VOLUME,
- SENDMSG_QUEUE,
- device,
- 0,
- streamState,
- 0);
- }
+ streamState.setIndex(mSafeMediaVolumeIndex, device);
+ sendMsg(mAudioHandler,
+ MSG_SET_DEVICE_VOLUME,
+ SENDMSG_QUEUE,
+ device,
+ 0,
+ streamState,
+ 0);
}
devices &= ~device;
}