From 38c830135f57354f7002da75aa29e2922c1d9dd1 Mon Sep 17 00:00:00 2001 From: kaytat Date: Fri, 16 Oct 2015 22:02:20 -0700 Subject: [PATCH] Initial commit --- .gitignore | 36 ++ SimpleProtocolPlayer.iml | 92 +++ build.gradle | 35 ++ gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 51010 bytes gradle/wrapper/gradle-wrapper.properties | 6 + gradlew | 164 ++++++ gradlew.bat | 90 +++ proguard-project.txt | 0 src/main/AndroidManifest.xml | 72 +++ src/main/AndroidManifest.xml~ | 72 +++ src/main/assets/notice.txt | 199 +++++++ .../AudioFocusHelper.java | 71 +++ .../simpleprotocolplayer/MainActivity.java | 459 +++++++++++++++ .../MediaButtonHelper.java | 85 +++ .../simpleprotocolplayer/MusicFocusable.java | 36 ++ .../MusicIntentReceiver.java | 55 ++ .../simpleprotocolplayer/MusicService.java | 529 ++++++++++++++++++ .../simpleprotocolplayer/NoticeActivity.java | 75 +++ .../RemoteControlClientCompat.java | 353 ++++++++++++ .../RemoteControlHelper.java | 87 +++ .../res/drawable-hdpi-v11/ic_stat_playing.png | Bin 0 -> 740 bytes .../res/drawable-hdpi-v9/ic_stat_playing.png | Bin 0 -> 834 bytes src/main/res/drawable-hdpi/eject.png | Bin 0 -> 4369 bytes src/main/res/drawable-hdpi/eject_pressed.png | Bin 0 -> 4503 bytes src/main/res/drawable-hdpi/ff.png | Bin 0 -> 4355 bytes src/main/res/drawable-hdpi/ff_pressed.png | Bin 0 -> 4493 bytes src/main/res/drawable-hdpi/ic_launcher.png | Bin 0 -> 4484 bytes .../res/drawable-hdpi/ic_stat_playing.png | Bin 0 -> 1149 bytes src/main/res/drawable-hdpi/pause.png | Bin 0 -> 4241 bytes src/main/res/drawable-hdpi/pause_pressed.png | Bin 0 -> 4459 bytes src/main/res/drawable-hdpi/play.png | Bin 0 -> 4373 bytes src/main/res/drawable-hdpi/play_pressed.png | Bin 0 -> 4578 bytes src/main/res/drawable-hdpi/rew.png | Bin 0 -> 4352 bytes src/main/res/drawable-hdpi/rew_pressed.png | Bin 0 -> 4490 bytes src/main/res/drawable-hdpi/stop.png | Bin 0 -> 4308 bytes src/main/res/drawable-hdpi/stop_pressed.png | Bin 0 -> 4520 bytes .../res/drawable-mdpi-v11/ic_stat_playing.png | Bin 0 -> 547 bytes .../res/drawable-mdpi-v9/ic_stat_playing.png | Bin 0 -> 548 bytes src/main/res/drawable-mdpi/ic_launcher.png | Bin 0 -> 2598 bytes .../res/drawable-mdpi/ic_stat_playing.png | Bin 0 -> 779 bytes .../res/drawable-nodpi/dummy_album_art.png | Bin 0 -> 9998 bytes .../drawable-xhdpi-v11/ic_stat_playing.png | Bin 0 -> 985 bytes .../res/drawable-xhdpi-v9/ic_stat_playing.png | Bin 0 -> 1114 bytes src/main/res/drawable-xhdpi/ic_launcher.png | Bin 0 -> 7240 bytes .../res/drawable-xhdpi/ic_stat_playing.png | Bin 0 -> 1720 bytes src/main/res/drawable/btn_eject.xml | 21 + src/main/res/drawable/btn_ff.xml | 21 + src/main/res/drawable/btn_pause.xml | 21 + src/main/res/drawable/btn_play.xml | 21 + src/main/res/drawable/btn_rew.xml | 21 + src/main/res/drawable/btn_stop.xml | 21 + src/main/res/layout-land/main.xml | 123 ++++ src/main/res/layout/main.xml | 193 +++++++ src/main/res/layout/notice.xml | 28 + src/main/res/menu/actions.xml | 4 + src/main/res/values-w820dp/dimens.xml | 10 + src/main/res/values/dimens.xml | 7 + src/main/res/values/strings.xml | 43 ++ 58 files changed, 3050 insertions(+) create mode 100644 .gitignore create mode 100644 SimpleProtocolPlayer.iml create mode 100644 build.gradle create mode 100644 gradle/wrapper/gradle-wrapper.jar create mode 100644 gradle/wrapper/gradle-wrapper.properties create mode 100755 gradlew create mode 100644 gradlew.bat create mode 100644 proguard-project.txt create mode 100644 src/main/AndroidManifest.xml create mode 100644 src/main/AndroidManifest.xml~ create mode 100644 src/main/assets/notice.txt create mode 100644 src/main/java/com/kaytat/simpleprotocolplayer/AudioFocusHelper.java create mode 100644 src/main/java/com/kaytat/simpleprotocolplayer/MainActivity.java create mode 100644 src/main/java/com/kaytat/simpleprotocolplayer/MediaButtonHelper.java create mode 100644 src/main/java/com/kaytat/simpleprotocolplayer/MusicFocusable.java create mode 100644 src/main/java/com/kaytat/simpleprotocolplayer/MusicIntentReceiver.java create mode 100644 src/main/java/com/kaytat/simpleprotocolplayer/MusicService.java create mode 100644 src/main/java/com/kaytat/simpleprotocolplayer/NoticeActivity.java create mode 100644 src/main/java/com/kaytat/simpleprotocolplayer/RemoteControlClientCompat.java create mode 100644 src/main/java/com/kaytat/simpleprotocolplayer/RemoteControlHelper.java create mode 100755 src/main/res/drawable-hdpi-v11/ic_stat_playing.png create mode 100755 src/main/res/drawable-hdpi-v9/ic_stat_playing.png create mode 100644 src/main/res/drawable-hdpi/eject.png create mode 100644 src/main/res/drawable-hdpi/eject_pressed.png create mode 100644 src/main/res/drawable-hdpi/ff.png create mode 100644 src/main/res/drawable-hdpi/ff_pressed.png create mode 100644 src/main/res/drawable-hdpi/ic_launcher.png create mode 100755 src/main/res/drawable-hdpi/ic_stat_playing.png create mode 100644 src/main/res/drawable-hdpi/pause.png create mode 100644 src/main/res/drawable-hdpi/pause_pressed.png create mode 100644 src/main/res/drawable-hdpi/play.png create mode 100644 src/main/res/drawable-hdpi/play_pressed.png create mode 100644 src/main/res/drawable-hdpi/rew.png create mode 100644 src/main/res/drawable-hdpi/rew_pressed.png create mode 100644 src/main/res/drawable-hdpi/stop.png create mode 100644 src/main/res/drawable-hdpi/stop_pressed.png create mode 100755 src/main/res/drawable-mdpi-v11/ic_stat_playing.png create mode 100755 src/main/res/drawable-mdpi-v9/ic_stat_playing.png create mode 100644 src/main/res/drawable-mdpi/ic_launcher.png create mode 100755 src/main/res/drawable-mdpi/ic_stat_playing.png create mode 100644 src/main/res/drawable-nodpi/dummy_album_art.png create mode 100755 src/main/res/drawable-xhdpi-v11/ic_stat_playing.png create mode 100755 src/main/res/drawable-xhdpi-v9/ic_stat_playing.png create mode 100644 src/main/res/drawable-xhdpi/ic_launcher.png create mode 100755 src/main/res/drawable-xhdpi/ic_stat_playing.png create mode 100644 src/main/res/drawable/btn_eject.xml create mode 100644 src/main/res/drawable/btn_ff.xml create mode 100644 src/main/res/drawable/btn_pause.xml create mode 100644 src/main/res/drawable/btn_play.xml create mode 100644 src/main/res/drawable/btn_rew.xml create mode 100644 src/main/res/drawable/btn_stop.xml create mode 100644 src/main/res/layout-land/main.xml create mode 100644 src/main/res/layout/main.xml create mode 100644 src/main/res/layout/notice.xml create mode 100644 src/main/res/menu/actions.xml create mode 100644 src/main/res/values-w820dp/dimens.xml create mode 100644 src/main/res/values/dimens.xml create mode 100644 src/main/res/values/strings.xml diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5ba0ff4 --- /dev/null +++ b/.gitignore @@ -0,0 +1,36 @@ +# Built application files +*.apk +*.ap_ + +# Files for the Dalvik VM +*.dex + +# Java class files +*.class + +# Generated files +bin/ +gen/ + +# Gradle files +.gradle/ +build/ +*/build/ + +# Local configuration file (sdk path, etc) +local.properties + +# Proguard folder generated by Eclipse +proguard/ + +# Log Files +*.log + +# Android Studio Navigation editor temp files +.navigation/ + +# Android Studio captures folder +captures/ + +.idea + diff --git a/SimpleProtocolPlayer.iml b/SimpleProtocolPlayer.iml new file mode 100644 index 0000000..8a56be3 --- /dev/null +++ b/SimpleProtocolPlayer.iml @@ -0,0 +1,92 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..216e827 --- /dev/null +++ b/build.gradle @@ -0,0 +1,35 @@ +apply plugin: 'com.android.application' +buildscript { + repositories { + jcenter() + } + dependencies { + classpath 'com.android.tools.build:gradle:1.1.0' + } +} +allprojects { + repositories { + jcenter() + } +} +apply plugin: 'com.android.application' +android { + compileSdkVersion 17 + buildToolsVersion "22.0.1" + defaultConfig { + applicationId "com.kaytat.simpleprotocolplayer" + minSdkVersion 14 + targetSdkVersion 17 + } + buildTypes { + release { + minifyEnabled true + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-project.txt' + } + } + productFlavors { + } +} + +dependencies { +} \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..2322723c7ed5f591adfa4c87b6c51932f591249a GIT binary patch literal 51010 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∓LFg$ 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 literal 0 HcmV?d00001 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..a6842ec --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Sun May 10 15:47:19 PDT 2015 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-2.2-bin.zip diff --git a/gradlew b/gradlew new file mode 100755 index 0000000..91a7e26 --- /dev/null +++ b/gradlew @@ -0,0 +1,164 @@ +#!/usr/bin/env bash + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn ( ) { + echo "$*" +} + +die ( ) { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; +esac + +# For Cygwin, ensure paths are in UNIX format before anything is touched. +if $cygwin ; then + [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` +fi + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >&- +APP_HOME="`pwd -P`" +cd "$SAVED" >&- + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules +function splitJvmOpts() { + JVM_OPTS=("$@") +} +eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS +JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" + +exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000..aec9973 --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,90 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windowz variants + +if not "%OS%" == "Windows_NT" goto win9xME_args +if "%@eval[2+2]" == "4" goto 4NT_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* +goto execute + +:4NT_args +@rem Get arguments from the 4NT Shell from JP Software +set CMD_LINE_ARGS=%$ + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/proguard-project.txt b/proguard-project.txt new file mode 100644 index 0000000..e69de29 diff --git a/src/main/AndroidManifest.xml b/src/main/AndroidManifest.xml new file mode 100644 index 0000000..9a31e1c --- /dev/null +++ b/src/main/AndroidManifest.xml @@ -0,0 +1,72 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/AndroidManifest.xml~ b/src/main/AndroidManifest.xml~ new file mode 100644 index 0000000..5320303 --- /dev/null +++ b/src/main/AndroidManifest.xml~ @@ -0,0 +1,72 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/assets/notice.txt b/src/main/assets/notice.txt new file mode 100644 index 0000000..011cf8c --- /dev/null +++ b/src/main/assets/notice.txt @@ -0,0 +1,199 @@ +------------------------------------------------------------ +This app uses samples from the Android SDK. + + + Copyright (c) 2005-2008, The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + +------------------------------------------------------------ +Icons + +http://www.flaticon.com - designed by Flaticon.com + diff --git a/src/main/java/com/kaytat/simpleprotocolplayer/AudioFocusHelper.java b/src/main/java/com/kaytat/simpleprotocolplayer/AudioFocusHelper.java new file mode 100644 index 0000000..8f31463 --- /dev/null +++ b/src/main/java/com/kaytat/simpleprotocolplayer/AudioFocusHelper.java @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * Copyright (C) 2014 kaytat + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.kaytat.simpleprotocolplayer; + +import android.content.Context; +import android.media.AudioManager; + +/** + * Convenience class to deal with audio focus. This class deals with everything related to audio + * focus: it can request and abandon focus, and will intercept focus change events and deliver + * them to a MusicFocusable interface (which, in our case, is implemented by {@link MusicService}). + * + * This class can only be used on SDK level 8 and above, since it uses API features that are not + * available on previous SDK's. + */ +public class AudioFocusHelper implements AudioManager.OnAudioFocusChangeListener { + AudioManager mAM; + MusicFocusable mFocusable; + + public AudioFocusHelper(Context ctx, MusicFocusable focusable) { + mAM = (AudioManager) ctx.getSystemService(Context.AUDIO_SERVICE); + mFocusable = focusable; + } + + /** Requests audio focus. Returns whether request was successful or not. */ + public boolean requestFocus() { + return AudioManager.AUDIOFOCUS_REQUEST_GRANTED == + mAM.requestAudioFocus(this, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN); + } + + /** Abandons audio focus. Returns whether request was successful or not. */ + public boolean abandonFocus() { + return AudioManager.AUDIOFOCUS_REQUEST_GRANTED == mAM.abandonAudioFocus(this); + } + + /** + * Called by AudioManager on audio focus changes. We implement this by calling our + * MusicFocusable appropriately to relay the message. + */ + public void onAudioFocusChange(int focusChange) { + if (mFocusable == null) return; + switch (focusChange) { + case AudioManager.AUDIOFOCUS_GAIN: + mFocusable.onGainedAudioFocus(); + break; + case AudioManager.AUDIOFOCUS_LOSS: + case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT: + mFocusable.onLostAudioFocus(false); + break; + case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK: + mFocusable.onLostAudioFocus(true); + break; + default: + } + } +} diff --git a/src/main/java/com/kaytat/simpleprotocolplayer/MainActivity.java b/src/main/java/com/kaytat/simpleprotocolplayer/MainActivity.java new file mode 100644 index 0000000..2ea159a --- /dev/null +++ b/src/main/java/com/kaytat/simpleprotocolplayer/MainActivity.java @@ -0,0 +1,459 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * Copyright (C) 2014 kaytat + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Code for NoFilter related from here: + * http://stackoverflow.com/questions/8512762/autocompletetextview-disable-filtering + */ + +package com.kaytat.simpleprotocolplayer; + +import android.app.Activity; +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.content.res.Resources; +import android.os.Bundle; +import android.util.Log; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.MotionEvent; +import android.view.View; +import android.view.View.OnClickListener; +import android.view.inputmethod.InputMethodManager; +import android.widget.ArrayAdapter; +import android.widget.AutoCompleteTextView; +import android.widget.Button; +import android.widget.EditText; +import android.widget.Filter; +import android.widget.Spinner; +import android.widget.TextView; +import android.widget.Toast; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.ArrayList; +import java.util.List; + +/** + * Main activity: shows media player buttons. This activity shows the media player buttons and + * lets the user click them. No media handling is done here -- everything is done by passing + * Intents to our {@link MusicService}. + * */ +public class MainActivity extends Activity implements OnClickListener { + private static final String TAG = "MainActivity"; + + AutoCompleteTextView mIPAddrText; + ArrayList mIPAddrList; + ArrayAdapter mIPAddrAdapter; + + AutoCompleteTextView mAudioPortText; + ArrayList mAudioPortList; + ArrayAdapter mAudioPortAdapter; + + int mSampleRate; + boolean mStereo; + int mBufferMs; + + Button mPlayButton; + Button mStopButton; + + /** + * Called when the activity is first created. Here, we simply set the event listeners and + * start the background service ({@link MusicService}) that will handle the actual media + * playback. + */ + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.main); + + mIPAddrText = (AutoCompleteTextView) findViewById(R.id.editTextIpAddr); + mAudioPortText = (AutoCompleteTextView) findViewById(R.id.editTextAudioPort); + mStopButton = (Button) findViewById(R.id.stopbutton); + mPlayButton = (Button) findViewById(R.id.playbutton); + mStopButton = (Button) findViewById(R.id.stopbutton); + + mPlayButton.setOnClickListener(this); + mStopButton.setOnClickListener(this); + + // Allow full list to be shown on first focus + mIPAddrText.setOnTouchListener(new View.OnTouchListener() { + @Override + public boolean onTouch(View v, MotionEvent event) { + mIPAddrText.showDropDown(); + return false; + } + }); + mIPAddrText.setOnFocusChangeListener(new View.OnFocusChangeListener() { + @Override + public void onFocusChange(View v, boolean hasFocus) { + if (hasFocus && mIPAddrText.getAdapter() != null) + mIPAddrText.showDropDown(); + + } + }); + mAudioPortText.setOnTouchListener(new View.OnTouchListener() { + @Override + public boolean onTouch(View v, MotionEvent event) { + mAudioPortText.showDropDown(); + return false; + } + }); + mAudioPortText.setOnFocusChangeListener(new View.OnFocusChangeListener() { + @Override + public void onFocusChange(View v, boolean hasFocus) { + if (hasFocus && mIPAddrText.getAdapter() != null) + mAudioPortText.showDropDown(); + + } + }); + } + + /* + The two different approaches here is an attempt to support both an old preferences + and new preferences. The newer version saved to JSON while the old version just saved + one string. + */ + static final String IP_PREF = "IP_PREF"; + static final String PORT_PREF = "PORT_PREF"; + + static final String IP_JSON_PREF = "IP_JSON_PREF"; + static final String PORT_JSON_PREF = "PORT_JSON_PREF"; + + static final String RATE_PREF = "RATE"; + static final String STEREO_PREF = "STEREO"; + static final String BUFFER_MS_PREF = "BUFFER_MS"; + + ArrayList getListFromPrefs( + SharedPreferences prefs, + String keyJson, + String keySingle) + { + // Retrieve the values from the shared preferences + String jsonString = prefs.getString(keyJson, null); + ArrayList arrayList = new ArrayList(); + + if (jsonString == null || jsonString.isEmpty()) + { + // Try to fill with the original key used + String single = prefs.getString(keySingle, null); + if (single != null && !single.isEmpty()) + { + arrayList.add(single); + } + } + else + { + try + { + JSONObject jsonObject = new JSONObject(jsonString); + + // Note that the array is hard-coded as the element labelled as 'list' + JSONArray jsonArray = jsonObject.getJSONArray("list"); + if (jsonArray != null) + { + for (int i = 0; i < jsonArray.length(); i++) + { + String s = (String)jsonArray.get(i); + if (s != null && !s.isEmpty()) + { + arrayList.add((String)s); + } + } + } + } + catch (JSONException jsonException) + { + Log.i(TAG, jsonException.toString()); + } + } + + return arrayList; + } + + private ArrayList getUpdatedArrayList( + SharedPreferences prefs, + AutoCompleteTextView view, + String keyJson, + String keySingle) { + // Retrieve the values from the shared preferences + ArrayList arrayList = getListFromPrefs( + prefs, + keyJson, + keySingle); + + // Make sure the most recent IP is on top + arrayList.remove(view.getText().toString()); + arrayList.add(0, view.getText().toString()); + + if (arrayList.size() >= 4) + { + arrayList.subList(4, arrayList.size()).clear(); + } + + return arrayList; + } + + private JSONObject getJson(ArrayList arrayList) + { + JSONArray jsonArray = new JSONArray(arrayList); + JSONObject jsonObject = new JSONObject(); + try + { + jsonObject.put("list", jsonArray); + } + catch (JSONException jsonException) + { + Log.i(TAG, jsonException.toString()); + } + + return jsonObject; + } + + private void savePrefs() + { + SharedPreferences myPrefs = this.getSharedPreferences("myPrefs", MODE_PRIVATE); + SharedPreferences.Editor prefsEditor = myPrefs.edit(); + + mIPAddrList = getUpdatedArrayList(myPrefs, mIPAddrText, IP_JSON_PREF, IP_PREF); + mAudioPortList = getUpdatedArrayList(myPrefs, mAudioPortText, PORT_JSON_PREF, PORT_PREF); + + // Write out JSON object + prefsEditor.putString(IP_JSON_PREF, getJson(mIPAddrList).toString()); + prefsEditor.putString(PORT_JSON_PREF, getJson(mAudioPortList).toString()); + + prefsEditor.putBoolean(STEREO_PREF, mStereo); + prefsEditor.putInt(RATE_PREF, mSampleRate); + prefsEditor.putInt(BUFFER_MS_PREF, mBufferMs); + prefsEditor.apply(); + + // Update adapters + mIPAddrAdapter.clear(); + mIPAddrAdapter.addAll(mIPAddrList); + mIPAddrAdapter.notifyDataSetChanged(); + mAudioPortAdapter.clear(); + mAudioPortAdapter.addAll(mAudioPortList); + mAudioPortAdapter.notifyDataSetChanged(); + } + + @Override + public void onPause() { + super.onPause(); + savePrefs(); + } + + private class NoFilterArrayAdapter + extends ArrayAdapter + { + private Filter filter = new NoFilter(); + public List items; + + @Override + public Filter getFilter() { + return filter; + } + + public NoFilterArrayAdapter(Context context, int textViewResourceId, + List objects) { + super(context, textViewResourceId, objects); + Log.v(TAG, "Adapter created " + filter); + items = objects; + } + + private class NoFilter extends Filter { + + @Override + protected android.widget.Filter.FilterResults performFiltering(CharSequence arg0) { + android.widget.Filter.FilterResults result = new android.widget.Filter.FilterResults(); + result.values = items; + result.count = items.size(); + return result; + } + + @Override + protected void publishResults(CharSequence arg0, android.widget.Filter.FilterResults arg1) { + notifyDataSetChanged(); + } + } + } + + @Override + public void onResume() + { + super.onResume(); + SharedPreferences myPrefs = this.getSharedPreferences("myPrefs", MODE_PRIVATE); + + mIPAddrList = getListFromPrefs(myPrefs, IP_JSON_PREF, IP_PREF); + mIPAddrAdapter = new NoFilterArrayAdapter(this, android.R.layout.simple_list_item_1, mIPAddrList); + mIPAddrText.setAdapter(mIPAddrAdapter); + mIPAddrText.setThreshold(1); + if (mIPAddrList.size() != 0) + { + mIPAddrText.setText((String)mIPAddrList.get(0)); + } + + mAudioPortList = getListFromPrefs(myPrefs, PORT_JSON_PREF, PORT_PREF); + mAudioPortAdapter = new NoFilterArrayAdapter(this, android.R.layout.simple_list_item_1, mAudioPortList); + mAudioPortText.setAdapter(mAudioPortAdapter); + mAudioPortText.setThreshold(1); + if (mAudioPortList.size() != 0) + { + mAudioPortText.setText((String)mAudioPortList.get(0)); + } + + // These hard-coded values should match the defaults in the strings array + Resources res = getResources(); + + mSampleRate = myPrefs.getInt(RATE_PREF, MusicService.DEFAULT_SAMPLE_RATE); + String rateString = Integer.toString(mSampleRate); + String[] sampleRateStrings = res.getStringArray(R.array.sampleRates); + for (int i = 0; i < sampleRateStrings.length; i++) { + if (sampleRateStrings[i].contains(rateString)) { + Spinner sampleRateSpinner = (Spinner) findViewById(R.id.spinnerSampleRate); + sampleRateSpinner.setSelection(i); + break; + } + } + + mStereo = myPrefs.getBoolean(STEREO_PREF, MusicService.DEFAULT_STEREO); + String[] stereoStrings = res.getStringArray(R.array.stereo); + Spinner stereoSpinner = (Spinner) findViewById(R.id.stereo); + String stereoKey = getResources().getString(R.string.stereoKey); + if (stereoStrings[0].contains(stereoKey) == mStereo) { + stereoSpinner.setSelection(0); + } else { + stereoSpinner.setSelection(1); + } + + mBufferMs = myPrefs.getInt(BUFFER_MS_PREF, 50); + Log.d(TAG, "mBufferMs:" + mBufferMs); + EditText e = (EditText)findViewById(R.id.editTextBufferSize); + e.setText(Integer.toString(mBufferMs)); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + // Inflate the menu items for use in the action bar + MenuInflater inflater = getMenuInflater(); + inflater.inflate(R.menu.actions, menu); + return super.onCreateOptionsMenu(menu); + } + + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case R.id.notice_item: + Intent intent = new Intent(this, NoticeActivity.class); + startActivity(intent); + return true; + + default: + return super.onOptionsItemSelected(item); + } + } + + public void onClick(View target) { + // Send the correct intent to the MusicService, according to the button that was clicked + if (target == mPlayButton) { + // Get the IP address and port and put it in the intent + Intent i = new Intent(MusicService.ACTION_PLAY); + String ipAddr = mIPAddrText.getText().toString(); + String portStr = mAudioPortText.getText().toString(); + if (ipAddr == null || ipAddr.equals("")) { + Toast.makeText(getApplicationContext(), "Invalid address", Toast.LENGTH_SHORT).show(); + return; + } + if (portStr == null || portStr.equals("")) { + Toast.makeText(getApplicationContext(), "Invalid port", Toast.LENGTH_SHORT).show(); + return; + } + i.putExtra(MusicService.DATA_IP_ADDRESS, ipAddr); + + int audioPort; + try { + audioPort = Integer.parseInt(portStr); + } catch (NumberFormatException nfe) { + Log.e(TAG, "Invalid port:" + nfe); + Toast.makeText(getApplicationContext(), "Invalid port", Toast.LENGTH_SHORT).show(); + return; + } + hideKb(); + i.putExtra(MusicService.DATA_AUDIO_PORT, audioPort); + + // Extract sample rate + Spinner sampleRateSpinner = (Spinner) findViewById(R.id.spinnerSampleRate); + try { + String rateStr = String.valueOf(sampleRateSpinner.getSelectedItem()); + String[] rateSplit = rateStr.split(" "); + if (rateSplit.length != 0) { + mSampleRate = Integer.parseInt(rateSplit[0]); + Log.i(TAG, "rate:" + mSampleRate); + i.putExtra(MusicService.DATA_SAMPLE_RATE, mSampleRate); + } + } + catch (Exception e) { + // Ignore parsing errors. The intent will have a default + } + + // Extract stereo/mono setting + Spinner stereoSpinner = (Spinner) findViewById(R.id.stereo); + try { + String stereoSettingString = String.valueOf(stereoSpinner.getSelectedItem()); + String[] stereoSplit = stereoSettingString.split(" "); + String stereoKey = getResources().getString(R.string.stereoKey); + if (stereoSplit.length != 0) { + mStereo = stereoSplit[0].contains(stereoKey); + Log.i(TAG, "stereo:" + mStereo); + i.putExtra(MusicService.DATA_STEREO, mStereo); + } + } + catch (Exception e) { + // Ignore parsing errors. The intent will have a default + } + + // Get the latest buffer entry + EditText e = (EditText)findViewById(R.id.editTextBufferSize); + String bufferMsString = e.getText().toString(); + if (bufferMsString == null || bufferMsString.isEmpty()) { + mBufferMs = 0; + } else { + mBufferMs = Integer.parseInt(bufferMsString); + } + i.putExtra(MusicService.DATA_BUFFER_MS, mBufferMs); + + // Save current settings + savePrefs(); + startService(i); + } + else if (target == mStopButton) { + hideKb(); + startService(new Intent(MusicService.ACTION_STOP)); + } + } + + private void hideKb() { + InputMethodManager inputManager = + (InputMethodManager)this.getSystemService(Context.INPUT_METHOD_SERVICE); + + View v = getCurrentFocus(); + if (v != null) { + inputManager.hideSoftInputFromWindow(v.getWindowToken(), + InputMethodManager.HIDE_NOT_ALWAYS); + } + } +} diff --git a/src/main/java/com/kaytat/simpleprotocolplayer/MediaButtonHelper.java b/src/main/java/com/kaytat/simpleprotocolplayer/MediaButtonHelper.java new file mode 100644 index 0000000..273571b --- /dev/null +++ b/src/main/java/com/kaytat/simpleprotocolplayer/MediaButtonHelper.java @@ -0,0 +1,85 @@ +package com.kaytat.simpleprotocolplayer; + +import android.content.ComponentName; +import android.media.AudioManager; +import android.util.Log; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +/** + * Class that assists with handling new media button APIs available in API level 8. + */ +public class MediaButtonHelper { + // Backwards compatibility code (methods available as of API Level 8) + private static final String TAG = "MediaButtonHelper"; + + static { + initializeStaticCompatMethods(); + } + + static Method sMethodRegisterMediaButtonEventReceiver; + static Method sMethodUnregisterMediaButtonEventReceiver; + + static void initializeStaticCompatMethods() { + try { + sMethodRegisterMediaButtonEventReceiver = AudioManager.class.getMethod( + "registerMediaButtonEventReceiver", + new Class[] { ComponentName.class }); + sMethodUnregisterMediaButtonEventReceiver = AudioManager.class.getMethod( + "unregisterMediaButtonEventReceiver", + new Class[] { ComponentName.class }); + } catch (NoSuchMethodException e) { + // Silently fail when running on an OS before API level 8. + } + } + + public static void registerMediaButtonEventReceiverCompat(AudioManager audioManager, + ComponentName receiver) { + if (sMethodRegisterMediaButtonEventReceiver == null) + return; + + try { + sMethodRegisterMediaButtonEventReceiver.invoke(audioManager, receiver); + } catch (InvocationTargetException e) { + // Unpack original exception when possible + Throwable cause = e.getCause(); + if (cause instanceof RuntimeException) { + throw (RuntimeException) cause; + } else if (cause instanceof Error) { + throw (Error) cause; + } else { + // Unexpected checked exception; wrap and re-throw + throw new RuntimeException(e); + } + } catch (IllegalAccessException e) { + Log.e(TAG, "IllegalAccessException invoking registerMediaButtonEventReceiver."); + e.printStackTrace(); + } + } + + @SuppressWarnings("unused") + public static void unregisterMediaButtonEventReceiverCompat(AudioManager audioManager, + ComponentName receiver) { + if (sMethodUnregisterMediaButtonEventReceiver == null) + return; + + try { + sMethodUnregisterMediaButtonEventReceiver.invoke(audioManager, receiver); + } catch (InvocationTargetException e) { + // Unpack original exception when possible + Throwable cause = e.getCause(); + if (cause instanceof RuntimeException) { + throw (RuntimeException) cause; + } else if (cause instanceof Error) { + throw (Error) cause; + } else { + // Unexpected checked exception; wrap and re-throw + throw new RuntimeException(e); + } + } catch (IllegalAccessException e) { + Log.e(TAG, "IllegalAccessException invoking unregisterMediaButtonEventReceiver."); + e.printStackTrace(); + } + } +} diff --git a/src/main/java/com/kaytat/simpleprotocolplayer/MusicFocusable.java b/src/main/java/com/kaytat/simpleprotocolplayer/MusicFocusable.java new file mode 100644 index 0000000..4744ea2 --- /dev/null +++ b/src/main/java/com/kaytat/simpleprotocolplayer/MusicFocusable.java @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * Copyright (C) 2014 kaytat + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.kaytat.simpleprotocolplayer; + +/** + * Represents something that can react to audio focus events. We implement this instead of just + * using AudioManager.OnAudioFocusChangeListener because that interface is only available in SDK + * level 8 and above, and we want our application to work on previous SDKs. + */ +public interface MusicFocusable { + /** Signals that audio focus was gained. */ + public void onGainedAudioFocus(); + + /** + * Signals that audio focus was lost. + * + * @param canDuck If true, audio can continue in "ducked" mode (low volume). Otherwise, all + * audio must stop. + */ + public void onLostAudioFocus(boolean canDuck); +} diff --git a/src/main/java/com/kaytat/simpleprotocolplayer/MusicIntentReceiver.java b/src/main/java/com/kaytat/simpleprotocolplayer/MusicIntentReceiver.java new file mode 100644 index 0000000..81ff974 --- /dev/null +++ b/src/main/java/com/kaytat/simpleprotocolplayer/MusicIntentReceiver.java @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * Copyright (C) 2014 kaytat + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.kaytat.simpleprotocolplayer; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.view.KeyEvent; +import android.util.Log; + +/** + * Receives broadcasted intents. In particular, we are interested in the + * android.media.AUDIO_BECOMING_NOISY and android.intent.action.MEDIA_BUTTON intents, which is + * broadcast, for example, when the user disconnects the headphones. This class works because we are + * declaring it in a <receiver> tag in AndroidManifest.xml. + */ +public class MusicIntentReceiver extends BroadcastReceiver { + static final String TAG = "MusicIntentReceiver"; + + @Override + public void onReceive(Context context, Intent intent) { + if (intent.getAction().equals(android.media.AudioManager.ACTION_AUDIO_BECOMING_NOISY)) { + Log.i(TAG, "onReceive - headphones disconnected. Stopping"); + // send an intent to our MusicService to telling it to pause the audio + context.startService(new Intent(MusicService.ACTION_STOP)); + + } else if (intent.getAction().equals(Intent.ACTION_MEDIA_BUTTON)) { + KeyEvent keyEvent = (KeyEvent) intent.getExtras().get(Intent.EXTRA_KEY_EVENT); + if (keyEvent.getAction() != KeyEvent.ACTION_DOWN) + return; + + switch (keyEvent.getKeyCode()) { + case KeyEvent.KEYCODE_MEDIA_STOP: + Log.i(TAG, "onReceive - media button stop"); + context.startService(new Intent(MusicService.ACTION_STOP)); + break; + } + } + } +} diff --git a/src/main/java/com/kaytat/simpleprotocolplayer/MusicService.java b/src/main/java/com/kaytat/simpleprotocolplayer/MusicService.java new file mode 100644 index 0000000..2353ed4 --- /dev/null +++ b/src/main/java/com/kaytat/simpleprotocolplayer/MusicService.java @@ -0,0 +1,529 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * Copyright (C) 2014 kaytat + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.kaytat.simpleprotocolplayer; + +import android.app.Notification; +import android.app.PendingIntent; +import android.app.Service; +import android.content.Context; +import android.content.Intent; +import android.media.AudioFormat; +import android.media.AudioManager; +import android.media.AudioTrack; +import android.net.wifi.WifiManager; +import android.net.wifi.WifiManager.WifiLock; +import android.os.Handler; +import android.os.IBinder; +import android.util.Log; +import android.widget.Toast; + +import java.io.DataInputStream; +import java.net.Socket; + +/** + * Service that handles media playback. This is the Service through which we perform all the media + * handling in our application. + */ +public class MusicService extends Service implements MusicFocusable { + + // The tag we put on debug messages + final static String TAG = "SimpleProtocol"; + + static final int DEFAULT_AUDIO_PORT = 12345; + static final int DEFAULT_SAMPLE_RATE = 44100; + static final boolean DEFAULT_STEREO = true; + static final int DEFAULT_BUFFER_MS = 50; + + // These are the Intent actions that we are prepared to handle. Notice that the fact these + // constants exist in our class is a mere convenience: what really defines the actions our + // service can handle are the tags in the tag for our service in + // AndroidManifest.xml. + public static final String ACTION_PLAY = "com.kaytat.simpleprotocolplayer.action.PLAY"; + public static final String ACTION_STOP = "com.kaytat.simpleprotocolplayer.action.STOP"; + + public static final String DATA_IP_ADDRESS = "ip_addr"; + public static final String DATA_AUDIO_PORT = "audio_port"; + public static final String DATA_SAMPLE_RATE = "sample_rate"; + public static final String DATA_STEREO = "stereo"; + public static final String DATA_BUFFER_MS = "buffer_ms"; + + // The volume we set the media player to when we lose audio focus, but are allowed to reduce + // the volume instead of stopping playback. + public static final float DUCK_VOLUME = 0.1f; + + // Media track + private AudioTrack mTrack = null; + private ThreadStoppable bufferToAudioTrackWorkerThread = null; + private ThreadStoppable networkReadWorkerThread = null; + + // our AudioFocusHelper object, if it's available (it's available on SDK level >= 8) + // If not available, this will be null. Always check for null before using! + AudioFocusHelper mAudioFocusHelper = null; + + // indicates the state our service: + enum State { + Stopped, // media player is stopped and not prepared to play + Playing // playback active (media player ready!) + } + + State mState = State.Stopped; + + // do we have audio focus? + // do we have audio focus? + enum AudioFocus { + NoFocusNoDuck, // we don't have audio focus, and can't duck + NoFocusCanDuck, // we don't have focus, but can play at a low volume ("ducking") + Focused // we have full audio focus + } + AudioFocus mAudioFocus = AudioFocus.NoFocusNoDuck; + + // Wifi lock that we hold when streaming files from the internet, in order to prevent the + // device from shutting off the Wifi radio + WifiLock mWifiLock; + + // The ID we use for the notification (the onscreen alert that appears at the notification + // area at the top of the screen as an icon -- and as text as well if the user expands the + // notification area). + final int NOTIFICATION_ID = 1; + + Notification mNotification = null; + + @Override + public void onCreate() { + Log.i(TAG, "Creating service"); + + // Create the Wifi lock (this does not acquire the lock, this just creates it) + mWifiLock = ((WifiManager) getSystemService(Context.WIFI_SERVICE)) + .createWifiLock(WifiManager.WIFI_MODE_FULL, "mylock"); + + // create the Audio Focus Helper, if the Audio Focus feature is available (SDK 8 or above) + if (android.os.Build.VERSION.SDK_INT >= 8) + mAudioFocusHelper = new AudioFocusHelper(getApplicationContext(), this); + else + mAudioFocus = AudioFocus.Focused; // no focus feature, so we always "have" audio focus + } + + /** + * Called when we receive an Intent. When we receive an intent sent to us via startService(), + * this is the method that gets called. So here we react appropriately depending on the + * Intent's action, which specifies what is being requested of us. + */ + @Override + public int onStartCommand(Intent intent, int flags, int startId) { + String action = intent.getAction(); + if (action.equals(ACTION_PLAY)) { + processPlayRequest(intent); + } + else if (action.equals(ACTION_STOP)) { + processStopRequest(); + } + + return START_NOT_STICKY; // Means we started the service, but don't want it to + // restart in case it's killed. + } + + void processPlayRequest(Intent i) { + if (mState == State.Stopped) { + tryToGetAudioFocus(); + playStream( + i.getStringExtra(DATA_IP_ADDRESS), + i.getIntExtra(DATA_AUDIO_PORT, DEFAULT_AUDIO_PORT), + i.getIntExtra(DATA_SAMPLE_RATE, DEFAULT_SAMPLE_RATE), + i.getBooleanExtra(DATA_STEREO, DEFAULT_STEREO), + i.getIntExtra(DATA_BUFFER_MS, DEFAULT_BUFFER_MS)); + } + } + + void processStopRequest() { + if (mState == State.Playing) { + mState = State.Stopped; + + // let go of all resources... + relaxResources(); + giveUpAudioFocus(); + + // service is no longer necessary. Will be started again if needed. + stopSelf(); + } + } + + void stopAndInterrupt(ThreadStoppable t) { + if (t != null) { + try { + t.customStop(); + t.interrupt(); + + // Do not join since this can take some time. The + // workers should be able to shutdown independently. + // t.join(); + } + catch (Exception e) { + Log.e(TAG, "join exception:" + e); + } + } + } + + /** + * Releases resources used by the service for playback. This includes the "foreground service" + * status and notification, the wake locks and the AudioTrack + */ + void relaxResources() { + // stop being a foreground service + stopForeground(true); + + // we can also release the Wifi lock, if we're holding it + if (mWifiLock.isHeld()) mWifiLock.release(); + + // Wait for worker thread to stop if running + stopAndInterrupt(bufferToAudioTrackWorkerThread); + stopAndInterrupt(networkReadWorkerThread); + + // Make sure to release any resources + if (mTrack != null) { + mTrack = null; + } + } + + void tryToGetAudioFocus() { + if (mAudioFocus != AudioFocus.Focused && mAudioFocusHelper != null + && mAudioFocusHelper.requestFocus()) + mAudioFocus = AudioFocus.Focused; + } + + void giveUpAudioFocus() { + if (mAudioFocus == AudioFocus.Focused && mAudioFocusHelper != null + && mAudioFocusHelper.abandonFocus()) + mAudioFocus = AudioFocus.NoFocusNoDuck; + } + + /** + * Reconfigures AudioTrack according to audio focus settings and starts/restarts it. + */ + void configVolume() { + if (mAudioFocus == AudioFocus.NoFocusNoDuck) { + // If we don't have audio focus and can't duck, we have to pause, even if mState + // is State.Playing. But we stay in the Playing state so that we know we have to resume + // playback once we get the focus back. + if (mState == State.Playing) { + processStopRequest(); + } + } + + else if (mAudioFocus == AudioFocus.NoFocusCanDuck) { + mTrack.setStereoVolume(DUCK_VOLUME, DUCK_VOLUME); // we'll be relatively quiet + } + else { + mTrack.setStereoVolume(1.0f, 1.0f); // we can be loud + } + } + + static private final int NUM_PKTS = 3; + + // The amount of data to read from the network before sending to AudioTrack + private int packet_size; + private final Object filledLock = new Object(); + private int filled = 0; + private byte[][] byteArray = new byte[NUM_PKTS][]; + + void initNetworkData( + int sample_rate, + boolean stereo, + int minBuf, + int buffer_ms) { + + // Assume 16 bits per sample + int bytesPerSecond = sample_rate * 2; + if (stereo) { + bytesPerSecond *= 2; + } + + packet_size = (bytesPerSecond * buffer_ms) / 1000; + if ((packet_size & 1) != 0) { + packet_size++; + } + + Log.d(TAG, "initNetworkData:bytes / second:" + (bytesPerSecond)); + Log.d(TAG, "initNetworkData:minBuf:" + minBuf); + Log.d(TAG, "initNetworkData:packet_size:" + packet_size); + + for (int i = 0; i < NUM_PKTS; i++) { + byteArray[i] = new byte[packet_size]; + } + } + + private class ThreadStoppable extends Thread { + boolean running = true; + public void customStop() { + running = false; + } + } + + /** + * Worker thread that takes data from the buffer and sends it to audio track + */ + private class BufferToAudioTrackThread extends ThreadStoppable { + static final String TAG = "BTATThread"; + + private AudioTrack mTrack; + + public BufferToAudioTrackThread(AudioTrack track) { + mTrack = track; + } + + @Override + public void run() { + Log.i(TAG, "start"); + + mTrack.play(); + + try { + int idx = 0; + while (running) { + synchronized (filledLock) { + while (filled == 0) { + filledLock.wait(); + if (!running) { + throw new Exception("Not running"); + } + } + } + + mTrack.write(byteArray[idx], 0, packet_size); + idx++; + if (idx == NUM_PKTS) { + idx = 0; + } + synchronized (filledLock) { + filled--; + filledLock.notifyAll(); + } + } + } + catch (Exception e) { + Log.e(TAG, "exception:" + e); + } + + // Do some cleanup + mTrack.stop(); + mTrack.release(); + mTrack = null; + Log.i(TAG, "done"); + } + } + + /** + * Worker thread reads data from the network + */ + private class NetworkReadThread extends ThreadStoppable { + static final String TAG = "NRThread"; + + Context context; + String ipAddr; + int port; + Socket socket; + + // socket timeout at 5 seconds + static final int SOCKET_TIMEOUT = 5 * 1000; + + public NetworkReadThread(Context context, String ipAddr, int port) { + this.context = context; + this.ipAddr = ipAddr; + this.port = port; + } + + @Override + public void run() { + Log.i(TAG, "start"); + + byte[] tmpBuf = new byte[packet_size]; + try { + // Create the TCP socket and setup some parameters + socket = new Socket(ipAddr, port); + DataInputStream is = new DataInputStream( + socket.getInputStream()); + try { + socket.setSoTimeout(SOCKET_TIMEOUT); + socket.setTcpNoDelay(true); + } catch (Exception e) { + Log.i(TAG, "exception:" + e); + return; + } + + Log.i(TAG, "running"); + int idx = 0; + + while (running) { + synchronized (filledLock) { + while (filled == NUM_PKTS) { + filledLock.wait(); + if (!running) { + throw new Exception("Not running"); + } + } + } + + // Get a packet + is.readFully(byteArray[idx]); + idx++; + if (idx == NUM_PKTS) { + idx = 0; + } + synchronized (filledLock) { + filled++; + if (filled == NUM_PKTS) { + Log.i(TAG, "flushing"); + // Filled up. Throw away everything that's in the network queue. + int rd; + do { + rd = is.read(tmpBuf); + } while (rd == packet_size && running); + } + filledLock.notifyAll(); + } + } + } + catch (Exception e) { + Log.i(TAG, "exception:" + e); + } + + try { + if (socket != null) { + socket.close(); + } + if (running) { + // Broke out of loop unexpectedly. Shutdown. + Handler h = new Handler(context.getMainLooper()); + Runnable r = new Runnable() { + @Override + public void run() { + Toast.makeText(getApplicationContext(), "Unable to stream", Toast.LENGTH_SHORT).show(); + processStopRequest(); + } + }; + h.post(r); + } + } + catch (Exception e) { + Log.i(TAG, "exception while closing:" + e); + } + + Log.i(TAG, "done"); + } + } + + /** + * Play the stream using the given IP address and port + */ + void playStream(String serverAddr, + int serverPort, + int sample_rate, + boolean stereo, + int buffer_ms) { + int format = stereo ? + AudioFormat.CHANNEL_OUT_STEREO : + AudioFormat.CHANNEL_OUT_MONO; + + // Sanitize input, just in case + if (sample_rate <= 0) { + sample_rate = DEFAULT_SAMPLE_RATE; + } + + if (buffer_ms <= 5) { + buffer_ms = DEFAULT_BUFFER_MS; + } + + int minBuf = AudioTrack.getMinBufferSize( + sample_rate, + format, + AudioFormat.ENCODING_PCM_16BIT); + + initNetworkData(sample_rate, stereo, minBuf, buffer_ms); + + mState = State.Stopped; + relaxResources(); + filled = 0; + + // The agreement here is that mTrack will be shutdown by the helper + mTrack = new AudioTrack(AudioManager.STREAM_MUSIC, + sample_rate, format, + AudioFormat.ENCODING_PCM_16BIT, minBuf, + AudioTrack.MODE_STREAM); + + bufferToAudioTrackWorkerThread = new BufferToAudioTrackThread(mTrack); + networkReadWorkerThread = new NetworkReadThread(this, serverAddr, serverPort); + + bufferToAudioTrackWorkerThread.start(); + networkReadWorkerThread.start(); + + mState = State.Playing; + configVolume(); + + setUpAsForeground("Streaming from " + serverAddr); + } + + /** + * Configures service as a foreground service. A foreground service is a service that's doing + * something the user is actively aware of (such as playing music), and must appear to the + * user as a notification. That's why we create the notification here. + */ + void setUpAsForeground(String text) { + PendingIntent pi = PendingIntent.getActivity(getApplicationContext(), 0, + new Intent(getApplicationContext(), MainActivity.class), + PendingIntent.FLAG_UPDATE_CURRENT); + mNotification = new Notification(); + mNotification.tickerText = text; + mNotification.icon = R.drawable.ic_stat_playing; + mNotification.flags |= Notification.FLAG_ONGOING_EVENT; + mNotification.setLatestEventInfo(getApplicationContext(), "SimpleProtocolPlayer", + text, pi); + startForeground(NOTIFICATION_ID, mNotification); + } + + @Override + public void onGainedAudioFocus() { + Log.i(TAG, "Gained audio focus"); + mAudioFocus = AudioFocus.Focused; + + // restart media player with new focus settings + if (mState == State.Playing) + configVolume(); + } + + @Override + public void onLostAudioFocus(boolean canDuck) { + Log.i(TAG, "Lost audio focus: canDuck:" + canDuck); + mAudioFocus = canDuck ? AudioFocus.NoFocusCanDuck : AudioFocus.NoFocusNoDuck; + + // start/restart/pause media player with new focus settings + if (mState == State.Playing) + configVolume(); + } + + @Override + public void onDestroy() { + // Service is being killed, so make sure we release our resources + mState = State.Stopped; + relaxResources(); + giveUpAudioFocus(); + } + + @Override + public IBinder onBind(Intent arg0) { + return null; + } +} diff --git a/src/main/java/com/kaytat/simpleprotocolplayer/NoticeActivity.java b/src/main/java/com/kaytat/simpleprotocolplayer/NoticeActivity.java new file mode 100644 index 0000000..600cb9c --- /dev/null +++ b/src/main/java/com/kaytat/simpleprotocolplayer/NoticeActivity.java @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * Copyright (C) 2014 kaytat + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.kaytat.simpleprotocolplayer; + +import android.app.Activity; +import android.os.Bundle; +import android.util.Log; +import android.widget.TextView; + +import java.io.InputStream; +import java.io.IOException; + +public class NoticeActivity extends Activity +{ + static final String TAG = "NoticeActivity"; + + /** + * Initialization of the Activity after it is first created. Must at least + * call {@link android.app.Activity#setContentView setContentView()} to + * describe what is to be displayed in the screen. + */ + @Override + protected void onCreate(Bundle savedInstanceState) + { + super.onCreate(savedInstanceState); + + // See assets/res/any/layout/styled_text.xml for this + // view layout definition. + setContentView(R.layout.notice); + + // Programmatically load text from an asset and place it into the + // text view. Note that the text we are loading is ASCII, so we + // need to convert it to UTF-16. + try { + InputStream is = getAssets().open("notice.txt"); + + // We guarantee that the available method returns the total + // size of the asset... of course, this does mean that a single + // asset can't be more than 2 gigs. + int size = is.available(); + + // Read the entire asset into a local byte buffer. + byte[] buffer = new byte[size]; + int readBytes = is.read(buffer); + is.close(); + + // Finally stick the string into the text view. + TextView tv = (TextView)findViewById(R.id.notice_view); + if (readBytes != 0) { + tv.setText(new String(buffer)); + } + else { + tv.setText("Error"); + } + } catch (IOException e) { + // Should never happen! + Log.e(TAG, "exception:" + e); + } + } +} diff --git a/src/main/java/com/kaytat/simpleprotocolplayer/RemoteControlClientCompat.java b/src/main/java/com/kaytat/simpleprotocolplayer/RemoteControlClientCompat.java new file mode 100644 index 0000000..52ca041 --- /dev/null +++ b/src/main/java/com/kaytat/simpleprotocolplayer/RemoteControlClientCompat.java @@ -0,0 +1,353 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.kaytat.simpleprotocolplayer; + +import android.app.PendingIntent; +import android.graphics.Bitmap; +import android.os.Looper; +import android.util.Log; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; + +/** + * RemoteControlClient enables exposing information meant to be consumed by remote controls capable + * of displaying metadata, artwork and media transport control buttons. A remote control client + * object is associated with a media button event receiver. This event receiver must have been + * previously registered with + * {@link android.media.AudioManager#registerMediaButtonEventReceiver(android.content.ComponentName)} + * before the RemoteControlClient can be registered through + * {@link android.media.AudioManager#registerRemoteControlClient(android.media.RemoteControlClient)}. + */ +@SuppressWarnings({"rawtypes", "unchecked"}) +public class RemoteControlClientCompat { + + private static final String TAG = "RemoteControlCompat"; + + private static Class sRemoteControlClientClass; + + // RCC short for RemoteControlClient + private static Method sRCCEditMetadataMethod; + private static Method sRCCSetPlayStateMethod; + private static Method sRCCSetTransportControlFlags; + + private static boolean sHasRemoteControlAPIs = false; + + static { + try { + ClassLoader classLoader = RemoteControlClientCompat.class.getClassLoader(); + sRemoteControlClientClass = getActualRemoteControlClientClass(classLoader); + // dynamically populate the playstate and flag values in case they change + // in future versions. + for (Field field : RemoteControlClientCompat.class.getFields()) { + try { + Field realField = sRemoteControlClientClass.getField(field.getName()); + Object realValue = realField.get(null); + field.set(null, realValue); + } catch (NoSuchFieldException e) { + Log.w(TAG, "Could not get real field: " + field.getName()); + } catch (IllegalArgumentException e) { + Log.w(TAG, "Error trying to pull field value for: " + field.getName() + + " " + e.getMessage()); + } catch (IllegalAccessException e) { + Log.w(TAG, "Error trying to pull field value for: " + field.getName() + + " " + e.getMessage()); + } + } + + // get the required public methods on RemoteControlClient + sRCCEditMetadataMethod = sRemoteControlClientClass.getMethod("editMetadata", + boolean.class); + sRCCSetPlayStateMethod = sRemoteControlClientClass.getMethod("setPlaybackState", + int.class); + sRCCSetTransportControlFlags = sRemoteControlClientClass.getMethod( + "setTransportControlFlags", int.class); + + sHasRemoteControlAPIs = true; + } catch (ClassNotFoundException e) { + // Silently fail when running on an OS before ICS. + } catch (NoSuchMethodException e) { + // Silently fail when running on an OS before ICS. + } catch (IllegalArgumentException e) { + // Silently fail when running on an OS before ICS. + } catch (SecurityException e) { + // Silently fail when running on an OS before ICS. + } + } + + public static Class getActualRemoteControlClientClass(ClassLoader classLoader) + throws ClassNotFoundException { + return classLoader.loadClass("android.media.RemoteControlClient"); + } + + private Object mActualRemoteControlClient; + + public RemoteControlClientCompat(PendingIntent pendingIntent) { + if (!sHasRemoteControlAPIs) { + return; + } + try { + mActualRemoteControlClient = + sRemoteControlClientClass.getConstructor(PendingIntent.class) + .newInstance(pendingIntent); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + public RemoteControlClientCompat(PendingIntent pendingIntent, Looper looper) { + if (!sHasRemoteControlAPIs) { + return; + } + + try { + mActualRemoteControlClient = + sRemoteControlClientClass.getConstructor(PendingIntent.class, Looper.class) + .newInstance(pendingIntent, looper); + } catch (Exception e) { + Log.e(TAG, "Error creating new instance of " + sRemoteControlClientClass.getName(), e); + } + } + + /** + * Class used to modify metadata in a {@link android.media.RemoteControlClient} object. Use + * {@link android.media.RemoteControlClient#editMetadata(boolean)} to create an instance of an + * editor, on which you set the metadata for the RemoteControlClient instance. Once all the + * information has been set, use {@link #apply()} to make it the new metadata that should be + * displayed for the associated client. Once the metadata has been "applied", you cannot reuse + * this instance of the MetadataEditor. + */ + public class MetadataEditorCompat { + + private Method mPutStringMethod; + private Method mPutBitmapMethod; + private Method mPutLongMethod; + private Method mClearMethod; + private Method mApplyMethod; + + private Object mActualMetadataEditor; + + /** + * The metadata key for the content artwork / album art. + */ + public final static int METADATA_KEY_ARTWORK = 100; + + private MetadataEditorCompat(Object actualMetadataEditor) { + if (sHasRemoteControlAPIs && actualMetadataEditor == null) { + throw new IllegalArgumentException("Remote Control API's exist, " + + "should not be given a null MetadataEditor"); + } + if (sHasRemoteControlAPIs) { + Class metadataEditorClass = actualMetadataEditor.getClass(); + + try { + mPutStringMethod = metadataEditorClass.getMethod("putString", + int.class, String.class); + mPutBitmapMethod = metadataEditorClass.getMethod("putBitmap", + int.class, Bitmap.class); + mPutLongMethod = metadataEditorClass.getMethod("putLong", + int.class, long.class); + mClearMethod = metadataEditorClass.getMethod("clear", new Class[]{}); + mApplyMethod = metadataEditorClass.getMethod("apply", new Class[]{}); + } catch (Exception e) { + throw new RuntimeException(e.getMessage(), e); + } + } + mActualMetadataEditor = actualMetadataEditor; + } + + /** + * Adds textual information to be displayed. + * Note that none of the information added after {@link #apply()} has been called, + * will be displayed. + * @param key The identifier of a the metadata field to set. Valid values are + * {@link android.media.MediaMetadataRetriever#METADATA_KEY_ALBUM}, + * {@link android.media.MediaMetadataRetriever#METADATA_KEY_ALBUMARTIST}, + * {@link android.media.MediaMetadataRetriever#METADATA_KEY_TITLE}, + * {@link android.media.MediaMetadataRetriever#METADATA_KEY_ARTIST}, + * {@link android.media.MediaMetadataRetriever#METADATA_KEY_AUTHOR}, + * {@link android.media.MediaMetadataRetriever#METADATA_KEY_COMPILATION}, + * {@link android.media.MediaMetadataRetriever#METADATA_KEY_COMPOSER}, + * {@link android.media.MediaMetadataRetriever#METADATA_KEY_DATE}, + * {@link android.media.MediaMetadataRetriever#METADATA_KEY_GENRE}, + * {@link android.media.MediaMetadataRetriever#METADATA_KEY_TITLE}, + * {@link android.media.MediaMetadataRetriever#METADATA_KEY_WRITER}. + * @param value The text for the given key, or {@code null} to signify there is no valid + * information for the field. + * @return Returns a reference to the same MetadataEditor object, so you can chain put + * calls together. + */ + public MetadataEditorCompat putString(int key, String value) { + if (sHasRemoteControlAPIs) { + try { + mPutStringMethod.invoke(mActualMetadataEditor, key, value); + } catch (Exception e) { + throw new RuntimeException(e.getMessage(), e); + } + } + return this; + } + + /** + * Sets the album / artwork picture to be displayed on the remote control. + * @param key the identifier of the bitmap to set. The only valid value is + * {@link #METADATA_KEY_ARTWORK} + * @param bitmap The bitmap for the artwork, or null if there isn't any. + * @return Returns a reference to the same MetadataEditor object, so you can chain put + * calls together. + * @throws IllegalArgumentException + * @see android.graphics.Bitmap + */ + public MetadataEditorCompat putBitmap(int key, Bitmap bitmap) { + if (sHasRemoteControlAPIs) { + try { + mPutBitmapMethod.invoke(mActualMetadataEditor, key, bitmap); + } catch (Exception e) { + throw new RuntimeException(e.getMessage(), e); + } + } + return this; + } + + /** + * Adds numerical information to be displayed. + * Note that none of the information added after {@link #apply()} has been called, + * will be displayed. + * @param key the identifier of a the metadata field to set. Valid values are + * {@link android.media.MediaMetadataRetriever#METADATA_KEY_CD_TRACK_NUMBER}, + * {@link android.media.MediaMetadataRetriever#METADATA_KEY_DISC_NUMBER}, + * {@link android.media.MediaMetadataRetriever#METADATA_KEY_DURATION} (with a value + * expressed in milliseconds), + * {@link android.media.MediaMetadataRetriever#METADATA_KEY_YEAR}. + * @param value The long value for the given key + * @return Returns a reference to the same MetadataEditor object, so you can chain put + * calls together. + * @throws IllegalArgumentException + */ + public MetadataEditorCompat putLong(int key, long value) { + if (sHasRemoteControlAPIs) { + try { + mPutLongMethod.invoke(mActualMetadataEditor, key, value); + } catch (Exception e) { + throw new RuntimeException(e.getMessage(), e); + } + } + return this; + } + + /** + * Clears all the metadata that has been set since the MetadataEditor instance was + * created with {@link android.media.RemoteControlClient#editMetadata(boolean)}. + */ + public void clear() { + if (sHasRemoteControlAPIs) { + try { + mClearMethod.invoke(mActualMetadataEditor, (Object[]) null); + } catch (Exception e) { + throw new RuntimeException(e.getMessage(), e); + } + } + } + + /** + * Associates all the metadata that has been set since the MetadataEditor instance was + * created with {@link android.media.RemoteControlClient#editMetadata(boolean)}, or since + * {@link #clear()} was called, with the RemoteControlClient. Once "applied", this + * MetadataEditor cannot be reused to edit the RemoteControlClient's metadata. + */ + public void apply() { + if (sHasRemoteControlAPIs) { + try { + mApplyMethod.invoke(mActualMetadataEditor, (Object[]) null); + } catch (Exception e) { + throw new RuntimeException(e.getMessage(), e); + } + } + } + } + + /** + * Creates a {@link android.media.RemoteControlClient.MetadataEditor}. + * @param startEmpty Set to false if you want the MetadataEditor to contain the metadata that + * was previously applied to the RemoteControlClient, or true if it is to be created empty. + * @return a new MetadataEditor instance. + */ + public MetadataEditorCompat editMetadata(boolean startEmpty) { + Object metadataEditor; + if (sHasRemoteControlAPIs) { + try { + metadataEditor = sRCCEditMetadataMethod.invoke(mActualRemoteControlClient, + startEmpty); + } catch (Exception e) { + throw new RuntimeException(e); + } + } else { + metadataEditor = null; + } + return new MetadataEditorCompat(metadataEditor); + } + + /** + * Sets the current playback state. + * @param state The current playback state, one of the following values: + * {@link android.media.RemoteControlClient#PLAYSTATE_STOPPED}, + * {@link android.media.RemoteControlClient#PLAYSTATE_PAUSED}, + * {@link android.media.RemoteControlClient#PLAYSTATE_PLAYING}, + * {@link android.media.RemoteControlClient#PLAYSTATE_FAST_FORWARDING}, + * {@link android.media.RemoteControlClient#PLAYSTATE_REWINDING}, + * {@link android.media.RemoteControlClient#PLAYSTATE_SKIPPING_FORWARDS}, + * {@link android.media.RemoteControlClient#PLAYSTATE_SKIPPING_BACKWARDS}, + * {@link android.media.RemoteControlClient#PLAYSTATE_BUFFERING}, + * {@link android.media.RemoteControlClient#PLAYSTATE_ERROR}. + */ + public void setPlaybackState(int state) { + if (sHasRemoteControlAPIs) { + try { + sRCCSetPlayStateMethod.invoke(mActualRemoteControlClient, state); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + } + + /** + * Sets the flags for the media transport control buttons that this client supports. + * @param transportControlFlags A combination of the following flags: + * {@link android.media.RemoteControlClient#FLAG_KEY_MEDIA_PREVIOUS}, + * {@link android.media.RemoteControlClient#FLAG_KEY_MEDIA_REWIND}, + * {@link android.media.RemoteControlClient#FLAG_KEY_MEDIA_PLAY}, + * {@link android.media.RemoteControlClient#FLAG_KEY_MEDIA_PLAY_PAUSE}, + * {@link android.media.RemoteControlClient#FLAG_KEY_MEDIA_PAUSE}, + * {@link android.media.RemoteControlClient#FLAG_KEY_MEDIA_STOP}, + * {@link android.media.RemoteControlClient#FLAG_KEY_MEDIA_FAST_FORWARD}, + * {@link android.media.RemoteControlClient#FLAG_KEY_MEDIA_NEXT} + */ + public void setTransportControlFlags(int transportControlFlags) { + if (sHasRemoteControlAPIs) { + try { + sRCCSetTransportControlFlags.invoke(mActualRemoteControlClient, + transportControlFlags); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + } + + public final Object getActualRemoteControlClientObject() { + return mActualRemoteControlClient; + } +} diff --git a/src/main/java/com/kaytat/simpleprotocolplayer/RemoteControlHelper.java b/src/main/java/com/kaytat/simpleprotocolplayer/RemoteControlHelper.java new file mode 100644 index 0000000..aa3bab7 --- /dev/null +++ b/src/main/java/com/kaytat/simpleprotocolplayer/RemoteControlHelper.java @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.kaytat.simpleprotocolplayer; + +import android.media.AudioManager; +import android.util.Log; + +import java.lang.reflect.Method; + +/** + * Contains methods to handle registering/unregistering remote control clients. These methods only + * run on ICS devices. On previous devices, all methods are no-ops. + */ +@SuppressWarnings({"unchecked", "rawtypes"}) +public class RemoteControlHelper { + private static final String TAG = "RemoteControlHelper"; + + private static boolean sHasRemoteControlAPIs = false; + + private static Method sRegisterRemoteControlClientMethod; + private static Method sUnregisterRemoteControlClientMethod; + + static { + try { + ClassLoader classLoader = RemoteControlHelper.class.getClassLoader(); + Class sRemoteControlClientClass = + RemoteControlClientCompat.getActualRemoteControlClientClass(classLoader); + sRegisterRemoteControlClientMethod = AudioManager.class.getMethod( + "registerRemoteControlClient", new Class[]{sRemoteControlClientClass}); + sUnregisterRemoteControlClientMethod = AudioManager.class.getMethod( + "unregisterRemoteControlClient", new Class[]{sRemoteControlClientClass}); + sHasRemoteControlAPIs = true; + } catch (ClassNotFoundException e) { + // Silently fail when running on an OS before ICS. + } catch (NoSuchMethodException e) { + // Silently fail when running on an OS before ICS. + } catch (IllegalArgumentException e) { + // Silently fail when running on an OS before ICS. + } catch (SecurityException e) { + // Silently fail when running on an OS before ICS. + } + } + + public static void registerRemoteControlClient(AudioManager audioManager, + RemoteControlClientCompat remoteControlClient) { + if (!sHasRemoteControlAPIs) { + return; + } + + try { + sRegisterRemoteControlClientMethod.invoke(audioManager, + remoteControlClient.getActualRemoteControlClientObject()); + } catch (Exception e) { + Log.e(TAG, e.getMessage(), e); + } + } + + + public static void unregisterRemoteControlClient(AudioManager audioManager, + RemoteControlClientCompat remoteControlClient) { + if (!sHasRemoteControlAPIs) { + return; + } + + try { + sUnregisterRemoteControlClientMethod.invoke(audioManager, + remoteControlClient.getActualRemoteControlClientObject()); + } catch (Exception e) { + Log.e(TAG, e.getMessage(), e); + } + } +} + diff --git a/src/main/res/drawable-hdpi-v11/ic_stat_playing.png b/src/main/res/drawable-hdpi-v11/ic_stat_playing.png new file mode 100755 index 0000000000000000000000000000000000000000..cc62c29f10f44f16f984adf1f990e65a12acb9f4 GIT binary patch literal 740 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 LNkvXXu0mjf8m3hL literal 0 HcmV?d00001 diff --git a/src/main/res/drawable-hdpi/eject_pressed.png b/src/main/res/drawable-hdpi/eject_pressed.png new file mode 100644 index 0000000000000000000000000000000000000000..065b30d9e4abd35efc7968ae47ef457c222db641 GIT binary patch literal 4503 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 literal 0 HcmV?d00001 diff --git a/src/main/res/drawable-hdpi/ff.png b/src/main/res/drawable-hdpi/ff.png new file mode 100644 index 0000000000000000000000000000000000000000..508f741fcd638644582dd376de2a8dc9a6cd8902 GIT binary patch literal 4355 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 literal 0 HcmV?d00001 diff --git a/src/main/res/drawable-hdpi/ff_pressed.png b/src/main/res/drawable-hdpi/ff_pressed.png new file mode 100644 index 0000000000000000000000000000000000000000..468ae8e6925fedbe3ec44da0fcf944327c4f37fd GIT binary patch literal 4493 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 literal 0 HcmV?d00001 diff --git a/src/main/res/drawable-hdpi/ic_launcher.png b/src/main/res/drawable-hdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..4797ef72b7f265b68ce4dd8419cf493e73e2f060 GIT binary patch literal 4484 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 P00000NkvXXu0mjfkRTLv literal 0 HcmV?d00001 diff --git a/src/main/res/drawable-hdpi/pause.png b/src/main/res/drawable-hdpi/pause.png new file mode 100644 index 0000000000000000000000000000000000000000..13581de347ed2167c1557ea7212a747bd5e527d1 GIT binary patch literal 4241 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 literal 0 HcmV?d00001 diff --git a/src/main/res/drawable-hdpi/pause_pressed.png b/src/main/res/drawable-hdpi/pause_pressed.png new file mode 100644 index 0000000000000000000000000000000000000000..9ddd07dabed3a30d79388ce4d3c1ce1bb18240d0 GIT binary patch literal 4459 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 literal 0 HcmV?d00001 diff --git a/src/main/res/drawable-hdpi/play.png b/src/main/res/drawable-hdpi/play.png new file mode 100644 index 0000000000000000000000000000000000000000..e34b48e80f9d583015637a1d7935ec4c002a79e6 GIT binary patch literal 4373 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 literal 0 HcmV?d00001 diff --git a/src/main/res/drawable-mdpi-v9/ic_stat_playing.png b/src/main/res/drawable-mdpi-v9/ic_stat_playing.png new file mode 100755 index 0000000000000000000000000000000000000000..7970cb976922eda2bf9a38de99ed8007326ab8e7 GIT binary patch literal 548 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 YN8bfMy2jQ2{X z+lx(69LF8wIx%jIP-w(RGboo3BNRhCdZ*?|5hZVm7aqyKpcI)mG9(@(xulQ@iOFS{ ziI5rNIx{|B&S;-)uf5hjXRkf;aK81)-fR8V+P~kroxOh}*WceiYzV6Y-xfeUT!7C| zpb-UkL*u3rH{|d}*aXX=3vR=Z4PXM!t$@w20qP()xbL`+Tq;2$Y%)dU52Aqe=lVN!VJPoXKx8)gd9x6|UzTQS{ z?rP?heN*OQ5mbXdNngQr(A%uO%v2Vu!3bbJ9_@$ipd3+HyD8AO#CsSQt_V9yPKV0^DK|PDk^~*>K>haw3kI%T zrc*i2y|4$gj>FnQ!9LItXmU^qUs0?c(NLL=|6~hbEG>?M61H&~L*={}1Emc`G5SQK zhwweBv1!C)I|}5u&3W0{q^0%@B1h5E_&oKR-N@x>3ZQ}pS}q5m80i-@_$&IAdu8Ud zPm<^*#!B!SQ#7Ukv?TOLw^>k(G}7TyLjg2{61pyG#b^gSf#6^iv^DL4(O4CU(9ifO2|eJW3knZ3%i2ej$#K;+S7=~f%{E*RIX zrG27mQvjL)ZK89Ddi(nde3mvkx3iJ{vxk8k<+acXF6zMOAXI{>&(zCp9V&=AXoemL ztCxaKI0fsN_nLREJvMXT@SW%X|Np-8)Uw%Z(f>@I|4A;~ z1p$Q!6e3WFfbU;iM1zBaevikqC!J33D=8_t*3{HAuXz8O07%1-?$2a04UipOT3Xu0 zwI53)5;v*;9RWi_LtF5&&g=CyXqwirxVX5Dx)1UqgcKntURG9SdVJO!0c~VtWJ@ZQ zI)ry8$p;~-qOOxVdFb2-@DN_{^cWr;g``eM@zO_IkrPt2{$leMFfcH%mw5va9avac z&?K~y*GMV)19sx_7J%1*cs#xlZ?!c@C)o!NAiaUz$=LIDn89ZI`ufhWAv1p@0s!jkEMR!HKy?BeW#?aq_(gkrdrZa{6YU0i?_jt-L`2&qR{{jg!O=7EiDdBfkhDw zc?%E_J5TJuowT_U-~`y|7`GSEs`&l={TtZvRpc;vrlzLmBZHHa37qvPx)LBjE5U|` zheN!Mt*mzwee(E}kmF-xV=p0((eB4ugu4>35@mFBw3M$_gd=)_95$TyQf|ycYCHlo zpU-Dfu`U6z*w1%oc6Rn~GMQ}PClpp>%F1_4B_fliZd!-m3W!7^Wx-%@H5!_g2Zh|q-YHMpvce&{vh(@C#XfMQFLavl6AgQa5CuQBe#>U1J zf}bAzZ0QSqw2zW&#ypwT2?e0)3z!4ZyAX%62aA}2;7kmNt0dsA6ic^?l) z=$p#*8_hI*7m3t`=H_PkL79?i2{XX46Dq$Z~rGsSO6|K3Ox=(yC=({qc} zIl{ah^vn9aV%_g{c6Pp@Y})+_$RuEXem(`jm=H@6Axearkh3#{{Vl}C&uON+yZbTy zk{u`067Y*nLVBA#DddurRfq^mK>mpOL)Eq(YZ3rZrnbvbsQ5p*RG z2%IH-GxobJ%L`#QSL^NV-OROmoc_~fFQP89M;>%_bxqh!aND+;0JnH~&s(_!c>}C> gLP0Ny8r+H07*qoM6N<$g6&%cssI20 literal 0 HcmV?d00001 diff --git a/src/main/res/drawable-xhdpi/ic_launcher.png b/src/main/res/drawable-xhdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..104bd042ae244849328f9f55fd504bc76bdd7999 GIT binary patch literal 7240 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 O0000 + + + + + + diff --git a/src/main/res/drawable/btn_ff.xml b/src/main/res/drawable/btn_ff.xml new file mode 100644 index 0000000..c87fa06 --- /dev/null +++ b/src/main/res/drawable/btn_ff.xml @@ -0,0 +1,21 @@ + + + + + + + diff --git a/src/main/res/drawable/btn_pause.xml b/src/main/res/drawable/btn_pause.xml new file mode 100644 index 0000000..7aadd2f --- /dev/null +++ b/src/main/res/drawable/btn_pause.xml @@ -0,0 +1,21 @@ + + + + + + + diff --git a/src/main/res/drawable/btn_play.xml b/src/main/res/drawable/btn_play.xml new file mode 100644 index 0000000..dc319c5 --- /dev/null +++ b/src/main/res/drawable/btn_play.xml @@ -0,0 +1,21 @@ + + + + + + + diff --git a/src/main/res/drawable/btn_rew.xml b/src/main/res/drawable/btn_rew.xml new file mode 100644 index 0000000..cc4dad8 --- /dev/null +++ b/src/main/res/drawable/btn_rew.xml @@ -0,0 +1,21 @@ + + + + + + + diff --git a/src/main/res/drawable/btn_stop.xml b/src/main/res/drawable/btn_stop.xml new file mode 100644 index 0000000..5ce2d17 --- /dev/null +++ b/src/main/res/drawable/btn_stop.xml @@ -0,0 +1,21 @@ + + + + + + + diff --git a/src/main/res/layout-land/main.xml b/src/main/res/layout-land/main.xml new file mode 100644 index 0000000..81de70a --- /dev/null +++ b/src/main/res/layout-land/main.xml @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +