| Index: content/public/android/java/src/org/chromium/content/browser/AudioFocusManager.java
|
| diff --git a/content/public/android/java/src/org/chromium/content/browser/AudioFocusManager.java b/content/public/android/java/src/org/chromium/content/browser/AudioFocusManager.java
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..9b8e7045745c4b70d0bafc391961857c90a3658f
|
| --- /dev/null
|
| +++ b/content/public/android/java/src/org/chromium/content/browser/AudioFocusManager.java
|
| @@ -0,0 +1,99 @@
|
| +// Copyright 2015 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +package org.chromium.content.browser;
|
| +
|
| +import android.content.Context;
|
| +import android.media.AudioManager;
|
| +import android.media.AudioManager.OnAudioFocusChangeListener;
|
| +
|
| +import org.chromium.base.CalledByNative;
|
| +import org.chromium.base.JNINamespace;
|
| +import org.chromium.base.Log;
|
| +
|
| +import java.util.AbstractMap.SimpleEntry;
|
| +import java.util.HashSet;
|
| +import java.util.Map.Entry;
|
| +import java.util.Set;
|
| +
|
| +@JNINamespace("content")
|
| +class AudioFocusManager implements OnAudioFocusChangeListener {
|
| + private static final String TAG = "AudioFocusManager";
|
| +
|
| + private static AudioFocusManager sInstance;
|
| +
|
| + private final Context mContext;
|
| +
|
| + // Maintain a set of native pointer and player ID pairs.
|
| + private final Set<Entry<Long, Integer>> mPlayers =
|
| + new HashSet<Entry<Long, Integer>>();
|
| +
|
| + private AudioFocusManager(Context context) {
|
| + mContext = context;
|
| + }
|
| +
|
| + @CalledByNative
|
| + public static AudioFocusManager getInstance(Context context) {
|
| + if (sInstance == null) {
|
| + sInstance = new AudioFocusManager(context.getApplicationContext());
|
| + }
|
| + return sInstance;
|
| + }
|
| +
|
| + @Override
|
| + public void onAudioFocusChange(int focusChange) {
|
| + if (focusChange == AudioManager.AUDIOFOCUS_LOSS
|
| + || focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT
|
| + || focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK) {
|
| + interruptAllPlayers();
|
| + mPlayers.clear();
|
| +
|
| + AudioManager audioManager = (AudioManager) mContext.getSystemService(
|
| + Context.AUDIO_SERVICE);
|
| + audioManager.abandonAudioFocus(this);
|
| + }
|
| + }
|
| +
|
| + @CalledByNative
|
| + private void abandonAudioFocus(long nativeAudioFocusManager, int playerId) {
|
| + Entry<Long, Integer> player =
|
| + new SimpleEntry<Long, Integer>(nativeAudioFocusManager, playerId);
|
| +
|
| + if (mPlayers.remove(player) && mPlayers.isEmpty()) {
|
| + AudioManager audioManager = (AudioManager) mContext.getSystemService(
|
| + Context.AUDIO_SERVICE);
|
| + audioManager.abandonAudioFocus(this);
|
| + }
|
| + }
|
| +
|
| + @CalledByNative
|
| + private void requestAudioFocus(long nativeAudioFocusManager, int playerId) {
|
| + AudioManager audioManager = (AudioManager) mContext.getSystemService(
|
| + Context.AUDIO_SERVICE);
|
| + int result = audioManager.requestAudioFocus(
|
| + this,
|
| + AudioManager.STREAM_MUSIC,
|
| + AudioManager.AUDIOFOCUS_GAIN);
|
| +
|
| + if (result == AudioManager.AUDIOFOCUS_REQUEST_FAILED) {
|
| + Log.w(TAG, "requestAudioFocus: Request for audio focus failed");
|
| + nativeOnMediaInterrupted(nativeAudioFocusManager, playerId);
|
| + return;
|
| + }
|
| +
|
| + Entry<Long, Integer> player =
|
| + new SimpleEntry<Long, Integer>(nativeAudioFocusManager, playerId);
|
| + mPlayers.add(player);
|
| + }
|
| +
|
| + private void interruptAllPlayers() {
|
| + for (Entry<Long, Integer> player : mPlayers) {
|
| + long nativeAudioFocusManager = player.getKey();
|
| + int playerId = player.getValue();
|
| + nativeOnMediaInterrupted(nativeAudioFocusManager, playerId);
|
| + }
|
| + }
|
| +
|
| + private native void nativeOnMediaInterrupted(long nativeAudioFocusManager, int playerId);
|
| +}
|
|
|