diff options
Diffstat (limited to 'cmds/bootanimation/BootAnimation.cpp')
-rw-r--r-- | cmds/bootanimation/BootAnimation.cpp | 47 |
1 files changed, 45 insertions, 2 deletions
diff --git a/cmds/bootanimation/BootAnimation.cpp b/cmds/bootanimation/BootAnimation.cpp index 85db4b9f0f8f..520366f518ab 100644 --- a/cmds/bootanimation/BootAnimation.cpp +++ b/cmds/bootanimation/BootAnimation.cpp @@ -106,6 +106,7 @@ 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 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; @@ -294,6 +295,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(); @@ -1092,7 +1135,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; @@ -1136,10 +1179,10 @@ BootAnimation::Animation* BootAnimation::loadAnimation(const String8& fn) parseAnimationDesc(*animation); if (!preloadZip(*animation)) { + releaseAnimation(animation); return nullptr; } - mLoadedFiles.remove(fn); return animation; } |