LayoutAnimations: attempt to work around potential crashes when animation is racing with setup or teardown
Summary: Attempt to fix T68951888 where (1) ComponentHandle is zero, and/or (2) ComponentHandle is missing in the registry. Either will cause a crash and both should be trivial to work around. I was able to repro once accidentally in about 1/200 sessions, so I am not 100% sure if this fixes the root cause. Changelog: [Internal] Reviewed By: shergin Differential Revision: D22216030 fbshipit-source-id: b6986adee6fe739ce58579a2b031a2d252e73e35
This commit is contained in:
Родитель
2e27fb6a97
Коммит
6342e6e3f1
|
@ -521,8 +521,8 @@ LayoutAnimationKeyFrameManager::pullTransaction(
|
|||
mutation.type == ShadowViewMutation::Type::Remove
|
||||
? mutation.oldChildShadowView
|
||||
: mutation.newChildShadowView);
|
||||
auto const &componentDescriptor =
|
||||
getComponentDescriptorForShadowView(baselineShadowView);
|
||||
bool haveComponentDescriptor =
|
||||
hasComponentDescriptorForShadowView(baselineShadowView);
|
||||
|
||||
auto mutationConfig =
|
||||
(mutation.type == ShadowViewMutation::Type::Delete
|
||||
|
@ -660,8 +660,11 @@ LayoutAnimationKeyFrameManager::pullTransaction(
|
|||
AnimationKeyFrame keyFrame{};
|
||||
if (mutation.type == ShadowViewMutation::Type::Insert) {
|
||||
if (mutationConfig->animationProperty ==
|
||||
AnimationProperty::Opacity) {
|
||||
auto props = componentDescriptor.cloneProps(viewStart.props, {});
|
||||
AnimationProperty::Opacity &&
|
||||
haveComponentDescriptor) {
|
||||
auto props =
|
||||
getComponentDescriptorForShadowView(baselineShadowView)
|
||||
.cloneProps(viewStart.props, {});
|
||||
const auto viewProps =
|
||||
dynamic_cast<const ViewProps *>(props.get());
|
||||
if (viewProps != nullptr) {
|
||||
|
@ -675,8 +678,10 @@ LayoutAnimationKeyFrameManager::pullTransaction(
|
|||
bool isScaleY = mutationConfig->animationProperty ==
|
||||
AnimationProperty::ScaleY ||
|
||||
mutationConfig->animationProperty == AnimationProperty::ScaleXY;
|
||||
if (isScaleX || isScaleY) {
|
||||
auto props = componentDescriptor.cloneProps(viewStart.props, {});
|
||||
if ((isScaleX || isScaleY) && haveComponentDescriptor) {
|
||||
auto props =
|
||||
getComponentDescriptorForShadowView(baselineShadowView)
|
||||
.cloneProps(viewStart.props, {});
|
||||
const auto viewProps =
|
||||
dynamic_cast<const ViewProps *>(props.get());
|
||||
if (viewProps != nullptr) {
|
||||
|
@ -695,8 +700,11 @@ LayoutAnimationKeyFrameManager::pullTransaction(
|
|||
0};
|
||||
} else if (mutation.type == ShadowViewMutation::Type::Delete) {
|
||||
if (mutationConfig->animationProperty ==
|
||||
AnimationProperty::Opacity) {
|
||||
auto props = componentDescriptor.cloneProps(viewFinal.props, {});
|
||||
AnimationProperty::Opacity &&
|
||||
haveComponentDescriptor) {
|
||||
auto props =
|
||||
getComponentDescriptorForShadowView(baselineShadowView)
|
||||
.cloneProps(viewFinal.props, {});
|
||||
const auto viewProps =
|
||||
dynamic_cast<const ViewProps *>(props.get());
|
||||
if (viewProps != nullptr) {
|
||||
|
@ -710,8 +718,10 @@ LayoutAnimationKeyFrameManager::pullTransaction(
|
|||
bool isScaleY = mutationConfig->animationProperty ==
|
||||
AnimationProperty::ScaleY ||
|
||||
mutationConfig->animationProperty == AnimationProperty::ScaleXY;
|
||||
if (isScaleX || isScaleY) {
|
||||
auto props = componentDescriptor.cloneProps(viewFinal.props, {});
|
||||
if ((isScaleX || isScaleY) && haveComponentDescriptor) {
|
||||
auto props =
|
||||
getComponentDescriptorForShadowView(baselineShadowView)
|
||||
.cloneProps(viewFinal.props, {});
|
||||
const auto viewProps =
|
||||
dynamic_cast<const ViewProps *>(props.get());
|
||||
if (viewProps != nullptr) {
|
||||
|
@ -983,6 +993,12 @@ bool LayoutAnimationKeyFrameManager::mutatedViewIsVirtual(
|
|||
return viewIsVirtual;
|
||||
}
|
||||
|
||||
bool LayoutAnimationKeyFrameManager::hasComponentDescriptorForShadowView(
|
||||
ShadowView const &shadowView) const {
|
||||
return componentDescriptorRegistry_->hasComponentDescriptorAt(
|
||||
shadowView.componentHandle);
|
||||
}
|
||||
|
||||
ComponentDescriptor const &
|
||||
LayoutAnimationKeyFrameManager::getComponentDescriptorForShadowView(
|
||||
ShadowView const &shadowView) const {
|
||||
|
@ -1008,6 +1024,9 @@ ShadowView LayoutAnimationKeyFrameManager::createInterpolatedShadowView(
|
|||
AnimationConfig const &animationConfig,
|
||||
ShadowView startingView,
|
||||
ShadowView finalView) const {
|
||||
if (!hasComponentDescriptorForShadowView(startingView)) {
|
||||
return finalView;
|
||||
}
|
||||
ComponentDescriptor const &componentDescriptor =
|
||||
getComponentDescriptorForShadowView(startingView);
|
||||
auto mutatedShadowView = ShadowView(startingView);
|
||||
|
|
|
@ -148,6 +148,7 @@ class LayoutAnimationKeyFrameManager : public UIManagerAnimationDelegate,
|
|||
protected:
|
||||
bool mutatedViewIsVirtual(ShadowViewMutation const &mutation) const;
|
||||
|
||||
bool hasComponentDescriptorForShadowView(ShadowView const &shadowView) const;
|
||||
ComponentDescriptor const &getComponentDescriptorForShadowView(
|
||||
ShadowView const &shadowView) const;
|
||||
std::pair<double, double> calculateAnimationProgress(
|
||||
|
|
|
@ -168,6 +168,18 @@ ComponentDescriptor const &ComponentDescriptorRegistry::at(
|
|||
return *_registryByHandle.at(componentHandle);
|
||||
}
|
||||
|
||||
bool ComponentDescriptorRegistry::hasComponentDescriptorAt(
|
||||
ComponentHandle componentHandle) const {
|
||||
std::shared_lock<better::shared_mutex> lock(mutex_);
|
||||
|
||||
auto iterator = _registryByHandle.find(componentHandle);
|
||||
if (iterator == _registryByHandle.end()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
SharedShadowNode ComponentDescriptorRegistry::createNode(
|
||||
Tag tag,
|
||||
std::string const &viewName,
|
||||
|
|
|
@ -51,6 +51,8 @@ class ComponentDescriptorRegistry {
|
|||
ComponentDescriptor const &at(std::string const &componentName) const;
|
||||
ComponentDescriptor const &at(ComponentHandle componentHandle) const;
|
||||
|
||||
bool hasComponentDescriptorAt(ComponentHandle componentHandle) const;
|
||||
|
||||
ShadowNode::Shared createNode(
|
||||
Tag tag,
|
||||
std::string const &viewName,
|
||||
|
|
Загрузка…
Ссылка в новой задаче