Skip to content

Commit 5717020

Browse files
James Chenminggo
authored andcommitted
fixed #17685: [android] Audio in game couldn't be mute while a ring or a call is coming (#17686)
* fixed #17685: [android] Audio in game couldn't be mute while a ring or a call is coming * Updates comments in AudioEngine-inl.cpp and removes extra empty line in javaactivity-android.cpp * Puts audio focus relative code to another java file named Cocos2dxAudioFocusManager.java Renames setAudioFocusLost to setAudioFocus. * Renames JNI function. * Register audio focus in onResume and unregister it in onPause.
1 parent 270bcb2 commit 5717020

15 files changed

+290
-36
lines changed

cocos/audio/android/AudioEngine-inl.cpp

Lines changed: 47 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,6 @@
2323
****************************************************************************/
2424
#if CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID
2525

26-
#define LOG_TAG "cocos2d-x debug info"
27-
2826
#include "audio/android/AudioEngine-inl.h"
2927

3028
#include <unistd.h>
@@ -43,6 +41,7 @@
4341
#include "base/CCEventDispatcher.h"
4442
#include "base/CCEventType.h"
4543
#include "base/CCEventListenerCustom.h"
44+
#include "base/ccUTF8.h"
4645
#include "platform/android/CCFileUtils-android.h"
4746
#include "platform/android/jni/Java_org_cocos2dx_lib_Cocos2dxHelper.h"
4847

@@ -55,8 +54,14 @@
5554
using namespace cocos2d;
5655
using namespace cocos2d::experimental;
5756

58-
#define DELAY_TIME_TO_REMOVE 0.5f
57+
// Audio focus values synchronized with which in cocos/platform/android/java/src/org/cocos2dx/lib/Cocos2dxActivity.java
58+
static const int AUDIOFOCUS_GAIN = 0;
59+
static const int AUDIOFOCUS_LOST = 1;
60+
static const int AUDIOFOCUS_LOST_TRANSIENT = 2;
61+
static const int AUDIOFOCUS_LOST_TRANSIENT_CAN_DUCK = 3;
5962

63+
static int __currentAudioFocus = AUDIOFOCUS_GAIN;
64+
static AudioEngineImpl* __impl = nullptr;
6065

6166
class CallerThreadUtils : public ICallerThreadUtils
6267
{
@@ -117,6 +122,7 @@ AudioEngineImpl::AudioEngineImpl()
117122
, _lazyInitLoop(true)
118123
{
119124
__callerThreadUtils.setCallerThreadId(std::this_thread::get_id());
125+
__impl = this;
120126
}
121127

122128
AudioEngineImpl::~AudioEngineImpl()
@@ -145,6 +151,8 @@ AudioEngineImpl::~AudioEngineImpl()
145151
{
146152
Director::getInstance()->getEventDispatcher()->removeEventListener(_onResumeListener);
147153
}
154+
155+
__impl = nullptr;
148156
}
149157

150158
bool AudioEngineImpl::init()
@@ -225,6 +233,14 @@ void AudioEngineImpl::onEnterForeground(EventCustom* event)
225233
_urlAudioPlayersNeedResume.clear();
226234
}
227235

236+
void AudioEngineImpl::setAudioFocusForAllPlayers(bool isFocus)
237+
{
238+
for (const auto& e : _audioPlayers)
239+
{
240+
e.second->setAudioFocus(isFocus);
241+
}
242+
}
243+
228244
int AudioEngineImpl::play2d(const std::string &filePath ,bool loop ,float volume)
229245
{
230246
ALOGV("play2d, _audioPlayers.size=%d", (int)_audioPlayers.size());
@@ -274,6 +290,7 @@ int AudioEngineImpl::play2d(const std::string &filePath ,bool loop ,float volume
274290

275291
player->setLoop(loop);
276292
player->setVolume(volume);
293+
player->setAudioFocus(__currentAudioFocus == AUDIOFOCUS_GAIN);
277294
player->play();
278295
}
279296
else
@@ -439,4 +456,31 @@ void AudioEngineImpl::uncacheAll()
439456
}
440457
}
441458

459+
// It's invoked from javaactivity-android.cpp
460+
void cocos_audioengine_focus_change(int focusChange)
461+
{
462+
if (focusChange < AUDIOFOCUS_GAIN || focusChange > AUDIOFOCUS_LOST_TRANSIENT_CAN_DUCK)
463+
{
464+
CCLOGERROR("cocos_audioengine_focus_change: unknown value: %d", focusChange);
465+
return;
466+
}
467+
CCLOG("cocos_audioengine_focus_change: %d", focusChange);
468+
__currentAudioFocus = focusChange;
469+
470+
if (__impl == nullptr)
471+
{
472+
CCLOGWARN("cocos_audioengine_focus_change: AudioEngineImpl isn't ready!");
473+
return;
474+
}
475+
476+
if (__currentAudioFocus == AUDIOFOCUS_GAIN)
477+
{
478+
__impl->setAudioFocusForAllPlayers(true);
479+
}
480+
else
481+
{
482+
__impl->setAudioFocusForAllPlayers(false);
483+
}
484+
}
485+
442486
#endif

cocos/audio/android/AudioEngine-inl.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ class AudioEngineImpl : public cocos2d::Ref
7272
void uncacheAll();
7373
void preload(const std::string& filePath, const std::function<void(bool)>& callback);
7474

75+
void setAudioFocusForAllPlayers(bool isFocus);
7576
private:
7677

7778
void onEnterBackground(EventCustom* event);

cocos/audio/android/IAudioPlayer.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@ class IAudioPlayer
6868

6969
virtual float getVolume() const = 0;
7070

71+
virtual void setAudioFocus(bool isFocus) = 0;
72+
7173
virtual void setLoop(bool isLoop) = 0;
7274

7375
virtual bool isLoop() const = 0;

cocos/audio/android/PcmAudioPlayer.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,11 @@ float PcmAudioPlayer::getVolume() const
110110
return _track->getVolume();
111111
}
112112

113+
void PcmAudioPlayer::setAudioFocus(bool isFocus)
114+
{
115+
_track->setAudioFocus(isFocus);
116+
}
117+
113118
void PcmAudioPlayer::setLoop(bool isLoop)
114119
{
115120
_track->setLoop(isLoop);

cocos/audio/android/PcmAudioPlayer.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ class PcmAudioPlayer : public IAudioPlayer
6262

6363
virtual float getVolume() const override;
6464

65+
virtual void setAudioFocus(bool isFocus) override;
66+
6567
virtual void setLoop(bool isLoop) override;
6668

6769
virtual bool isLoop() const override;

cocos/audio/android/Track.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ Track::Track(const PcmData &pcmData)
4141
, _isVolumeDirty(true)
4242
, _isLoop(false)
4343
, _isInitialized(false)
44+
, _isAudioFocus(true)
4445
{
4546
init(_pcmData.pcmBuffer->data(), _pcmData.numFrames, _pcmData.bitsPerSample / 8 * _pcmData.numChannels);
4647
}
@@ -52,7 +53,8 @@ Track::~Track()
5253

5354
gain_minifloat_packed_t Track::getVolumeLR()
5455
{
55-
gain_minifloat_t v = gain_from_float(_volume);
56+
float volume = _isAudioFocus ? _volume : 0.0f;
57+
gain_minifloat_t v = gain_from_float(volume);
5658
return gain_minifloat_pack(v, v);
5759
}
5860

@@ -83,6 +85,12 @@ float Track::getVolume() const
8385
return _volume;
8486
}
8587

88+
void Track::setAudioFocus(bool isFocus)
89+
{
90+
_isAudioFocus = isFocus;
91+
setVolumeDirty(true);
92+
}
93+
8694
void Track::setState(State state)
8795
{
8896
std::lock_guard<std::mutex> lk(_stateMutex);

cocos/audio/android/Track.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ class Track : public PcmBufferProvider, public IVolumeProvider
6262
void setVolume(float volume);
6363
float getVolume() const;
6464

65+
void setAudioFocus(bool isFocus);
66+
6567
bool setPosition(float pos);
6668
float getPosition() const;
6769

@@ -96,6 +98,7 @@ class Track : public PcmBufferProvider, public IVolumeProvider
9698
std::mutex _volumeDirtyMutex;
9799
bool _isLoop;
98100
bool _isInitialized;
101+
bool _isAudioFocus;
99102

100103
friend class AudioMixerController;
101104
};

