diff options
-rw-r--r-- | tools/android/packaging/xbmc/AndroidManifest.xml.in | 1 | ||||
-rw-r--r-- | xbmc/android/activity/XBMCApp.cpp | 28 | ||||
-rw-r--r-- | xbmc/android/activity/XBMCApp.h | 2 | ||||
-rw-r--r-- | xbmc/android/jni/AudioManager.cpp | 14 | ||||
-rw-r--r-- | xbmc/android/jni/AudioManager.h | 2 | ||||
-rw-r--r-- | xbmc/android/jni/Intent.cpp | 7 | ||||
-rw-r--r-- | xbmc/android/jni/Intent.h | 1 | ||||
-rw-r--r-- | xbmc/cores/AudioEngine/Sinks/AESinkAUDIOTRACK.cpp | 27 | ||||
-rw-r--r-- | xbmc/cores/AudioEngine/Sinks/AESinkAUDIOTRACK.h | 1 |
9 files changed, 71 insertions, 12 deletions
diff --git a/tools/android/packaging/xbmc/AndroidManifest.xml.in b/tools/android/packaging/xbmc/AndroidManifest.xml.in index 16ca03e70a..e893188cb7 100644 --- a/tools/android/packaging/xbmc/AndroidManifest.xml.in +++ b/tools/android/packaging/xbmc/AndroidManifest.xml.in @@ -11,6 +11,7 @@ <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.WAKE_LOCK" /> <uses-permission android:name="android.permission.GET_TASKS" /> + <uses-permission android:name="android.permission.BLUETOOTH" /> <uses-feature android:name="android.hardware.screen.landscape" android:required="true" /> <uses-feature android:name="android.hardware.touchscreen" android:required="false" /> diff --git a/xbmc/android/activity/XBMCApp.cpp b/xbmc/android/activity/XBMCApp.cpp index e641d7a711..9d41bbe450 100644 --- a/xbmc/android/activity/XBMCApp.cpp +++ b/xbmc/android/activity/XBMCApp.cpp @@ -49,6 +49,7 @@ #include "AppParamParser.h" #include "XbmcContext.h" #include <android/bitmap.h> +#include "cores/AudioEngine/AEFactory.h" #include "android/jni/JNIThreading.h" #include "android/jni/BroadcastReceiver.h" #include "android/jni/Intent.h" @@ -99,6 +100,7 @@ CJNIWakeLock *CXBMCApp::m_wakeLock = NULL; ANativeWindow* CXBMCApp::m_window = NULL; int CXBMCApp::m_batteryLevel = 0; bool CXBMCApp::m_hasFocus = false; +bool CXBMCApp::m_headsetPlugged = false; CCriticalSection CXBMCApp::m_applicationsMutex; std::vector<androidPackage> CXBMCApp::m_applications; @@ -158,6 +160,8 @@ void CXBMCApp::onResume() intentFilter.addAction("android.intent.action.BATTERY_CHANGED"); intentFilter.addAction("android.intent.action.DREAMING_STOPPED"); intentFilter.addAction("android.intent.action.SCREEN_ON"); + intentFilter.addAction("android.intent.action.HEADSET_PLUG"); + intentFilter.addAction("android.bluetooth.a2dp.profile.action.CONNECTION_STATE_CHANGED"); registerReceiver(*this, intentFilter); if (!g_application.IsInScreenSaver()) @@ -165,6 +169,9 @@ void CXBMCApp::onResume() else g_application.WakeUpScreenSaverAndDPMS(); + CJNIAudioManager audioManager(getSystemService("audio")); + m_headsetPlugged = audioManager.isWiredHeadsetOn() || audioManager.isBluetoothA2dpOn(); + // Clear the applications cache. We could have installed/deinstalled apps { CSingleLock lock(m_applicationsMutex); @@ -351,6 +358,11 @@ bool CXBMCApp::HasFocus() return m_hasFocus; } +bool CXBMCApp::IsHeadsetPlugged() +{ + return m_headsetPlugged; +} + void CXBMCApp::run() { int status = 0; @@ -739,8 +751,24 @@ void CXBMCApp::onReceive(CJNIIntent intent) if (action == "android.intent.action.BATTERY_CHANGED") m_batteryLevel = intent.getIntExtra("level",-1); else if (action == "android.intent.action.DREAMING_STOPPED" || action == "android.intent.action.SCREEN_ON") + { if (HasFocus()) g_application.WakeUpScreenSaverAndDPMS(); + } + else if (action == "android.intent.action.HEADSET_PLUG" || action == "android.bluetooth.a2dp.profile.action.CONNECTION_STATE_CHANGED") + { + bool newstate; + if (action == "android.intent.action.HEADSET_PLUG") + newstate = (intent.getIntExtra("state", 0) != 0); + else + newstate = (intent.getIntExtra("android.bluetooth.profile.extra.STATE", 0) == 2 /* STATE_CONNECTED */); + + if (newstate != m_headsetPlugged) + { + m_headsetPlugged = newstate; + CAEFactory::DeviceChange(); + } + } } void CXBMCApp::onNewIntent(CJNIIntent intent) diff --git a/xbmc/android/activity/XBMCApp.h b/xbmc/android/activity/XBMCApp.h index 6f16ff739a..7e99b1de07 100644 --- a/xbmc/android/activity/XBMCApp.h +++ b/xbmc/android/activity/XBMCApp.h @@ -90,6 +90,7 @@ public: static int GetBatteryLevel(); static bool EnableWakeLock(bool on); static bool HasFocus(); + static bool IsHeadsetPlugged(); static bool StartActivity(const std::string &package, const std::string &intent = std::string(), const std::string &dataType = std::string(), const std::string &dataURI = std::string()); static std::vector <androidPackage> GetApplications(); @@ -138,6 +139,7 @@ private: static CJNIWakeLock *m_wakeLock; static int m_batteryLevel; static bool m_hasFocus; + static bool m_headsetPlugged; bool m_firstrun; bool m_exiting; pthread_t m_thread; diff --git a/xbmc/android/jni/AudioManager.cpp b/xbmc/android/jni/AudioManager.cpp index 42b0dc292e..3997520440 100644 --- a/xbmc/android/jni/AudioManager.cpp +++ b/xbmc/android/jni/AudioManager.cpp @@ -80,6 +80,20 @@ int CJNIAudioManager::abandonAudioFocus(const CJNIAudioManagerAudioFocusChangeLi "(Landroid/media/AudioManager$OnAudioFocusChangeListener;)I", listener.get_raw()); } +bool CJNIAudioManager::isBluetoothA2dpOn() +{ + return call_method<jboolean>(m_object, + "isBluetoothA2dpOn", + "()Z"); +} + +bool CJNIAudioManager::isWiredHeadsetOn() +{ + return call_method<jboolean>(m_object, + "isWiredHeadsetOn", + "()Z"); +} + ////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////// CJNIAudioManagerAudioFocusChangeListener* CJNIAudioManagerAudioFocusChangeListener::m_listenerInstance(NULL); diff --git a/xbmc/android/jni/AudioManager.h b/xbmc/android/jni/AudioManager.h index c02889fefd..85d7d104b1 100644 --- a/xbmc/android/jni/AudioManager.h +++ b/xbmc/android/jni/AudioManager.h @@ -51,6 +51,8 @@ public: int requestAudioFocus(const CJNIAudioManagerAudioFocusChangeListener &listener, int streamType, int durationHint); int abandonAudioFocus (const CJNIAudioManagerAudioFocusChangeListener &listener); + bool isBluetoothA2dpOn(); + bool isWiredHeadsetOn(); static void PopulateStaticFields(); static int STREAM_MUSIC; diff --git a/xbmc/android/jni/Intent.cpp b/xbmc/android/jni/Intent.cpp index b09b6c9d34..eb7eeec8d2 100644 --- a/xbmc/android/jni/Intent.cpp +++ b/xbmc/android/jni/Intent.cpp @@ -65,6 +65,13 @@ int CJNIIntent::getIntExtra(const std::string &name, int defaultValue) const jcast<jhstring>(name), defaultValue); } +std::string CJNIIntent::getStringExtra(const std::string &name) const +{ + return jcast<std::string>(call_method<jhstring>(m_object, + "getStringExtra", "(Ljava/lang/String;I)Ljava/lang/String;", + jcast<jhstring>(name))); +} + bool CJNIIntent::hasExtra(const std::string &name) const { return call_method<jboolean>(m_object, diff --git a/xbmc/android/jni/Intent.h b/xbmc/android/jni/Intent.h index a944b03248..c187642c88 100644 --- a/xbmc/android/jni/Intent.h +++ b/xbmc/android/jni/Intent.h @@ -35,6 +35,7 @@ public: std::string getType() const ; int getIntExtra(const std::string &name, int defaultValue) const; + std::string getStringExtra(const std::string &name) const; bool hasExtra(const std::string &name) const; bool hasCategory(const std::string &category) const; diff --git a/xbmc/cores/AudioEngine/Sinks/AESinkAUDIOTRACK.cpp b/xbmc/cores/AudioEngine/Sinks/AESinkAUDIOTRACK.cpp index e9b1b42533..6ed6b5dbf7 100644 --- a/xbmc/cores/AudioEngine/Sinks/AESinkAUDIOTRACK.cpp +++ b/xbmc/cores/AudioEngine/Sinks/AESinkAUDIOTRACK.cpp @@ -208,7 +208,6 @@ bool CAESinkAUDIOTRACK::IsSupported(int sampleRateInHz, int channelConfig, int e bool CAESinkAUDIOTRACK::Initialize(AEAudioFormat &format, std::string &device) { - m_lastFormat = format; m_format = format; m_volume = -1; @@ -388,7 +387,7 @@ void CAESinkAUDIOTRACK::EnumerateDevicesEx(AEDeviceInfoList &list, bool force) m_info.m_dataFormats.clear(); m_info.m_sampleRates.clear(); - m_info.m_deviceType = AE_DEVTYPE_HDMI; + m_info.m_deviceType = AE_DEVTYPE_PCM; m_info.m_deviceName = "AudioTrack"; m_info.m_displayName = "android"; m_info.m_displayNameExtra = "audiotrack"; @@ -400,19 +399,25 @@ void CAESinkAUDIOTRACK::EnumerateDevicesEx(AEDeviceInfoList &list, bool force) #else m_info.m_channels = KnownChannels; #endif - int test_sample[] = { 44100, 48000, 96000, 192000 }; - int test_sample_sz = sizeof(test_sample) / sizeof(int); - for (int i=0; i<test_sample_sz; ++i) + m_info.m_dataFormats.push_back(AE_FMT_S16LE); + m_info.m_sampleRates.push_back(CJNIAudioTrack::getNativeOutputSampleRate(CJNIAudioManager::STREAM_MUSIC)); + + if (!CXBMCApp::IsHeadsetPlugged()) { - if (IsSupported(test_sample[i], CJNIAudioFormat::CHANNEL_OUT_STEREO, CJNIAudioFormat::ENCODING_PCM_16BIT)) + m_info.m_deviceType = AE_DEVTYPE_HDMI; + int test_sample[] = { 44100, 48000, 96000, 192000 }; + int test_sample_sz = sizeof(test_sample) / sizeof(int); + for (int i=0; i<test_sample_sz; ++i) { - m_info.m_sampleRates.push_back(test_sample[i]); - CLog::Log(LOGDEBUG, "AESinkAUDIOTRACK - %d supported", test_sample[i]); + if (IsSupported(test_sample[i], CJNIAudioFormat::CHANNEL_OUT_STEREO, CJNIAudioFormat::ENCODING_PCM_16BIT)) + { + m_info.m_sampleRates.push_back(test_sample[i]); + CLog::Log(LOGDEBUG, "AESinkAUDIOTRACK - %d supported", test_sample[i]); + } } + m_info.m_dataFormats.push_back(AE_FMT_AC3); + m_info.m_dataFormats.push_back(AE_FMT_DTS); } - m_info.m_dataFormats.push_back(AE_FMT_S16LE); - m_info.m_dataFormats.push_back(AE_FMT_AC3); - m_info.m_dataFormats.push_back(AE_FMT_DTS); #if 0 //defined(__ARM_NEON__) if (g_cpuInfo.GetCPUFeatures() & CPU_FEATURE_NEON) m_info.m_dataFormats.push_back(AE_FMT_FLOAT); diff --git a/xbmc/cores/AudioEngine/Sinks/AESinkAUDIOTRACK.h b/xbmc/cores/AudioEngine/Sinks/AESinkAUDIOTRACK.h index 0b6f8f5f65..8927e707ff 100644 --- a/xbmc/cores/AudioEngine/Sinks/AESinkAUDIOTRACK.h +++ b/xbmc/cores/AudioEngine/Sinks/AESinkAUDIOTRACK.h @@ -59,7 +59,6 @@ private: static CAEDeviceInfo m_info; AEAudioFormat m_format; - AEAudioFormat m_lastFormat; double m_volume; volatile int m_min_frames; int16_t *m_alignedS16; |