aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorfelixpalmer <felixpalmer@gmail.com>2014-01-07 01:14:57 -0800
committerfelixpalmer <felixpalmer@gmail.com>2014-01-07 01:14:57 -0800
commit57e96262c3d8d33a0b2ec26189ea1f06e690f1c3 (patch)
treedf4caea3f75608320a2ef34d7f218d9547be016e
parent4054f8b6e2153b07c5af275372b9609d1019727a (diff)
parenta0227b318b91451daf3fd8d23fb1a5c44a4e187d (diff)
downloadandroid_external_android-visualizer-57e96262c3d8d33a0b2ec26189ea1f06e690f1c3.tar.gz
android_external_android-visualizer-57e96262c3d8d33a0b2ec26189ea1f06e690f1c3.tar.bz2
android_external_android-visualizer-57e96262c3d8d33a0b2ec26189ea1f06e690f1c3.zip
Merge pull request #6 from h6ah4i/feature/tunnel_player_workaroundmaster
Implement Tunnel Player workaround code
-rw-r--r--res/raw/workaround_1min.mp3bin0 -> 961305 bytes
-rw-r--r--src/com/pheelicks/app/MainActivity.java27
-rw-r--r--src/com/pheelicks/utils/SystemPropertiesProxy.java73
-rw-r--r--src/com/pheelicks/utils/TunnelPlayerWorkaround.java72
4 files changed, 172 insertions, 0 deletions
diff --git a/res/raw/workaround_1min.mp3 b/res/raw/workaround_1min.mp3
new file mode 100644
index 0000000..199d19c
--- /dev/null
+++ b/res/raw/workaround_1min.mp3
Binary files differ
diff --git a/src/com/pheelicks/app/MainActivity.java b/src/com/pheelicks/app/MainActivity.java
index 1b38f44..a2d52dd 100644
--- a/src/com/pheelicks/app/MainActivity.java
+++ b/src/com/pheelicks/app/MainActivity.java
@@ -17,6 +17,7 @@ import android.media.MediaPlayer;
import android.os.Bundle;
import android.view.View;
+import com.pheelicks.utils.TunnelPlayerWorkaround;
import com.pheelicks.visualizer.R;
import com.pheelicks.visualizer.VisualizerView;
import com.pheelicks.visualizer.renderer.BarGraphRenderer;
@@ -29,6 +30,7 @@ import com.pheelicks.visualizer.renderer.LineRenderer;
*/
public class MainActivity extends Activity {
private MediaPlayer mPlayer;
+ private MediaPlayer mSilentPlayer; /* to avoid tunnel player issue */
private VisualizerView mVisualizerView;
/** Called when the activity is first created. */
@@ -42,6 +44,7 @@ public class MainActivity extends Activity {
protected void onResume()
{
super.onResume();
+ initTunnelPlayerWorkaround();
init();
}
@@ -82,6 +85,30 @@ public class MainActivity extends Activity {
mPlayer.release();
mPlayer = null;
}
+
+ if (mSilentPlayer != null)
+ {
+ mSilentPlayer.release();
+ mSilentPlayer = null;
+ }
+ }
+
+ // Workaround (for Galaxy S4)
+ //
+ // "Visualization does not work on the new Galaxy devices"
+ // https://github.com/felixpalmer/android-visualizer/issues/5
+ //
+ // NOTE:
+ // This code is not required for visualizing default "test.mp3" file,
+ // because tunnel player is used when duration is longer than 1 minute.
+ // (default "test.mp3" file: 8 seconds)
+ //
+ private void initTunnelPlayerWorkaround() {
+ // Read "tunnel.decode" system property to determine
+ // the workaround is needed
+ if (TunnelPlayerWorkaround.isTunnelDecodeEnabled(this)) {
+ mSilentPlayer = TunnelPlayerWorkaround.createSilentMediaPlayer(this);
+ }
}
// Methods for adding renderers to visualizer
diff --git a/src/com/pheelicks/utils/SystemPropertiesProxy.java b/src/com/pheelicks/utils/SystemPropertiesProxy.java
new file mode 100644
index 0000000..6e49979
--- /dev/null
+++ b/src/com/pheelicks/utils/SystemPropertiesProxy.java
@@ -0,0 +1,73 @@
+/**
+ * Copyright 2013, Haruki Hasegawa
+ *
+ * Licensed under the MIT license:
+ * http://creativecommons.org/licenses/MIT/
+ */
+
+/**
+ * from http://stackoverflow.com/questions/2641111/where-is-android-os-systemproperties
+ */
+
+package com.pheelicks.utils;
+
+import java.lang.reflect.Method;
+
+import android.content.Context;
+import android.util.Log;
+
+public class SystemPropertiesProxy {
+ private static final String TAG = "SystemPropertiesProxy";
+
+ /**
+ * Get the value for the given key, returned as a boolean. Values 'n', 'no',
+ * '0', 'false' or 'off' are considered false. Values 'y', 'yes', '1', 'true'
+ * or 'on' are considered true. (case insensitive). If the key does not exist,
+ * or has any other value, then the default result is returned.
+ *
+ * @param key the key to lookup
+ * @param def a default value to return
+ * @return the key parsed as a boolean, or def if the key isn't found or is
+ * not able to be parsed as a boolean.
+ * @throws IllegalArgumentException if the key exceeds 32 characters
+ */
+ public static Boolean getBoolean(Context context, String key, boolean def)
+ throws IllegalArgumentException {
+ return getBoolean(context.getClassLoader(), key, def);
+ }
+
+ public static Boolean getBoolean(ClassLoader cl, String key, boolean def)
+ throws IllegalArgumentException {
+
+ Boolean ret = def;
+
+ try {
+ @SuppressWarnings("rawtypes")
+ Class SystemProperties = cl.loadClass("android.os.SystemProperties");
+
+ // Parameters Types
+ @SuppressWarnings("rawtypes")
+ Class[] paramTypes = new Class[2];
+ paramTypes[0] = String.class;
+ paramTypes[1] = boolean.class;
+
+ @SuppressWarnings("unchecked")
+ Method getBoolean = SystemProperties.getMethod("getBoolean", paramTypes);
+
+ // Parameters
+ Object[] params = new Object[2];
+ params[0] = new String(key);
+ params[1] = Boolean.valueOf(def);
+
+ ret = (Boolean) getBoolean.invoke(SystemProperties, params);
+
+ } catch (IllegalArgumentException iAE) {
+ throw iAE;
+ } catch (Exception e) {
+ Log.e(TAG, "getBoolean(context, key: " + key + ", def:" + def + ")", e);
+ ret = def;
+ }
+
+ return ret;
+ }
+}
diff --git a/src/com/pheelicks/utils/TunnelPlayerWorkaround.java b/src/com/pheelicks/utils/TunnelPlayerWorkaround.java
new file mode 100644
index 0000000..c25caf0
--- /dev/null
+++ b/src/com/pheelicks/utils/TunnelPlayerWorkaround.java
@@ -0,0 +1,72 @@
+/**
+ * Copyright 2013, Haruki Hasegawa
+ *
+ * Licensed under the MIT license:
+ * http://creativecommons.org/licenses/MIT/
+ */
+
+package com.pheelicks.utils;
+
+import java.io.IOException;
+
+import android.content.Context;
+import android.media.AudioManager;
+import android.media.MediaPlayer;
+import android.util.Log;
+
+import com.pheelicks.visualizer.R;
+
+public class TunnelPlayerWorkaround {
+ private static final String TAG = "TunnelPlayerWorkaround";
+
+ private static final String SYSTEM_PROP_TUNNEL_DECODE_ENABLED = "tunnel.decode";
+
+ private TunnelPlayerWorkaround()
+ {
+ }
+
+ /**
+ * Obtain "tunnel.decode" system property value
+ *
+ * @param context Context
+ * @return Whether tunnel player is enabled
+ */
+ public static boolean isTunnelDecodeEnabled(Context context)
+ {
+ return SystemPropertiesProxy.getBoolean(
+ context, SYSTEM_PROP_TUNNEL_DECODE_ENABLED, false);
+ }
+
+ /**
+ * Create silent MediaPlayer instance to avoid tunnel player issue
+ *
+ * @param context Context
+ * @return MediaPlayer instance
+ */
+ public static MediaPlayer createSilentMediaPlayer(Context context)
+ {
+ boolean result = false;
+
+ MediaPlayer mp = null;
+ try {
+ mp = MediaPlayer.create(context, R.raw.workaround_1min);
+ mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
+
+ // NOTE: start() is no needed
+ // mp.start();
+
+ result = true;
+ } catch (RuntimeException e) {
+ Log.e(TAG, "createSilentMediaPlayer()", e);
+ } finally {
+ if (!result && mp != null) {
+ try {
+ mp.release();
+ } catch (IllegalStateException e) {
+ }
+ }
+ }
+
+ return mp;
+ }
+}