Refactor bootanimation into a shared lib.

We would like to reuse the animation parts of it in Android things.
This refactors the audio part into the _main and gets callbacks from
the BootAnimation class at interesting times. This will be the same
approach we take to integrate with it.

BUG: 37992717
Test: Built locally and pushed to a bullhead, works with sound.
Change-Id: I5eaca07c25eeb5edeab07d7ae7a29945e0e2cd37
diff --git a/cmds/bootanimation/BootAnimation.cpp b/cmds/bootanimation/BootAnimation.cpp
index 4f772c3..6b2de4b 100644
--- a/cmds/bootanimation/BootAnimation.cpp
+++ b/cmds/bootanimation/BootAnimation.cpp
@@ -62,7 +62,6 @@
 #include <EGL/eglext.h>
 
 #include "BootAnimation.h"
-#include "audioplay.h"
 
 namespace android {
 
@@ -92,26 +91,18 @@
 static const int TEXT_CENTER_VALUE = INT_MAX;
 static const int TEXT_MISSING_VALUE = INT_MIN;
 static const char EXIT_PROP_NAME[] = "service.bootanim.exit";
-static const char PLAY_SOUND_PROP_NAME[] = "persist.sys.bootanim.play_sound";
 static const int ANIM_ENTRY_NAME_MAX = 256;
 static constexpr size_t TEXT_POS_LEN_MAX = 16;
-static const char BOOT_COMPLETED_PROP_NAME[] = "sys.boot_completed";
-static const char BOOTREASON_PROP_NAME[] = "ro.boot.bootreason";
-// bootreasons list in "system/core/bootstat/bootstat.cpp".
-static const std::vector<std::string> PLAY_SOUND_BOOTREASON_BLACKLIST {
-  "kernel_panic",
-  "Panic",
-  "Watchdog",
-};
 
 // ---------------------------------------------------------------------------
 
-BootAnimation::BootAnimation() : Thread(false), mClockEnabled(true), mTimeIsAccurate(false),
-        mTimeFormat12Hour(false), mTimeCheckThread(NULL) {
+BootAnimation::BootAnimation(InitCallback initCallback,
+                             PlayPartCallback partCallback)
+        : Thread(false), mClockEnabled(true), mTimeIsAccurate(false),
+        mTimeFormat12Hour(false), mTimeCheckThread(NULL),
+        mInitCallback(initCallback), mPlayPartCallback(partCallback) {
     mSession = new SurfaceComposerClient();
 
-    // If the system has already booted, the animation is not being used for a boot.
-    mSystemBoot = !android::base::GetBoolProperty(BOOT_COMPLETED_PROP_NAME, false);
     std::string powerCtl = android::base::GetProperty("sys.powerctl", "");
     if (powerCtl.empty()) {
         mShuttingDown = false;
@@ -142,7 +133,6 @@
     // might be blocked on a condition variable that will never be updated.
     kill( getpid(), SIGKILL );
     requestExit();
-    audioplay::destroy();
 }
 
 status_t BootAnimation::initTexture(Texture* texture, AssetManager& assets,
@@ -704,7 +694,6 @@
         return false;
     }
 
-    Animation::Part* partWithAudio = NULL;
     ZipEntryRO entry;
     char name[ANIM_ENTRY_NAME_MAX];
     while ((entry = zip->nextEntry(cookie)) != NULL) {
@@ -739,7 +728,6 @@
                                     // a part may have at most one audio file
                                     part.audioData = (uint8_t *)map->getDataPtr();
                                     part.audioLength = map->getDataLength();
-                                    partWithAudio = &part;
                                 } else if (leaf == "trim.txt") {
                                     part.trimData.setTo((char const*)map->getDataPtr(),
                                                         map->getDataLength());
@@ -789,13 +777,8 @@
         }
     }
 
-    // Create and initialize audioplay if there is a wav file in any of the animations.
-    // Do it on a separate thread so we don't hold up the animation intro.
-    if (partWithAudio != NULL) {
-        ALOGD("found audio.wav, creating playback engine");
-        mInitAudioThread = new InitAudioThread(partWithAudio->audioData,
-                                               partWithAudio->audioLength);
-        mInitAudioThread->run("BootAnimation::InitAudioThread", PRIORITY_NORMAL);
+    if (mInitCallback != nullptr) {
+        mInitCallback(animation.parts);
     }
 
     zip->endIteration(cookie);
@@ -868,11 +851,6 @@
         mTimeCheckThread = nullptr;
     }
 
-    // We should have joined mInitAudioThread thread in playAnimation
-    if (mInitAudioThread != nullptr) {
-        mInitAudioThread = nullptr;
-    }
-
     releaseAnimation(animation);
 
     if (clockFontInitialized) {
@@ -909,14 +887,8 @@
             if(exitPending() && !part.playUntilComplete)
                 break;
 
-            // only play audio file the first time we animate the part
-            if (r == 0 && part.audioData && playSoundsAllowed()) {
-                ALOGD("playing clip for part%d, size=%d", (int) i, part.audioLength);
-                // Block until the audio engine is finished initializing.
-                if (mInitAudioThread != nullptr) {
-                    mInitAudioThread->join();
-                }
-                audioplay::playClip(part.audioData, part.audioLength);
+            if (mPlayPartCallback != nullptr) {
+                mPlayPartCallback(i, part, r);
             }
 
             glClearColor(
@@ -1005,10 +977,6 @@
         }
     }
 
-    // we've finally played everything we're going to play
-    audioplay::setPlaying(false);
-    audioplay::destroy();
-
     return true;
 }
 
@@ -1054,32 +1022,6 @@
     return animation;
 }
 
-bool BootAnimation::playSoundsAllowed() const {
-    // Only play sounds for system boots, not runtime restarts.
-    if (!mSystemBoot) {
-        return false;
-    }
-    if (mShuttingDown) { // no audio while shutting down
-        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;
-}
-
 bool BootAnimation::updateIsTimeAccurate() {
     static constexpr long long MAX_TIME_IN_PAST =   60000LL * 60LL * 24LL * 30LL;  // 30 days
     static constexpr long long MAX_TIME_IN_FUTURE = 60000LL * 90LL;  // 90 minutes
@@ -1211,17 +1153,6 @@
     return NO_ERROR;
 }
 
-BootAnimation::InitAudioThread::InitAudioThread(uint8_t* exampleAudioData, int exampleAudioLength)
-    : Thread(false),
-      mExampleAudioData(exampleAudioData),
-      mExampleAudioLength(exampleAudioLength) {}
-
-bool BootAnimation::InitAudioThread::threadLoop() {
-    audioplay::create(mExampleAudioData, mExampleAudioLength);
-    // Exit immediately
-    return false;
-}
-
 // ---------------------------------------------------------------------------
 
 }