Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7c91d02a authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Refactor audio code out of bootanimation_main."

parents ca380037 33f4b7d6
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@

#include <androidfw/AssetManager.h>
#include <utils/Thread.h>
#include <binder/IBinder.h>

#include <EGL/egl.h>
#include <GLES/gl.h>
+43 −0
Original line number Diff line number Diff line
@@ -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
+7 −0
Original line number Diff line number Diff line
@@ -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
+79 −2
Original line number Diff line number Diff line
@@ -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 = &part;
                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
+5 −0
Original line number Diff line number Diff line
@@ -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_
Loading