summaryrefslogtreecommitdiff
path: root/cmds/bootanimation/BootAnimation.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'cmds/bootanimation/BootAnimation.cpp')
-rw-r--r--cmds/bootanimation/BootAnimation.cpp55
1 files changed, 51 insertions, 4 deletions
diff --git a/cmds/bootanimation/BootAnimation.cpp b/cmds/bootanimation/BootAnimation.cpp
index 87f7224702e1..9af2a96cbe13 100644
--- a/cmds/bootanimation/BootAnimation.cpp
+++ b/cmds/bootanimation/BootAnimation.cpp
@@ -63,6 +63,10 @@
#include "BootAnimation.h"
+#define ANIM_PATH_MAX 255
+#define STR(x) #x
+#define STRTO(x) STR(x)
+
namespace android {
static const char OEM_BOOTANIMATION_FILE[] = "/oem/media/bootanimation.zip";
@@ -96,7 +100,8 @@ static constexpr size_t FONT_NUM_ROWS = FONT_NUM_CHARS / FONT_NUM_COLS;
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 int ANIM_ENTRY_NAME_MAX = 256;
+static const char DISPLAYS_PROP_NAME[] = "persist.service.bootanim.displays";
+static const int ANIM_ENTRY_NAME_MAX = ANIM_PATH_MAX + 1;
static constexpr size_t TEXT_POS_LEN_MAX = 16;
// ---------------------------------------------------------------------------
@@ -284,6 +289,48 @@ status_t BootAnimation::readyToRun() {
dinfo.w, dinfo.h, PIXEL_FORMAT_RGB_565);
SurfaceComposerClient::Transaction t;
+
+ // this guest property specifies multi-display IDs to show the boot animation
+ // multiple ids can be set with comma (,) as separator, for example:
+ // setprop persist.boot.animation.displays 19260422155234049,19261083906282754
+ Vector<uint64_t> physicalDisplayIds;
+ char displayValue[PROPERTY_VALUE_MAX] = "";
+ property_get(DISPLAYS_PROP_NAME, displayValue, "");
+ bool isValid = displayValue[0] != '\0';
+ if (isValid) {
+ char *p = displayValue;
+ while (*p) {
+ if (!isdigit(*p) && *p != ',') {
+ isValid = false;
+ break;
+ }
+ p ++;
+ }
+ if (!isValid)
+ SLOGE("Invalid syntax for the value of system prop: %s", DISPLAYS_PROP_NAME);
+ }
+ if (isValid) {
+ std::istringstream stream(displayValue);
+ for (PhysicalDisplayId id; stream >> id; ) {
+ physicalDisplayIds.add(id);
+ if (stream.peek() == ',')
+ stream.ignore();
+ }
+
+ // In the case of multi-display, boot animation shows on the specified displays
+ // in addition to the primary display
+ auto ids = SurfaceComposerClient::getPhysicalDisplayIds();
+ constexpr uint32_t LAYER_STACK = 0;
+ for (auto id : physicalDisplayIds) {
+ if (std::find(ids.begin(), ids.end(), id) != ids.end()) {
+ sp<IBinder> token = SurfaceComposerClient::getPhysicalDisplayToken(id);
+ if (token != nullptr)
+ t.setDisplayLayerStack(token, LAYER_STACK);
+ }
+ }
+ t.setLayerStack(control, LAYER_STACK);
+ }
+
t.setLayer(control, 0x40000000)
.apply();
@@ -705,7 +752,7 @@ bool BootAnimation::parseAnimationDesc(Animation& animation)
animation.width = width;
animation.height = height;
animation.fps = fps;
- } else if (sscanf(l, " %c %d %d %s #%6s %16s %16s",
+ } else if (sscanf(l, " %c %d %d %" STRTO(ANIM_PATH_MAX) "s #%6s %16s %16s",
&pathType, &count, &pause, path, color, clockPos1, clockPos2) >= 4) {
//SLOGD("> type=%c, count=%d, pause=%d, path=%s, color=%s, clockPos1=%s, clockPos2=%s",
// pathType, count, pause, path, color, clockPos1, clockPos2);
@@ -1078,7 +1125,7 @@ void BootAnimation::handleViewport(nsecs_t timestep) {
SurfaceComposerClient::Transaction t;
t.setPosition(mFlingerSurfaceControl, 0, -mTargetInset)
.setCrop(mFlingerSurfaceControl, Rect(0, mTargetInset, mWidth, mHeight));
- t.setDisplayProjection(mDisplayToken, 0 /* orientation */, layerStackRect, displayRect);
+ t.setDisplayProjection(mDisplayToken, ui::ROTATION_0, layerStackRect, displayRect);
t.apply();
mTargetInset = mCurrentInset = 0;
@@ -1122,10 +1169,10 @@ BootAnimation::Animation* BootAnimation::loadAnimation(const String8& fn)
parseAnimationDesc(*animation);
if (!preloadZip(*animation)) {
+ releaseAnimation(animation);
return nullptr;
}
-
mLoadedFiles.remove(fn);
return animation;
}