diff options
author | 2018-04-10 13:39:09 -0700 | |
---|---|---|
committer | 2018-05-31 11:50:47 -0700 | |
commit | 33f4b7d63b511b145e3ce72580a52f3551358a61 (patch) | |
tree | 3231e0a33be92e7758f9e6b11b33172c3e89288e | |
parent | 3bb9562f198bbbdf2bf949203936b092903803f1 (diff) |
Refactor audio code out of bootanimation_main.
So it can be shared with the iot/ variant I refactored it into the
audioplay.h file. This keeps all of the audio code local, we could hide
the functions and only expose the callback but that would make testing
harder.
Test: Ran a bootanimation.zip with audio.wav on Marlin, works as expected.
Bug: 67051984
Change-Id: Ie31dc5f2cfaad5bb23134ef81be712afa6b3cd6f
-rw-r--r-- | cmds/bootanimation/BootAnimation.h | 1 | ||||
-rw-r--r-- | cmds/bootanimation/BootAnimationUtil.cpp | 43 | ||||
-rw-r--r-- | cmds/bootanimation/BootAnimationUtil.h | 7 | ||||
-rw-r--r-- | cmds/bootanimation/audioplay.cpp | 81 | ||||
-rw-r--r-- | cmds/bootanimation/audioplay.h | 5 | ||||
-rw-r--r-- | cmds/bootanimation/bootanimation_main.cpp | 111 |
6 files changed, 136 insertions, 112 deletions
diff --git a/cmds/bootanimation/BootAnimation.h b/cmds/bootanimation/BootAnimation.h index 56e131523bcb..dffbfde649e0 100644 --- a/cmds/bootanimation/BootAnimation.h +++ b/cmds/bootanimation/BootAnimation.h @@ -22,6 +22,7 @@ #include <androidfw/AssetManager.h> #include <utils/Thread.h> +#include <binder/IBinder.h> #include <EGL/egl.h> #include <GLES/gl.h> diff --git a/cmds/bootanimation/BootAnimationUtil.cpp b/cmds/bootanimation/BootAnimationUtil.cpp index 7718daf61d81..1e417e938359 100644 --- a/cmds/bootanimation/BootAnimationUtil.cpp +++ b/cmds/bootanimation/BootAnimationUtil.cpp @@ -16,14 +16,30 @@ #include "BootAnimationUtil.h" +#include <vector> #include <inttypes.h> #include <binder/IServiceManager.h> #include <cutils/properties.h> #include <utils/Log.h> #include <utils/SystemClock.h> +#include <android-base/properties.h> namespace android { +namespace { + +static constexpr char PLAY_SOUND_PROP_NAME[] = "persist.sys.bootanim.play_sound"; +static constexpr char BOOT_COMPLETED_PROP_NAME[] = "sys.boot_completed"; +static constexpr char POWER_CTL_PROP_NAME[] = "sys.powerctl"; +static constexpr char BOOTREASON_PROP_NAME[] = "ro.boot.bootreason"; +static const std::vector<std::string> PLAY_SOUND_BOOTREASON_BLACKLIST { + "kernel_panic", + "Panic", + "Watchdog", +}; + +} // namespace + bool bootAnimationDisabled() { char value[PROPERTY_VALUE_MAX]; @@ -58,4 +74,31 @@ void waitForSurfaceFlinger() { } } +bool playSoundsAllowed() { + // Only play sounds for system boots, not runtime restarts. + if (android::base::GetBoolProperty(BOOT_COMPLETED_PROP_NAME, false)) { + return false; + } + // no audio while shutting down + if (!android::base::GetProperty(POWER_CTL_PROP_NAME, "").empty()) { + return false; + } + // Read the system property to see if we should play the sound. + // If it's not present, default to allowed. + if (!property_get_bool(PLAY_SOUND_PROP_NAME, 1)) { + return false; + } + + // Don't play sounds if this is a reboot due to an error. + char bootreason[PROPERTY_VALUE_MAX]; + if (property_get(BOOTREASON_PROP_NAME, bootreason, nullptr) > 0) { + for (const auto& str : PLAY_SOUND_BOOTREASON_BLACKLIST) { + if (strcasecmp(str.c_str(), bootreason) == 0) { + return false; + } + } + } + return true; +} + } // namespace android diff --git a/cmds/bootanimation/BootAnimationUtil.h b/cmds/bootanimation/BootAnimationUtil.h index 60987cd1ccd1..1e1140a51763 100644 --- a/cmds/bootanimation/BootAnimationUtil.h +++ b/cmds/bootanimation/BootAnimationUtil.h @@ -14,6 +14,9 @@ * limitations under the License. */ +#ifndef ANDROID_BOOTANIMATION_UTIL_H +#define ANDROID_BOOTANIMATION_UTIL_H + namespace android { // Returns true if boot animation is disabled. @@ -22,4 +25,8 @@ bool bootAnimationDisabled(); // Waits until the surface flinger is up. void waitForSurfaceFlinger(); +// Returns whether sounds should be played during current boot. +bool playSoundsAllowed(); } // namespace android + +#endif // ANDROID_BOOTANIMATION_UTIL_H diff --git a/cmds/bootanimation/audioplay.cpp b/cmds/bootanimation/audioplay.cpp index c546072e733a..874aab08862e 100644 --- a/cmds/bootanimation/audioplay.cpp +++ b/cmds/bootanimation/audioplay.cpp @@ -17,22 +17,27 @@ // cribbed from samples/native-audio -#include "audioplay.h" - #define CHATTY ALOGD #define LOG_TAG "audioplay" +#include "audioplay.h" + #include <string.h> #include <utils/Log.h> +#include <utils/threads.h> // for native audio #include <SLES/OpenSLES.h> #include <SLES/OpenSLES_Android.h> +#include "BootAnimationUtil.h" + namespace audioplay { namespace { +using namespace android; + // engine interfaces static SLObjectItf engineObject = NULL; static SLEngineItf engineEngine; @@ -305,6 +310,74 @@ bool parseClipBuf(const uint8_t* clipBuf, int clipBufSize, const ChunkFormat** o return true; } +class InitAudioThread : public Thread { +public: + InitAudioThread(uint8_t* exampleAudioData, int exampleAudioLength) + : Thread(false), + mExampleAudioData(exampleAudioData), + mExampleAudioLength(exampleAudioLength) {} +private: + virtual bool threadLoop() { + audioplay::create(mExampleAudioData, mExampleAudioLength); + // Exit immediately + return false; + } + + uint8_t* mExampleAudioData; + int mExampleAudioLength; +}; + +// Typedef to aid readability. +typedef android::BootAnimation::Animation Animation; + +class AudioAnimationCallbacks : public android::BootAnimation::Callbacks { +public: + void init(const Vector<Animation::Part>& parts) override { + const Animation::Part* partWithAudio = nullptr; + for (const Animation::Part& part : parts) { + if (part.audioData != nullptr) { + partWithAudio = ∂ + break; + } + } + + if (partWithAudio == nullptr) { + return; + } + + ALOGD("found audio.wav, creating playback engine"); + // The audioData is used to initialize the audio system. Different data + // can be played later for other parts BUT the assumption is that they + // will all be the same format and only the format of this audioData + // will work correctly. + initAudioThread = new InitAudioThread(partWithAudio->audioData, + partWithAudio->audioLength); + initAudioThread->run("BootAnimation::InitAudioThread", PRIORITY_NORMAL); + }; + + void playPart(int partNumber, const Animation::Part& part, int playNumber) override { + // only play audio file the first time we animate the part + if (playNumber == 0 && part.audioData && playSoundsAllowed()) { + ALOGD("playing clip for part%d, size=%d", + partNumber, part.audioLength); + // Block until the audio engine is finished initializing. + if (initAudioThread != nullptr) { + initAudioThread->join(); + } + audioplay::playClip(part.audioData, part.audioLength); + } + }; + + void shutdown() override { + // we've finally played everything we're going to play + audioplay::setPlaying(false); + audioplay::destroy(); + }; + +private: + sp<InitAudioThread> initAudioThread = nullptr; +}; + } // namespace bool create(const uint8_t* exampleClipBuf, int exampleClipBufSize) { @@ -397,4 +470,8 @@ void destroy() { } } +sp<BootAnimation::Callbacks> createAnimationCallbacks() { + return new AudioAnimationCallbacks(); +} + } // namespace audioplay diff --git a/cmds/bootanimation/audioplay.h b/cmds/bootanimation/audioplay.h index 0e5705af0ad0..4704a702d50b 100644 --- a/cmds/bootanimation/audioplay.h +++ b/cmds/bootanimation/audioplay.h @@ -20,6 +20,8 @@ #include <string.h> +#include "BootAnimation.h" + namespace audioplay { // Initializes the engine with an example of the type of WAV clip to play. @@ -32,6 +34,9 @@ bool playClip(const uint8_t* buf, int size); void setPlaying(bool isPlaying); void destroy(); +// Generates callbacks to integrate the audioplay system with the BootAnimation. +android::sp<android::BootAnimation::Callbacks> createAnimationCallbacks(); + } #endif // AUDIOPLAY_H_ diff --git a/cmds/bootanimation/bootanimation_main.cpp b/cmds/bootanimation/bootanimation_main.cpp index 8501982d071c..a52a5e92a840 100644 --- a/cmds/bootanimation/bootanimation_main.cpp +++ b/cmds/bootanimation/bootanimation_main.cpp @@ -26,8 +26,6 @@ #include <sys/resource.h> #include <utils/Log.h> #include <utils/SystemClock.h> -#include <utils/threads.h> -#include <android-base/properties.h> #include "BootAnimation.h" #include "BootAnimationUtil.h" @@ -35,113 +33,6 @@ using namespace android; -// --------------------------------------------------------------------------- - -namespace { - -// Create a typedef for readability. -typedef android::BootAnimation::Animation Animation; - -static const char PLAY_SOUND_PROP_NAME[] = "persist.sys.bootanim.play_sound"; -static const char BOOT_COMPLETED_PROP_NAME[] = "sys.boot_completed"; -static const char POWER_CTL_PROP_NAME[] = "sys.powerctl"; -static const char BOOTREASON_PROP_NAME[] = "ro.boot.bootreason"; -static const std::vector<std::string> PLAY_SOUND_BOOTREASON_BLACKLIST { - "kernel_panic", - "Panic", - "Watchdog", -}; - -class InitAudioThread : public Thread { -public: - InitAudioThread(uint8_t* exampleAudioData, int exampleAudioLength) - : Thread(false), - mExampleAudioData(exampleAudioData), - mExampleAudioLength(exampleAudioLength) {} -private: - virtual bool threadLoop() { - audioplay::create(mExampleAudioData, mExampleAudioLength); - // Exit immediately - return false; - } - - uint8_t* mExampleAudioData; - int mExampleAudioLength; -}; - -bool playSoundsAllowed() { - // Only play sounds for system boots, not runtime restarts. - if (android::base::GetBoolProperty(BOOT_COMPLETED_PROP_NAME, false)) { - return false; - } - // no audio while shutting down - if (!android::base::GetProperty(POWER_CTL_PROP_NAME, "").empty()) { - return false; - } - // Read the system property to see if we should play the sound. - // If it's not present, default to allowed. - if (!property_get_bool(PLAY_SOUND_PROP_NAME, 1)) { - return false; - } - - // Don't play sounds if this is a reboot due to an error. - char bootreason[PROPERTY_VALUE_MAX]; - if (property_get(BOOTREASON_PROP_NAME, bootreason, nullptr) > 0) { - for (const auto& str : PLAY_SOUND_BOOTREASON_BLACKLIST) { - if (strcasecmp(str.c_str(), bootreason) == 0) { - return false; - } - } - } - return true; -} - -class AudioAnimationCallbacks : public android::BootAnimation::Callbacks { -public: - void init(const Vector<Animation::Part>& parts) override { - const Animation::Part* partWithAudio = nullptr; - for (const Animation::Part& part : parts) { - if (part.audioData != nullptr) { - partWithAudio = ∂ - } - } - - if (partWithAudio == nullptr) { - return; - } - - ALOGD("found audio.wav, creating playback engine"); - initAudioThread = new InitAudioThread(partWithAudio->audioData, - partWithAudio->audioLength); - initAudioThread->run("BootAnimation::InitAudioThread", PRIORITY_NORMAL); - }; - - void playPart(int partNumber, const Animation::Part& part, int playNumber) override { - // only play audio file the first time we animate the part - if (playNumber == 0 && part.audioData && playSoundsAllowed()) { - ALOGD("playing clip for part%d, size=%d", - partNumber, part.audioLength); - // Block until the audio engine is finished initializing. - if (initAudioThread != nullptr) { - initAudioThread->join(); - } - audioplay::playClip(part.audioData, part.audioLength); - } - }; - - void shutdown() override { - // we've finally played everything we're going to play - audioplay::setPlaying(false); - audioplay::destroy(); - }; - -private: - sp<InitAudioThread> initAudioThread = nullptr; -}; - -} // namespace - - int main() { setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_DISPLAY); @@ -156,7 +47,7 @@ int main() waitForSurfaceFlinger(); // create the boot animation object - sp<BootAnimation> boot = new BootAnimation(new AudioAnimationCallbacks()); + sp<BootAnimation> boot = new BootAnimation(audioplay::createAnimationCallbacks()); ALOGV("Boot animation set up. Joining pool."); IPCThreadState::self()->joinThreadPool(); |