cocos/audio/android/UrlAudioPlayer.cpp

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ UrlAudioPlayer::UrlAudioPlayer(SLEngineItf engineItf, SLObjectItf outputMixObjec
6060
: _engineItf(engineItf), _outputMixObj(outputMixObject),
6161
_callerThreadUtils(callerThreadUtils), _id(-1), _assetFd(nullptr),
6262
_playObj(nullptr), _playItf(nullptr), _seekItf(nullptr), _volumeItf(nullptr),
63-
_volume(0.0f), _duration(0.0f), _isLoop(false), _state(State::INVALID),
63+
_volume(0.0f), _duration(0.0f), _isLoop(false), _isAudioFocus(true), _state(State::INVALID),
6464
_playEventCallback(nullptr), _isDestroyed(std::make_shared<bool>(false))
6565
{
6666
std::call_once(__onceFlag, [](){
@@ -215,16 +215,36 @@ void UrlAudioPlayer::play()
215215
}
216216
}
217217

218-
void UrlAudioPlayer::setVolume(float volume)
218+
void UrlAudioPlayer::setVolumeToSLPlayer(float volume)
219219
{
220-
_volume = volume;
221220
int dbVolume = 2000 * log10(volume);
222221
if (dbVolume < SL_MILLIBEL_MIN)
223222
{
224223
dbVolume = SL_MILLIBEL_MIN;
225224
}
226225
SLresult r = (*_volumeItf)->SetVolumeLevel(_volumeItf, dbVolume);
227-
SL_RETURN_IF_FAILED(r, "UrlAudioPlayer::setVolume %d failed", dbVolume);
226+
SL_RETURN_IF_FAILED(r, "UrlAudioPlayer::setVolumeToSLPlayer %d failed", dbVolume);
227+
}
228+
229+
void UrlAudioPlayer::setVolume(float volume)
230+
{
231+
_volume = volume;
232+
if (_isAudioFocus)
233+
{
234+
setVolumeToSLPlayer(_volume);
235+
}
236+
}
237+
238+
float UrlAudioPlayer::getVolume() const
239+
{
240+
return _volume;
241+
}
242+
243+
void UrlAudioPlayer::setAudioFocus(bool isFocus)
244+
{
245+
_isAudioFocus = isFocus;
246+
float volume = _isAudioFocus ? _volume : 0.0f;
247+
setVolumeToSLPlayer(volume);
228248
}
229249

230250
float UrlAudioPlayer::getDuration() const
@@ -362,11 +382,6 @@ void UrlAudioPlayer::rewind()
362382
// Not supported currently. since cocos audio engine will new -> prepare -> play again.
363383
}
364384

365-
float UrlAudioPlayer::getVolume() const
366-
{
367-
return _volume;
368-
}
369-
370385
void UrlAudioPlayer::setLoop(bool isLoop)
371386
{
372387
_isLoop = isLoop;

cocos/audio/android/UrlAudioPlayer.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@ class UrlAudioPlayer : public IAudioPlayer
6868

6969
virtual float getVolume() const override;
7070

71+
virtual void setAudioFocus(bool isFocus) override;
72+
7173
virtual void setLoop(bool isLoop) override;
7274

7375
virtual bool isLoop() const override;
@@ -97,6 +99,8 @@ class UrlAudioPlayer : public IAudioPlayer
9799

98100
void playEventCallback(SLPlayItf caller, SLuint32 playEvent);
99101

102+
void setVolumeToSLPlayer(float volume);
103+
100104
private:
101105
SLEngineItf _engineItf;
102106
SLObjectItf _outputMixObj;
@@ -115,6 +119,7 @@ class UrlAudioPlayer : public IAudioPlayer
115119
float _volume;
116120
float _duration;
117121
bool _isLoop;
122+
bool _isAudioFocus;
118123
State _state;
119124

120125
PlayEventCallback _playEventCallback;

cocos/platform/android/java/src/org/cocos2dx/lib/Cocos2dxActivity.java

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,16 +33,13 @@ of this software and associated documentation files (the "Software"), to deal
3333
import android.opengl.GLSurfaceView;
3434
import android.os.Build;
3535
import android.os.Bundle;
36-
import android.os.Handler;
3736
import android.os.Message;
3837
import android.preference.PreferenceManager.OnActivityResultListener;
39-
import android.util.AttributeSet;
4038
import android.util.Log;
41-
import android.view.ViewGroup;
4239
import android.view.View;
40+
import android.view.ViewGroup;
4341
import android.view.Window;
4442
import android.view.WindowManager;
45-
import android.widget.FrameLayout;
4643

4744
import org.cocos2dx.lib.Cocos2dxHelper.Cocos2dxHelperListener;
4845

@@ -74,7 +71,7 @@ public abstract class Cocos2dxActivity extends Activity implements Cocos2dxHelpe
7471
public Cocos2dxGLSurfaceView getGLSurfaceView(){
7572
return mGLSurfaceView;
7673
}
77-
74+
7875
public static Context getContext() {
7976
return sContext;
8077
}
@@ -135,12 +132,13 @@ protected void onCreate(final Bundle savedInstanceState) {
135132
Window window = this.getWindow();
136133
window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
137134

135+
// Audio configuration
138136
this.setVolumeControlStream(AudioManager.STREAM_MUSIC);
139137
}
140138

141139
//native method,call GLViewImpl::getGLContextAttrs() to get the OpenGL ES context attributions
142140
private static native int[] getGLContextAttrs();
143-
141+
144142
// ===========================================================
145143
// Getter & Setter
146144
// ===========================================================
@@ -153,6 +151,7 @@ protected void onCreate(final Bundle savedInstanceState) {
153151
protected void onResume() {
154152
Log.d(TAG, "onResume()");
155153
super.onResume();
154+
Cocos2dxAudioFocusManager.registerAudioFocusListener(this);
156155
this.hideVirtualButton();
157156
resumeIfHasFocus();
158157
}
@@ -178,12 +177,14 @@ private void resumeIfHasFocus() {
178177
protected void onPause() {
179178
Log.d(TAG, "onPause()");
180179
super.onPause();
180+
Cocos2dxAudioFocusManager.unregisterAudioFocusListener(this);
181181
Cocos2dxHelper.onPause();
182182
mGLSurfaceView.onPause();
183183
}
184184

185185
@Override
186186
protected void onDestroy() {
187+
Cocos2dxAudioFocusManager.unregisterAudioFocusListener(this);
187188
super.onDestroy();
188189
}
189190

0 commit comments

Comments
 (0)