diff --git a/cocos/audio/android/AudioEngine-inl.cpp b/cocos/audio/android/AudioEngine-inl.cpp index cad99a8f9b..56622bdf30 100644 --- a/cocos/audio/android/AudioEngine-inl.cpp +++ b/cocos/audio/android/AudioEngine-inl.cpp @@ -23,8 +23,6 @@ ****************************************************************************/ #if CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID -#define LOG_TAG "cocos2d-x debug info" - #include "audio/android/AudioEngine-inl.h" #include @@ -43,6 +41,7 @@ #include "base/CCEventDispatcher.h" #include "base/CCEventType.h" #include "base/CCEventListenerCustom.h" +#include "base/ccUTF8.h" #include "platform/android/CCFileUtils-android.h" #include "platform/android/jni/Java_org_cocos2dx_lib_Cocos2dxHelper.h" @@ -55,8 +54,14 @@ using namespace cocos2d; using namespace cocos2d::experimental; -#define DELAY_TIME_TO_REMOVE 0.5f +// Audio focus values synchronized with which in cocos/platform/android/java/src/org/cocos2dx/lib/Cocos2dxActivity.java +static const int AUDIOFOCUS_GAIN = 0; +static const int AUDIOFOCUS_LOST = 1; +static const int AUDIOFOCUS_LOST_TRANSIENT = 2; +static const int AUDIOFOCUS_LOST_TRANSIENT_CAN_DUCK = 3; +static int __currentAudioFocus = AUDIOFOCUS_GAIN; +static AudioEngineImpl* __impl = nullptr; class CallerThreadUtils : public ICallerThreadUtils { @@ -117,6 +122,7 @@ AudioEngineImpl::AudioEngineImpl() , _lazyInitLoop(true) { __callerThreadUtils.setCallerThreadId(std::this_thread::get_id()); + __impl = this; } AudioEngineImpl::~AudioEngineImpl() @@ -145,6 +151,8 @@ AudioEngineImpl::~AudioEngineImpl() { Director::getInstance()->getEventDispatcher()->removeEventListener(_onResumeListener); } + + __impl = nullptr; } bool AudioEngineImpl::init() @@ -225,6 +233,14 @@ void AudioEngineImpl::onEnterForeground(EventCustom* event) _urlAudioPlayersNeedResume.clear(); } +void AudioEngineImpl::setAudioFocusForAllPlayers(bool isFocus) +{ + for (const auto& e : _audioPlayers) + { + e.second->setAudioFocus(isFocus); + } +} + int AudioEngineImpl::play2d(const std::string &filePath ,bool loop ,float volume) { ALOGV("play2d, _audioPlayers.size=%d", (int)_audioPlayers.size()); @@ -274,6 +290,7 @@ int AudioEngineImpl::play2d(const std::string &filePath ,bool loop ,float volume player->setLoop(loop); player->setVolume(volume); + player->setAudioFocus(__currentAudioFocus == AUDIOFOCUS_GAIN); player->play(); } else @@ -439,4 +456,31 @@ void AudioEngineImpl::uncacheAll() } } +// It's invoked from javaactivity-android.cpp +void cocos_audioengine_focus_change(int focusChange) +{ + if (focusChange < AUDIOFOCUS_GAIN || focusChange > AUDIOFOCUS_LOST_TRANSIENT_CAN_DUCK) + { + CCLOGERROR("cocos_audioengine_focus_change: unknown value: %d", focusChange); + return; + } + CCLOG("cocos_audioengine_focus_change: %d", focusChange); + __currentAudioFocus = focusChange; + + if (__impl == nullptr) + { + CCLOGWARN("cocos_audioengine_focus_change: AudioEngineImpl isn't ready!"); + return; + } + + if (__currentAudioFocus == AUDIOFOCUS_GAIN) + { + __impl->setAudioFocusForAllPlayers(true); + } + else + { + __impl->setAudioFocusForAllPlayers(false); + } +} + #endif diff --git a/cocos/audio/android/AudioEngine-inl.h b/cocos/audio/android/AudioEngine-inl.h index f2a6943d89..bec699dbae 100644 --- a/cocos/audio/android/AudioEngine-inl.h +++ b/cocos/audio/android/AudioEngine-inl.h @@ -72,6 +72,7 @@ public: void uncacheAll(); void preload(const std::string& filePath, const std::function& callback); + void setAudioFocusForAllPlayers(bool isFocus); private: void onEnterBackground(EventCustom* event); diff --git a/cocos/audio/android/IAudioPlayer.h b/cocos/audio/android/IAudioPlayer.h index fe8390d43d..d5cd1cca24 100644 --- a/cocos/audio/android/IAudioPlayer.h +++ b/cocos/audio/android/IAudioPlayer.h @@ -68,6 +68,8 @@ public: virtual float getVolume() const = 0; + virtual void setAudioFocus(bool isFocus) = 0; + virtual void setLoop(bool isLoop) = 0; virtual bool isLoop() const = 0; diff --git a/cocos/audio/android/PcmAudioPlayer.cpp b/cocos/audio/android/PcmAudioPlayer.cpp index 5624345aff..30ae4c5522 100644 --- a/cocos/audio/android/PcmAudioPlayer.cpp +++ b/cocos/audio/android/PcmAudioPlayer.cpp @@ -110,6 +110,11 @@ float PcmAudioPlayer::getVolume() const return _track->getVolume(); } +void PcmAudioPlayer::setAudioFocus(bool isFocus) +{ + _track->setAudioFocus(isFocus); +} + void PcmAudioPlayer::setLoop(bool isLoop) { _track->setLoop(isLoop); diff --git a/cocos/audio/android/PcmAudioPlayer.h b/cocos/audio/android/PcmAudioPlayer.h index a08c8b0193..b55f6dc51d 100644 --- a/cocos/audio/android/PcmAudioPlayer.h +++ b/cocos/audio/android/PcmAudioPlayer.h @@ -62,6 +62,8 @@ public: virtual float getVolume() const override; + virtual void setAudioFocus(bool isFocus) override; + virtual void setLoop(bool isLoop) override; virtual bool isLoop() const override; diff --git a/cocos/audio/android/Track.cpp b/cocos/audio/android/Track.cpp index 780e75edf7..f94faec578 100644 --- a/cocos/audio/android/Track.cpp +++ b/cocos/audio/android/Track.cpp @@ -41,6 +41,7 @@ Track::Track(const PcmData &pcmData) , _isVolumeDirty(true) , _isLoop(false) , _isInitialized(false) + , _isAudioFocus(true) { init(_pcmData.pcmBuffer->data(), _pcmData.numFrames, _pcmData.bitsPerSample / 8 * _pcmData.numChannels); } @@ -52,7 +53,8 @@ Track::~Track() gain_minifloat_packed_t Track::getVolumeLR() { - gain_minifloat_t v = gain_from_float(_volume); + float volume = _isAudioFocus ? _volume : 0.0f; + gain_minifloat_t v = gain_from_float(volume); return gain_minifloat_pack(v, v); } @@ -83,6 +85,12 @@ float Track::getVolume() const return _volume; } +void Track::setAudioFocus(bool isFocus) +{ + _isAudioFocus = isFocus; + setVolumeDirty(true); +} + void Track::setState(State state) { std::lock_guard lk(_stateMutex); diff --git a/cocos/audio/android/Track.h b/cocos/audio/android/Track.h index 570bc1a695..c9a559fd57 100644 --- a/cocos/audio/android/Track.h +++ b/cocos/audio/android/Track.h @@ -62,6 +62,8 @@ public: void setVolume(float volume); float getVolume() const; + void setAudioFocus(bool isFocus); + bool setPosition(float pos); float getPosition() const; @@ -96,6 +98,7 @@ private: std::mutex _volumeDirtyMutex; bool _isLoop; bool _isInitialized; + bool _isAudioFocus; friend class AudioMixerController; }; diff --git a/cocos/audio/android/UrlAudioPlayer.cpp b/cocos/audio/android/UrlAudioPlayer.cpp index a01de52e75..c6f01b826c 100644 --- a/cocos/audio/android/UrlAudioPlayer.cpp +++ b/cocos/audio/android/UrlAudioPlayer.cpp @@ -60,7 +60,7 @@ UrlAudioPlayer::UrlAudioPlayer(SLEngineItf engineItf, SLObjectItf outputMixObjec : _engineItf(engineItf), _outputMixObj(outputMixObject), _callerThreadUtils(callerThreadUtils), _id(-1), _assetFd(nullptr), _playObj(nullptr), _playItf(nullptr), _seekItf(nullptr), _volumeItf(nullptr), - _volume(0.0f), _duration(0.0f), _isLoop(false), _state(State::INVALID), + _volume(0.0f), _duration(0.0f), _isLoop(false), _isAudioFocus(true), _state(State::INVALID), _playEventCallback(nullptr), _isDestroyed(std::make_shared(false)) { std::call_once(__onceFlag, [](){ @@ -215,16 +215,36 @@ void UrlAudioPlayer::play() } } -void UrlAudioPlayer::setVolume(float volume) +void UrlAudioPlayer::setVolumeToSLPlayer(float volume) { - _volume = volume; int dbVolume = 2000 * log10(volume); if (dbVolume < SL_MILLIBEL_MIN) { dbVolume = SL_MILLIBEL_MIN; } SLresult r = (*_volumeItf)->SetVolumeLevel(_volumeItf, dbVolume); - SL_RETURN_IF_FAILED(r, "UrlAudioPlayer::setVolume %d failed", dbVolume); + SL_RETURN_IF_FAILED(r, "UrlAudioPlayer::setVolumeToSLPlayer %d failed", dbVolume); +} + +void UrlAudioPlayer::setVolume(float volume) +{ + _volume = volume; + if (_isAudioFocus) + { + setVolumeToSLPlayer(_volume); + } +} + +float UrlAudioPlayer::getVolume() const +{ + return _volume; +} + +void UrlAudioPlayer::setAudioFocus(bool isFocus) +{ + _isAudioFocus = isFocus; + float volume = _isAudioFocus ? _volume : 0.0f; + setVolumeToSLPlayer(volume); } float UrlAudioPlayer::getDuration() const @@ -362,11 +382,6 @@ void UrlAudioPlayer::rewind() // Not supported currently. since cocos audio engine will new -> prepare -> play again. } -float UrlAudioPlayer::getVolume() const -{ - return _volume; -} - void UrlAudioPlayer::setLoop(bool isLoop) { _isLoop = isLoop; diff --git a/cocos/audio/android/UrlAudioPlayer.h b/cocos/audio/android/UrlAudioPlayer.h index 5e4dfa0b22..0ac1ca8907 100644 --- a/cocos/audio/android/UrlAudioPlayer.h +++ b/cocos/audio/android/UrlAudioPlayer.h @@ -68,6 +68,8 @@ public: virtual float getVolume() const override; + virtual void setAudioFocus(bool isFocus) override; + virtual void setLoop(bool isLoop) override; virtual bool isLoop() const override; @@ -97,6 +99,8 @@ private: void playEventCallback(SLPlayItf caller, SLuint32 playEvent); + void setVolumeToSLPlayer(float volume); + private: SLEngineItf _engineItf; SLObjectItf _outputMixObj; @@ -115,6 +119,7 @@ private: float _volume; float _duration; bool _isLoop; + bool _isAudioFocus; State _state; PlayEventCallback _playEventCallback; diff --git a/cocos/platform/android/java/src/org/cocos2dx/lib/Cocos2dxActivity.java b/cocos/platform/android/java/src/org/cocos2dx/lib/Cocos2dxActivity.java index b5ba68b505..69204c3c59 100644 --- a/cocos/platform/android/java/src/org/cocos2dx/lib/Cocos2dxActivity.java +++ b/cocos/platform/android/java/src/org/cocos2dx/lib/Cocos2dxActivity.java @@ -33,16 +33,13 @@ import android.media.AudioManager; import android.opengl.GLSurfaceView; import android.os.Build; import android.os.Bundle; -import android.os.Handler; import android.os.Message; import android.preference.PreferenceManager.OnActivityResultListener; -import android.util.AttributeSet; import android.util.Log; -import android.view.ViewGroup; import android.view.View; +import android.view.ViewGroup; import android.view.Window; import android.view.WindowManager; -import android.widget.FrameLayout; import org.cocos2dx.lib.Cocos2dxHelper.Cocos2dxHelperListener; @@ -74,7 +71,7 @@ public abstract class Cocos2dxActivity extends Activity implements Cocos2dxHelpe public Cocos2dxGLSurfaceView getGLSurfaceView(){ return mGLSurfaceView; } - + public static Context getContext() { return sContext; } @@ -135,12 +132,13 @@ public abstract class Cocos2dxActivity extends Activity implements Cocos2dxHelpe Window window = this.getWindow(); window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN); + // Audio configuration this.setVolumeControlStream(AudioManager.STREAM_MUSIC); } //native method,call GLViewImpl::getGLContextAttrs() to get the OpenGL ES context attributions private static native int[] getGLContextAttrs(); - + // =========================================================== // Getter & Setter // =========================================================== @@ -153,6 +151,7 @@ public abstract class Cocos2dxActivity extends Activity implements Cocos2dxHelpe protected void onResume() { Log.d(TAG, "onResume()"); super.onResume(); + Cocos2dxAudioFocusManager.registerAudioFocusListener(this); this.hideVirtualButton(); resumeIfHasFocus(); } @@ -178,12 +177,14 @@ public abstract class Cocos2dxActivity extends Activity implements Cocos2dxHelpe protected void onPause() { Log.d(TAG, "onPause()"); super.onPause(); + Cocos2dxAudioFocusManager.unregisterAudioFocusListener(this); Cocos2dxHelper.onPause(); mGLSurfaceView.onPause(); } @Override protected void onDestroy() { + Cocos2dxAudioFocusManager.unregisterAudioFocusListener(this); super.onDestroy(); } diff --git a/cocos/platform/android/java/src/org/cocos2dx/lib/Cocos2dxAudioFocusManager.java b/cocos/platform/android/java/src/org/cocos2dx/lib/Cocos2dxAudioFocusManager.java new file mode 100644 index 0000000000..253e1c7462 --- /dev/null +++ b/cocos/platform/android/java/src/org/cocos2dx/lib/Cocos2dxAudioFocusManager.java @@ -0,0 +1,131 @@ +/**************************************************************************** + * Copyright (c) 2017 Chukong Technologies Inc. + * + * http://www.cocos2d-x.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + ****************************************************************************/ + +package org.cocos2dx.lib; + +import android.content.Context; +import android.media.AudioManager; +import android.util.Log; + +class Cocos2dxAudioFocusManager { + + private final static String TAG = "AudioFocusManager"; + // Audio focus values synchronized with which in cocos/platform/android/javaactivity-android.cpp + private final static int AUDIOFOCUS_GAIN = 0; + private final static int AUDIOFOCUS_LOST = 1; + private final static int AUDIOFOCUS_LOST_TRANSIENT = 2; + private final static int AUDIOFOCUS_LOST_TRANSIENT_CAN_DUCK = 3; + + private static AudioManager.OnAudioFocusChangeListener sAfChangeListener = + new AudioManager.OnAudioFocusChangeListener() { + public void onAudioFocusChange(int focusChange) { + + Log.d(TAG, "onAudioFocusChange: " + focusChange + ", thread: " + Thread.currentThread().getName()); + + if (focusChange == AudioManager.AUDIOFOCUS_LOSS) { + // Permanent loss of audio focus + // Pause playback immediately + Log.d(TAG, "Pause music by AUDIOFOCUS_LOSS"); + Cocos2dxHelper.runOnGLThread(new Runnable() { + @Override + public void run() { + nativeOnAudioFocusChange(AUDIOFOCUS_LOST); + Cocos2dxHelper.setAudioFocus(false); + } + }); + + } else if (focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT) { + // Pause playback + Log.d(TAG, "Pause music by AUDIOFOCUS_LOSS_TRANSILENT"); + Cocos2dxHelper.runOnGLThread(new Runnable() { + @Override + public void run() { + nativeOnAudioFocusChange(AUDIOFOCUS_LOST_TRANSIENT); + Cocos2dxHelper.setAudioFocus(false); + } + }); + } else if (focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK) { + // Lower the volume, keep playing + Log.d(TAG, "Lower the volume, keep playing by AUDIOFOCUS_LOSS_TRANSILENT_CAN_DUCK"); + Cocos2dxHelper.runOnGLThread(new Runnable() { + @Override + public void run() { + nativeOnAudioFocusChange(AUDIOFOCUS_LOST_TRANSIENT_CAN_DUCK); + Cocos2dxHelper.setAudioFocus(false); + } + }); + } else if (focusChange == AudioManager.AUDIOFOCUS_GAIN) { + // Your app has been granted audio focus again + // Raise volume to normal, restart playback if necessary + Log.d(TAG, "Resume music by AUDIOFOCUS_GAIN"); + Cocos2dxHelper.runOnGLThread(new Runnable() { + @Override + public void run() { + nativeOnAudioFocusChange(AUDIOFOCUS_GAIN); + Cocos2dxHelper.setAudioFocus(true); + } + }); + } + } + }; + + static boolean registerAudioFocusListener(Context context) { + AudioManager am = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); + + // Request audio focus for playback + int result = am.requestAudioFocus(sAfChangeListener, + // Use the music stream. + AudioManager.STREAM_MUSIC, + // Request permanent focus. + AudioManager.AUDIOFOCUS_GAIN); + + if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) { + Log.d(TAG, "requestAudioFocus succeed"); + return true; + } + + Log.e(TAG, "requestAudioFocus failed!"); + return false; + } + + static void unregisterAudioFocusListener(Context context) { + AudioManager am = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); + int result = am.abandonAudioFocus(sAfChangeListener); + if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) { + Log.d(TAG, "abandonAudioFocus succeed!"); + } else { + Log.e(TAG, "abandonAudioFocus failed!"); + } + + Cocos2dxHelper.runOnGLThread(new Runnable() { + @Override + public void run() { + Cocos2dxHelper.setAudioFocus(true); + nativeOnAudioFocusChange(AUDIOFOCUS_GAIN); + } + }); + } + + private static native void nativeOnAudioFocusChange(int focusChange); +} diff --git a/cocos/platform/android/java/src/org/cocos2dx/lib/Cocos2dxHelper.java b/cocos/platform/android/java/src/org/cocos2dx/lib/Cocos2dxHelper.java index 6edb15d2c0..ac02517566 100644 --- a/cocos/platform/android/java/src/org/cocos2dx/lib/Cocos2dxHelper.java +++ b/cocos/platform/android/java/src/org/cocos2dx/lib/Cocos2dxHelper.java @@ -47,7 +47,6 @@ import android.util.DisplayMetrics; import android.util.Log; import android.view.Display; import android.view.WindowManager; -import android.hardware.SensorManager; import com.android.vending.expansion.zipfile.APKExpansionSupport; import com.android.vending.expansion.zipfile.ZipResourceFile; @@ -438,6 +437,11 @@ public class Cocos2dxHelper { Cocos2dxHelper.sCocos2dSound.stopAllEffects(); } + static void setAudioFocus(boolean isAudioFocus) { + sCocos2dMusic.setAudioFocus(isAudioFocus); + sCocos2dSound.setAudioFocus(isAudioFocus); + } + public static void end() { Cocos2dxHelper.sCocos2dMusic.end(); Cocos2dxHelper.sCocos2dSound.end(); diff --git a/cocos/platform/android/java/src/org/cocos2dx/lib/Cocos2dxMusic.java b/cocos/platform/android/java/src/org/cocos2dx/lib/Cocos2dxMusic.java index 5208cebbeb..2aeec41a67 100644 --- a/cocos/platform/android/java/src/org/cocos2dx/lib/Cocos2dxMusic.java +++ b/cocos/platform/android/java/src/org/cocos2dx/lib/Cocos2dxMusic.java @@ -51,6 +51,7 @@ public class Cocos2dxMusic { private boolean mPaused; // whether music is paused state. private boolean mIsLoop = false; private boolean mManualPaused = false; // whether music is paused manually before the program is switched to the background. + private boolean mIsAudioFocus = true; private String mCurrentPath; // =========================================================== @@ -226,7 +227,7 @@ public class Cocos2dxMusic { } this.mLeftVolume = this.mRightVolume = volume; - if (this.mBackgroundMediaPlayer != null) { + if (this.mBackgroundMediaPlayer != null && mIsAudioFocus) { this.mBackgroundMediaPlayer.setVolume(this.mLeftVolume, this.mRightVolume); } } @@ -298,6 +299,16 @@ public class Cocos2dxMusic { return mediaPlayer; } + void setAudioFocus(boolean isFocus) { + mIsAudioFocus = isFocus; + + if (mBackgroundMediaPlayer != null) { + float lVolume = mIsAudioFocus ? mLeftVolume : 0.0f; + float rVolume = mIsAudioFocus ? mRightVolume : 0.0f; + mBackgroundMediaPlayer.setVolume(lVolume, rVolume); + } + } + // =========================================================== // Inner and Anonymous Classes // =========================================================== diff --git a/cocos/platform/android/java/src/org/cocos2dx/lib/Cocos2dxSound.java b/cocos/platform/android/java/src/org/cocos2dx/lib/Cocos2dxSound.java index d4051570e2..bfb5973fcd 100644 --- a/cocos/platform/android/java/src/org/cocos2dx/lib/Cocos2dxSound.java +++ b/cocos/platform/android/java/src/org/cocos2dx/lib/Cocos2dxSound.java @@ -52,6 +52,7 @@ public class Cocos2dxSound { private SoundPool mSoundPool; private float mLeftVolume; private float mRightVolume; + private boolean mIsAudioFocus = true; // sound path and stream ids map // a file may be played many times at the same time @@ -255,6 +256,13 @@ public class Cocos2dxSound { this.mLeftVolume = this.mRightVolume = volume; + if (!mIsAudioFocus) + return; + + setEffectsVolumeInternal(mLeftVolume, mRightVolume); + } + + private void setEffectsVolumeInternal(float left, float right) { synchronized (mLockPathStreamIDsMap) { // change the volume of playing sounds if (!this.mPathStreamIDsMap.isEmpty()) { @@ -262,7 +270,7 @@ public class Cocos2dxSound { while (iter.hasNext()) { final Entry> entry = iter.next(); for (final int steamID : entry.getValue()) { - this.mSoundPool.setVolume(steamID, this.mLeftVolume, this.mRightVolume); + this.mSoundPool.setVolume(steamID, left, right); } } } @@ -346,6 +354,14 @@ public class Cocos2dxSound { this.mSoundPool.autoResume(); } + void setAudioFocus(boolean isFocus) { + mIsAudioFocus = isFocus; + float leftVolume = mIsAudioFocus ? mLeftVolume : 0.0f; + float rightVolume = mIsAudioFocus ? mRightVolume : 0.0f; + + setEffectsVolumeInternal(leftVolume, rightVolume); + } + // =========================================================== // Inner and Anonymous Classes // =========================================================== diff --git a/cocos/platform/android/javaactivity-android.cpp b/cocos/platform/android/javaactivity-android.cpp index 183879dbab..50f6d982c2 100644 --- a/cocos/platform/android/javaactivity-android.cpp +++ b/cocos/platform/android/javaactivity-android.cpp @@ -46,6 +46,8 @@ THE SOFTWARE. void cocos_android_app_init(JNIEnv* env) __attribute__((weak)); +void cocos_audioengine_focus_change(int focusChange); + using namespace cocos2d; extern "C" @@ -56,21 +58,20 @@ extern "C" #if __ANDROID_API__ > 19 #include #include - typedef __sighandler_t (*bsd_signal_func_t)(int, __sighandler_t); - bsd_signal_func_t bsd_signal_func = NULL; + typedef __sighandler_t (*bsd_signal_func_t)(int, __sighandler_t); + bsd_signal_func_t bsd_signal_func = NULL; - __sighandler_t bsd_signal(int s, __sighandler_t f) { - if (bsd_signal_func == NULL) { - // For now (up to Android 7.0) this is always available - bsd_signal_func = (bsd_signal_func_t) dlsym(RTLD_DEFAULT, "bsd_signal"); + __sighandler_t bsd_signal(int s, __sighandler_t f) { + if (bsd_signal_func == NULL) { + // For now (up to Android 7.0) this is always available + bsd_signal_func = (bsd_signal_func_t) dlsym(RTLD_DEFAULT, "bsd_signal"); - if (bsd_signal_func == NULL) { - __android_log_assert("", "bsd_signal_wrapper", "bsd_signal symbol not found!"); - } + if (bsd_signal_func == NULL) { + __android_log_assert("", "bsd_signal_wrapper", "bsd_signal symbol not found!"); + } + } + return bsd_signal_func(s, f); } - - return bsd_signal_func(s, f); - } #endif // __ANDROID_API__ > 19 JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *reserved) @@ -123,6 +124,11 @@ JNIEXPORT jintArray Java_org_cocos2dx_lib_Cocos2dxActivity_getGLContextAttrs(JNI return glContextAttrsJava; } +JNIEXPORT void Java_org_cocos2dx_lib_Cocos2dxAudioFocusManager_nativeOnAudioFocusChange(JNIEnv* env, jobject thiz, jint focusChange) +{ + cocos_audioengine_focus_change(focusChange); +} + JNIEXPORT void Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeOnSurfaceChanged(JNIEnv* env, jobject thiz, jint w, jint h) { cocos2d::Application::getInstance()->applicationScreenSizeChanged(w, h);