aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tools/android/packaging/xbmc/AndroidManifest.xml.in1
-rw-r--r--xbmc/android/activity/XBMCApp.cpp28
-rw-r--r--xbmc/android/activity/XBMCApp.h2
-rw-r--r--xbmc/android/jni/AudioManager.cpp14
-rw-r--r--xbmc/android/jni/AudioManager.h2
-rw-r--r--xbmc/android/jni/Intent.cpp7
-rw-r--r--xbmc/android/jni/Intent.h1
-rw-r--r--xbmc/cores/AudioEngine/Sinks/AESinkAUDIOTRACK.cpp27
-rw-r--r--xbmc/cores/AudioEngine/Sinks/AESinkAUDIOTRACK.h1
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;