[go: nahoru, domu]

[GroupEffect] Remove SingleKeyframeEffectAnimation

SingleKeyframeEffectAnimation was introduced to support multiple effects
per animation for AnimationWorklet. i.e. each animation has a list of
single KeyframeEffects.

However, GroupEffect is now re-designed for WebAnimation. Instead of a
list of KeyframeEffects, an animation will have one AnimationEffect
which could be either a single KeyframeEffect of a GroupEffect which
combines a list of AnimationEffect in different manners. See [1] for
details. Therefore the existing model is obsolete and should be removed.

This patch is just a refactoring and it should not affect any prod
paths.

[1] https://github.com/yi-gu/group_effect

Bug: 767043, 956696
Change-Id: I2b5bc60dea9763ac64e5484e6ba793d8b6404089
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1993429
Commit-Queue: Yi Gu <yigu@chromium.org>
Reviewed-by: Stephen McGruer <smcgruer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#730563}
diff --git a/cc/animation/BUILD.gn b/cc/animation/BUILD.gn
index 19627f4..5bd47e6 100644
--- a/cc/animation/BUILD.gn
+++ b/cc/animation/BUILD.gn
@@ -40,8 +40,6 @@
     "scroll_offset_animations_impl.h",
     "scroll_timeline.cc",
     "scroll_timeline.h",
-    "single_keyframe_effect_animation.cc",
-    "single_keyframe_effect_animation.h",
     "timing_function.cc",
     "timing_function.h",
     "transform_operation.cc",
diff --git a/cc/animation/README.md b/cc/animation/README.md
index 07ed15c..d631728 100644
--- a/cc/animation/README.md
+++ b/cc/animation/README.md
@@ -32,15 +32,7 @@
 Each Animation has a copy on the impl thread, and will take care of
 synchronizing to/from the impl thread when requested.
 
-[SingleKeyframeEffectAnimation](https://cs.chromium.org/chromium/src/cc/animation/single_keyframe_effect_animation.h)
-It is a sub-class of Animation that serves as a bridge between the cc animation
-clients and cc because currently only a single keyframe effect per animation is
-supported.
-
-There is a 1:1 relationship between SingleKeyframeEffectAnimation and
-the KeyframeEffect.
-
-> NOTE: SingleKeyframeEffectAnimation is being deprecated.
+There is a 1:1 relationship between Animation and KeyframeEffect.
 
 [Keyframe model](https://codesearch.chromium.org/chromium/src/cc/animation/keyframe_model.h)
 KeyframeModels contain the state necessary to 'play' (interpolate values from) an
diff --git a/cc/animation/animation.cc b/cc/animation/animation.cc
index bccfa2e..f61cb82 100644
--- a/cc/animation/animation.cc
+++ b/cc/animation/animation.cc
@@ -24,13 +24,15 @@
   return base::WrapRefCounted(new Animation(id));
 }
 
-Animation::Animation(int id)
-    : animation_host_(),
-      animation_timeline_(),
-      animation_delegate_(),
-      id_(id),
-      ticking_keyframe_effects_count(0) {
+Animation::Animation(int id) : Animation(id, nullptr) {}
+
+Animation::Animation(int id, std::unique_ptr<KeyframeEffect> keyframe_effect)
+    : animation_host_(), animation_timeline_(), animation_delegate_(), id_(id) {
   DCHECK(id_);
+  if (!keyframe_effect)
+    keyframe_effect.reset(new KeyframeEffect(this));
+
+  keyframe_effect_ = std::move(keyframe_effect);
 }
 
 Animation::~Animation() {
@@ -41,6 +43,10 @@
   return Animation::Create(id());
 }
 
+ElementId Animation::element_id() const {
+  return keyframe_effect_->element_id();
+}
+
 void Animation::SetAnimationHost(AnimationHost* animation_host) {
   animation_host_ = animation_host;
 }
@@ -49,234 +55,89 @@
   if (animation_timeline_ == timeline)
     return;
 
-  // We need to unregister keyframe_effect to manage ElementAnimations and
+  // We need to unregister the animation to manage ElementAnimations and
   // observers properly.
-  if (!element_to_keyframe_effect_id_map_.empty() && animation_host_) {
-    // Destroy ElementAnimations or release it if it's still needed.
-    UnregisterKeyframeEffects();
+  if (keyframe_effect_->has_attached_element() &&
+      keyframe_effect_->has_bound_element_animations()) {
+    UnregisterAnimation();
   }
 
   animation_timeline_ = timeline;
 
-  // Register animation only if layer AND host attached. Unlike the
-  // SingleKeyframeEffectAnimation case, all keyframe_effects have been attached
-  // to their corresponding elements.
-  if (!element_to_keyframe_effect_id_map_.empty() && animation_host_) {
-    RegisterKeyframeEffects();
-  }
-}
-
-bool Animation::has_element_animations() const {
-  return !element_to_keyframe_effect_id_map_.empty();
-}
-
-scoped_refptr<ElementAnimations> Animation::element_animations(
-    KeyframeEffectId keyframe_effect_id) const {
-  return GetKeyframeEffectById(keyframe_effect_id)->element_animations();
-}
-
-void Animation::AttachElementForKeyframeEffect(
-    ElementId element_id,
-    KeyframeEffectId keyframe_effect_id) {
-  DCHECK(GetKeyframeEffectById(keyframe_effect_id));
-  GetKeyframeEffectById(keyframe_effect_id)->AttachElement(element_id);
-  element_to_keyframe_effect_id_map_[element_id].emplace(keyframe_effect_id);
   // Register animation only if layer AND host attached.
-  if (animation_host_) {
-    // Create ElementAnimations or re-use existing.
-    RegisterKeyframeEffect(element_id, keyframe_effect_id);
-  }
+  if (keyframe_effect_->has_attached_element() && animation_host_)
+    RegisterAnimation();
 }
 
-void Animation::DetachElementForKeyframeEffect(
-    ElementId element_id,
-    KeyframeEffectId keyframe_effect_id) {
-  DCHECK(GetKeyframeEffectById(keyframe_effect_id));
-  DCHECK_EQ(GetKeyframeEffectById(keyframe_effect_id)->element_id(),
-            element_id);
+scoped_refptr<ElementAnimations> Animation::element_animations() const {
+  return keyframe_effect_->element_animations();
+}
 
-  UnregisterKeyframeEffect(element_id, keyframe_effect_id);
-  GetKeyframeEffectById(keyframe_effect_id)->DetachElement();
-  element_to_keyframe_effect_id_map_[element_id].erase(keyframe_effect_id);
+void Animation::AttachElement(ElementId element_id) {
+  keyframe_effect_->AttachElement(element_id);
+  // Register animation only if layer AND host attached.
+  if (animation_host_)
+    RegisterAnimation();
 }
 
 void Animation::DetachElement() {
-  if (animation_host_) {
-    // Destroy ElementAnimations or release it if it's still needed.
-    UnregisterKeyframeEffects();
-  }
+  DCHECK(keyframe_effect_->has_attached_element());
 
-  for (auto pair = element_to_keyframe_effect_id_map_.begin();
-       pair != element_to_keyframe_effect_id_map_.end();) {
-    for (auto keyframe_effect = pair->second.begin();
-         keyframe_effect != pair->second.end();) {
-      GetKeyframeEffectById(*keyframe_effect)->DetachElement();
-      keyframe_effect = pair->second.erase(keyframe_effect);
-    }
-    pair = element_to_keyframe_effect_id_map_.erase(pair);
-  }
-  DCHECK_EQ(element_to_keyframe_effect_id_map_.size(), 0u);
+  if (animation_host_)
+    UnregisterAnimation();
+
+  keyframe_effect_->DetachElement();
 }
 
-void Animation::RegisterKeyframeEffect(ElementId element_id,
-                                       KeyframeEffectId keyframe_effect_id) {
+void Animation::RegisterAnimation() {
   DCHECK(animation_host_);
-  KeyframeEffect* keyframe_effect = GetKeyframeEffectById(keyframe_effect_id);
-  DCHECK(!keyframe_effect->has_bound_element_animations());
+  DCHECK(keyframe_effect_->has_attached_element());
+  DCHECK(!keyframe_effect_->has_bound_element_animations());
 
-  if (!keyframe_effect->has_attached_element())
-    return;
-  animation_host_->RegisterKeyframeEffectForElement(element_id,
-                                                    keyframe_effect);
+  // Create ElementAnimations or re-use existing.
+  animation_host_->RegisterAnimationForElement(keyframe_effect_->element_id(),
+                                               this);
 }
 
-void Animation::UnregisterKeyframeEffect(ElementId element_id,
-                                         KeyframeEffectId keyframe_effect_id) {
+void Animation::UnregisterAnimation() {
   DCHECK(animation_host_);
-  KeyframeEffect* keyframe_effect = GetKeyframeEffectById(keyframe_effect_id);
-  DCHECK(keyframe_effect);
-  if (keyframe_effect->has_attached_element() &&
-      keyframe_effect->has_bound_element_animations()) {
-    animation_host_->UnregisterKeyframeEffectForElement(element_id,
-                                                        keyframe_effect);
-  }
-}
-void Animation::RegisterKeyframeEffects() {
-  for (auto& element_id_keyframe_effect_id :
-       element_to_keyframe_effect_id_map_) {
-    const ElementId element_id = element_id_keyframe_effect_id.first;
-    const std::unordered_set<KeyframeEffectId>& keyframe_effect_ids =
-        element_id_keyframe_effect_id.second;
-    for (auto& keyframe_effect_id : keyframe_effect_ids)
-      RegisterKeyframeEffect(element_id, keyframe_effect_id);
-  }
-}
+  DCHECK(keyframe_effect_->has_attached_element());
+  DCHECK(keyframe_effect_->has_bound_element_animations());
 
-void Animation::UnregisterKeyframeEffects() {
-  for (auto& element_id_keyframe_effect_id :
-       element_to_keyframe_effect_id_map_) {
-    const ElementId element_id = element_id_keyframe_effect_id.first;
-    const std::unordered_set<KeyframeEffectId>& keyframe_effect_ids =
-        element_id_keyframe_effect_id.second;
-    for (auto& keyframe_effect_id : keyframe_effect_ids)
-      UnregisterKeyframeEffect(element_id, keyframe_effect_id);
-  }
-  animation_host_->RemoveFromTicking(this);
-}
-
-void Animation::PushAttachedKeyframeEffectsToImplThread(
-    Animation* animation_impl) const {
-  for (auto& keyframe_effect : keyframe_effects_) {
-    KeyframeEffect* keyframe_effect_impl =
-        animation_impl->GetKeyframeEffectById(keyframe_effect->id());
-    if (keyframe_effect_impl)
-      continue;
-
-    std::unique_ptr<KeyframeEffect> to_add =
-        keyframe_effect->CreateImplInstance();
-    animation_impl->AddKeyframeEffect(std::move(to_add));
-  }
-}
-
-void Animation::PushPropertiesToImplThread(Animation* animation_impl) {
-  for (auto& keyframe_effect : keyframe_effects_) {
-    if (KeyframeEffect* keyframe_effect_impl =
-            animation_impl->GetKeyframeEffectById(keyframe_effect->id())) {
-      keyframe_effect->PushPropertiesTo(keyframe_effect_impl);
-    }
-  }
-}
-
-void Animation::AddKeyframeModelForKeyframeEffect(
-    std::unique_ptr<KeyframeModel> keyframe_model,
-    KeyframeEffectId keyframe_effect_id) {
-  DCHECK(GetKeyframeEffectById(keyframe_effect_id));
-  GetKeyframeEffectById(keyframe_effect_id)
-      ->AddKeyframeModel(std::move(keyframe_model));
-}
-
-void Animation::PauseKeyframeModelForKeyframeEffect(
-    int keyframe_model_id,
-    base::TimeDelta time_offset,
-    KeyframeEffectId keyframe_effect_id) {
-  DCHECK(GetKeyframeEffectById(keyframe_effect_id));
-  GetKeyframeEffectById(keyframe_effect_id)
-      ->PauseKeyframeModel(keyframe_model_id, time_offset);
-}
-
-void Animation::RemoveKeyframeModelForKeyframeEffect(
-    int keyframe_model_id,
-    KeyframeEffectId keyframe_effect_id) {
-  DCHECK(GetKeyframeEffectById(keyframe_effect_id));
-  GetKeyframeEffectById(keyframe_effect_id)
-      ->RemoveKeyframeModel(keyframe_model_id);
-}
-
-void Animation::AbortKeyframeModelForKeyframeEffect(
-    int keyframe_model_id,
-    KeyframeEffectId keyframe_effect_id) {
-  DCHECK(GetKeyframeEffectById(keyframe_effect_id));
-  GetKeyframeEffectById(keyframe_effect_id)
-      ->AbortKeyframeModel(keyframe_model_id);
-}
-
-void Animation::AbortKeyframeModelsWithProperty(
-    TargetProperty::Type target_property,
-    bool needs_completion) {
-  for (auto& keyframe_effect : keyframe_effects_)
-    keyframe_effect->AbortKeyframeModelsWithProperty(target_property,
-                                                     needs_completion);
+  // Destroy ElementAnimations or release it if it's still needed.
+  animation_host_->UnregisterAnimationForElement(keyframe_effect_->element_id(),
+                                                 this);
 }
 
 void Animation::PushPropertiesTo(Animation* animation_impl) {
-  // In general when pushing proerties to impl thread we first push attached
-  // properties to impl followed by removing the detached ones. However, we
-  // never remove individual keyframe effect from an animation so there is no
-  // need to remove the detached ones.
-  PushAttachedKeyframeEffectsToImplThread(animation_impl);
-  PushPropertiesToImplThread(animation_impl);
+  keyframe_effect_->PushPropertiesTo(animation_impl->keyframe_effect_.get());
 }
 
 void Animation::Tick(base::TimeTicks monotonic_time) {
   DCHECK(!monotonic_time.is_null());
-  for (auto& keyframe_effect : keyframe_effects_)
-    keyframe_effect->Tick(monotonic_time);
+  keyframe_effect_->Tick(monotonic_time);
 }
 
 void Animation::UpdateState(bool start_ready_animations,
                             AnimationEvents* events) {
-  for (auto& keyframe_effect : keyframe_effects_) {
-    keyframe_effect->UpdateState(start_ready_animations, events);
-    keyframe_effect->UpdateTickingState();
-  }
+  keyframe_effect_->UpdateState(start_ready_animations, events);
+  keyframe_effect_->UpdateTickingState();
 }
 
 void Animation::AddToTicking() {
-  ++ticking_keyframe_effects_count;
-  if (ticking_keyframe_effects_count > 1)
-    return;
   DCHECK(animation_host_);
   animation_host_->AddToTicking(this);
 }
 
 void Animation::RemoveFromTicking() {
-  DCHECK_GE(ticking_keyframe_effects_count, 0);
-  if (!ticking_keyframe_effects_count)
-    return;
-  --ticking_keyframe_effects_count;
   DCHECK(animation_host_);
-  DCHECK_GE(ticking_keyframe_effects_count, 0);
-  if (ticking_keyframe_effects_count)
-    return;
   animation_host_->RemoveFromTicking(this);
 }
 
 void Animation::DispatchAndDelegateAnimationEvent(const AnimationEvent& event) {
   if (event.ShouldDispatchToKeyframeEffectAndModel()) {
-    KeyframeEffect* keyframe_effect =
-        GetKeyframeEffectById(event.uid.effect_id);
-    if (!keyframe_effect ||
-        !keyframe_effect->DispatchAnimationEventToKeyframeModel(event)) {
+    if (!keyframe_effect_ ||
+        !keyframe_effect_->DispatchAnimationEventToKeyframeModel(event)) {
       // If we fail to dispatch the event, it is to clean up an obsolete
       // animation and should not notify the delegate.
       // TODO(gerchiko): Determine when we expect the referenced animations not
@@ -324,17 +185,11 @@
 }
 
 size_t Animation::TickingKeyframeModelsCount() const {
-  size_t count = 0;
-  for (auto& keyframe_effect : keyframe_effects_)
-    count += keyframe_effect->TickingKeyframeModelsCount();
-  return count;
+  return keyframe_effect_->TickingKeyframeModelsCount();
 }
 
 bool Animation::AffectsCustomProperty() const {
-  for (const auto& keyframe_effect : keyframe_effects_)
-    if (keyframe_effect->AffectsCustomProperty())
-      return true;
-  return false;
+  return keyframe_effect_->AffectsCustomProperty();
 }
 
 void Animation::SetNeedsCommit() {
@@ -348,50 +203,61 @@
   animation_timeline_->SetNeedsPushProperties();
 }
 
-void Animation::ActivateKeyframeEffects() {
-  for (auto& keyframe_effect : keyframe_effects_) {
-    keyframe_effect->ActivateKeyframeEffects();
-    keyframe_effect->UpdateTickingState();
-  }
+void Animation::ActivateKeyframeModels() {
+  keyframe_effect_->ActivateKeyframeModels();
+  keyframe_effect_->UpdateTickingState();
 }
 
-KeyframeModel* Animation::GetKeyframeModelForKeyframeEffect(
-    TargetProperty::Type target_property,
-    KeyframeEffectId keyframe_effect_id) const {
-  DCHECK(GetKeyframeEffectById(keyframe_effect_id));
-  return GetKeyframeEffectById(keyframe_effect_id)
-      ->GetKeyframeModel(target_property);
+KeyframeModel* Animation::GetKeyframeModel(
+    TargetProperty::Type target_property) const {
+  return keyframe_effect_->GetKeyframeModel(target_property);
 }
 
 std::string Animation::ToString() const {
-  std::string output = base::StringPrintf("Animation{id=%d", id_);
-  for (const auto& keyframe_effect : keyframe_effects_) {
-    output +=
-        base::StringPrintf(", element_id=%s, keyframe_models=[%s]",
-                           keyframe_effect->element_id().ToString().c_str(),
-                           keyframe_effect->KeyframeModelsToString().c_str());
-  }
-  return output + "}";
+  return base::StringPrintf(
+      "Animation{id=%d, element_id=%s, keyframe_models=[%s]}", id_,
+      keyframe_effect_->element_id().ToString().c_str(),
+      keyframe_effect_->KeyframeModelsToString().c_str());
 }
 
 bool Animation::IsWorkletAnimation() const {
   return false;
 }
 
-void Animation::AddKeyframeEffect(
-    std::unique_ptr<KeyframeEffect> keyframe_effect) {
-  keyframe_effect->SetAnimation(this);
-  keyframe_effects_.push_back(std::move(keyframe_effect));
-
-  SetNeedsPushProperties();
+void Animation::AddKeyframeModel(
+    std::unique_ptr<KeyframeModel> keyframe_model) {
+  keyframe_effect_->AddKeyframeModel(std::move(keyframe_model));
 }
 
-KeyframeEffect* Animation::GetKeyframeEffectById(
-    KeyframeEffectId keyframe_effect_id) const {
-  // May return nullptr when syncing keyframe_effects_ to impl.
-  return keyframe_effects_.size() > keyframe_effect_id
-             ? keyframe_effects_[keyframe_effect_id].get()
-             : nullptr;
+void Animation::PauseKeyframeModel(int keyframe_model_id,
+                                   base::TimeDelta time_offset) {
+  keyframe_effect_->PauseKeyframeModel(keyframe_model_id, time_offset);
+}
+
+void Animation::RemoveKeyframeModel(int keyframe_model_id) {
+  keyframe_effect_->RemoveKeyframeModel(keyframe_model_id);
+}
+
+void Animation::AbortKeyframeModel(int keyframe_model_id) {
+  keyframe_effect_->AbortKeyframeModel(keyframe_model_id);
+}
+
+void Animation::AbortKeyframeModelsWithProperty(
+    TargetProperty::Type target_property,
+    bool needs_completion) {
+  keyframe_effect_->AbortKeyframeModelsWithProperty(target_property,
+                                                    needs_completion);
+}
+
+void Animation::NotifyKeyframeModelFinishedForTesting(
+    int timeline_id,
+    int keyframe_model_id,
+    TargetProperty::Type target_property,
+    int group_id) {
+  AnimationEvent event(AnimationEvent::FINISHED,
+                       {timeline_id, id(), keyframe_model_id}, group_id,
+                       target_property, base::TimeTicks());
+  DispatchAndDelegateAnimationEvent(event);
 }
 
 }  // namespace cc
diff --git a/cc/animation/animation.h b/cc/animation/animation.h
index 1188409b..1e03092 100644
--- a/cc/animation/animation.h
+++ b/cc/animation/animation.h
@@ -37,6 +37,8 @@
 //
 // Each Animation has a copy on the impl thread, and will take care of
 // synchronizing to/from the impl thread when requested.
+//
+// There is a 1:1 relationship between Animation and KeyframeEffect.
 class CC_ANIMATION_EXPORT Animation : public base::RefCounted<Animation> {
  public:
   static scoped_refptr<Animation> Create(int id);
@@ -46,7 +48,9 @@
   Animation& operator=(const Animation&) = delete;
 
   int id() const { return id_; }
-  typedef size_t KeyframeEffectId;
+  ElementId element_id() const;
+
+  KeyframeEffect* keyframe_effect() const { return keyframe_effect_.get(); }
 
   // Parent AnimationHost. Animation can be detached from AnimationTimeline.
   AnimationHost* animation_host() { return animation_host_; }
@@ -59,37 +63,32 @@
   const AnimationTimeline* animation_timeline() const {
     return animation_timeline_;
   }
-  virtual void SetAnimationTimeline(AnimationTimeline* timeline);
+  void SetAnimationTimeline(AnimationTimeline* timeline);
 
   // TODO(smcgruer): If/once ScrollTimeline is supported on normal Animations,
   // we will need to move the promotion logic from WorkletAnimation to here.
   virtual void PromoteScrollTimelinePendingToActive() {}
 
-  bool has_element_animations() const;
-  scoped_refptr<ElementAnimations> element_animations(
-      KeyframeEffectId keyframe_effect_id) const;
+  scoped_refptr<ElementAnimations> element_animations() const;
 
   void set_animation_delegate(AnimationDelegate* delegate) {
     animation_delegate_ = delegate;
   }
 
-  void AttachElementForKeyframeEffect(ElementId element_id,
-                                      KeyframeEffectId keyframe_effect_id);
-  void DetachElementForKeyframeEffect(ElementId element_id,
-                                      KeyframeEffectId keyframe_effect_id);
-  virtual void DetachElement();
+  void AttachElement(ElementId element_id);
+  void DetachElement();
 
-  void AddKeyframeModelForKeyframeEffect(
-      std::unique_ptr<KeyframeModel> keyframe_model,
-      KeyframeEffectId keyframe_effect_id);
-  void PauseKeyframeModelForKeyframeEffect(int keyframe_model_id,
-                                           base::TimeDelta time_offset,
-                                           KeyframeEffectId keyframe_effect_id);
-  void RemoveKeyframeModelForKeyframeEffect(
+  void AddKeyframeModel(std::unique_ptr<KeyframeModel> keyframe_model);
+  void PauseKeyframeModel(int keyframe_model_id, base::TimeDelta time_offset);
+  virtual void RemoveKeyframeModel(int keyframe_model_id);
+  void AbortKeyframeModel(int keyframe_model_id);
+
+  void NotifyKeyframeModelFinishedForTesting(
+      int timeline_id,
       int keyframe_model_id,
-      KeyframeEffectId keyframe_effect_id);
-  void AbortKeyframeModelForKeyframeEffect(int keyframe_model_id,
-                                           KeyframeEffectId keyframe_effect_id);
+      TargetProperty::Type target_property,
+      int group_id);
+
   void AbortKeyframeModelsWithProperty(TargetProperty::Type target_property,
                                        bool needs_completion);
 
@@ -116,43 +115,30 @@
   // Make KeyframeModels affect active elements if and only if they affect
   // pending elements. Any KeyframeModels that no longer affect any elements
   // are deleted.
-  void ActivateKeyframeEffects();
+  void ActivateKeyframeModels();
 
   // Returns the keyframe model animating the given property that is either
   // running, or is next to run, if such a keyframe model exists.
-  KeyframeModel* GetKeyframeModelForKeyframeEffect(
-      TargetProperty::Type target_property,
-      KeyframeEffectId keyframe_effect_id) const;
+  KeyframeModel* GetKeyframeModel(TargetProperty::Type target_property) const;
 
   std::string ToString() const;
 
   void SetNeedsCommit();
 
   virtual bool IsWorkletAnimation() const;
-  void AddKeyframeEffect(std::unique_ptr<KeyframeEffect>);
-
-  KeyframeEffect* GetKeyframeEffectById(
-      KeyframeEffectId keyframe_effect_id) const;
-  KeyframeEffectId NextKeyframeEffectId() { return keyframe_effects_.size(); }
 
  private:
   friend class base::RefCounted<Animation>;
 
-  void RegisterKeyframeEffect(ElementId element_id,
-                              KeyframeEffectId keyframe_effect_id);
-  void UnregisterKeyframeEffect(ElementId element_id,
-                                KeyframeEffectId keyframe_effect_id);
-  void RegisterKeyframeEffects();
-  void UnregisterKeyframeEffects();
-
-  void PushAttachedKeyframeEffectsToImplThread(Animation* animation_impl) const;
-  void PushPropertiesToImplThread(Animation* animation_impl);
+  void RegisterAnimation();
+  void UnregisterAnimation();
 
   // Delegates animation event
   void DelegateAnimationEvent(const AnimationEvent& event);
 
  protected:
   explicit Animation(int id);
+  Animation(int id, std::unique_ptr<KeyframeEffect>);
   virtual ~Animation();
 
   AnimationHost* animation_host_;
@@ -160,19 +146,7 @@
   AnimationDelegate* animation_delegate_;
 
   int id_;
-
-  using ElementToKeyframeEffectIdMap =
-      std::unordered_map<ElementId,
-                         std::unordered_set<KeyframeEffectId>,
-                         ElementIdHash>;
-  using KeyframeEffects = std::vector<std::unique_ptr<KeyframeEffect>>;
-
-  // It is possible for a keyframe_effect to be in keyframe_effects_ but not in
-  // element_to_keyframe_effect_id_map_ but the reverse is not possible.
-  ElementToKeyframeEffectIdMap element_to_keyframe_effect_id_map_;
-  KeyframeEffects keyframe_effects_;
-
-  int ticking_keyframe_effects_count;
+  std::unique_ptr<KeyframeEffect> keyframe_effect_;
 };
 
 }  // namespace cc
diff --git a/cc/animation/animation_events.cc b/cc/animation/animation_events.cc
index 1382569b..b972b02 100644
--- a/cc/animation/animation_events.cc
+++ b/cc/animation/animation_events.cc
@@ -27,7 +27,7 @@
       // Also initializing keyframe_id with 0 which in its case is a valid
       // value. However this is safe since keyframe_id and model_id are not used
       // when routing a TIME_UPDATED event.
-      uid({timeline_id, animation_id, 0, 0}),
+      uid({timeline_id, animation_id, 0}),
       group_id(),
       target_property(),
       monotonic_time(),
diff --git a/cc/animation/animation_events.h b/cc/animation/animation_events.h
index 2835c41..99eb6804b 100644
--- a/cc/animation/animation_events.h
+++ b/cc/animation/animation_events.h
@@ -21,7 +21,6 @@
   struct UniqueKeyframeModelId {
     int timeline_id;
     int animation_id;
-    KeyframeEffectId effect_id;
     int model_id;
   };
 
diff --git a/cc/animation/animation_host.cc b/cc/animation/animation_host.cc
index ceffe592..a6280e84f 100644
--- a/cc/animation/animation_host.cc
+++ b/cc/animation/animation_host.cc
@@ -19,7 +19,6 @@
 #include "cc/animation/animation_id_provider.h"
 #include "cc/animation/animation_timeline.h"
 #include "cc/animation/element_animations.h"
-#include "cc/animation/keyframe_effect.h"
 #include "cc/animation/scroll_offset_animation_curve.h"
 #include "cc/animation/scroll_offset_animations.h"
 #include "cc/animation/scroll_offset_animations_impl.h"
@@ -172,11 +171,10 @@
     element_animations->ElementIdUnregistered(element_id, list_type);
 }
 
-void AnimationHost::RegisterKeyframeEffectForElement(
-    ElementId element_id,
-    KeyframeEffect* keyframe_effect) {
+void AnimationHost::RegisterAnimationForElement(ElementId element_id,
+                                                Animation* animation) {
   DCHECK(element_id);
-  DCHECK(keyframe_effect);
+  DCHECK(animation);
 
   scoped_refptr<ElementAnimations> element_animations =
       GetElementAnimationsForElementId(element_id);
@@ -188,14 +186,13 @@
 
   DCHECK(element_animations->AnimationHostIs(this));
 
-  element_animations->AddKeyframeEffect(keyframe_effect);
+  element_animations->AddKeyframeEffect(animation->keyframe_effect());
 }
 
-void AnimationHost::UnregisterKeyframeEffectForElement(
-    ElementId element_id,
-    KeyframeEffect* keyframe_effect) {
+void AnimationHost::UnregisterAnimationForElement(ElementId element_id,
+                                                  Animation* animation) {
   DCHECK(element_id);
-  DCHECK(keyframe_effect);
+  DCHECK(animation);
 
   scoped_refptr<ElementAnimations> element_animations =
       GetElementAnimationsForElementId(element_id);
@@ -207,13 +204,15 @@
   PropertyToElementIdMap element_id_map =
       element_animations->GetPropertyToElementIdMap();
 
-  element_animations->RemoveKeyframeEffect(keyframe_effect);
+  element_animations->RemoveKeyframeEffect(animation->keyframe_effect());
 
   if (element_animations->IsEmpty()) {
     element_animations->ClearAffectedElementTypes(element_id_map);
     element_to_animations_map_.erase(element_animations->element_id());
     element_animations->ClearAnimationHost();
   }
+
+  RemoveFromTicking(animation);
 }
 
 void AnimationHost::SetMutatorHostClient(MutatorHostClient* client) {
@@ -379,7 +378,7 @@
   TRACE_EVENT0("cc", "AnimationHost::ActivateAnimations");
   AnimationsList ticking_animations_copy = ticking_animations_;
   for (auto& it : ticking_animations_copy) {
-    it->ActivateKeyframeEffects();
+    it->ActivateKeyframeModels();
     // Finish animations which no longer affect active or pending elements.
     it->UpdateState(false, animation_events);
   }
diff --git a/cc/animation/animation_host.h b/cc/animation/animation_host.h
index af99fca9..327248a1 100644
--- a/cc/animation/animation_host.h
+++ b/cc/animation/animation_host.h
@@ -29,7 +29,6 @@
 class AnimationTimeline;
 class ElementAnimations;
 class LayerTreeHost;
-class KeyframeEffect;
 class ScrollOffsetAnimations;
 class ScrollOffsetAnimationsImpl;
 class WorkletAnimation;
@@ -66,10 +65,9 @@
   void RemoveAnimationTimeline(scoped_refptr<AnimationTimeline> timeline);
   AnimationTimeline* GetTimelineById(int timeline_id) const;
 
-  void RegisterKeyframeEffectForElement(ElementId element_id,
-                                        KeyframeEffect* keyframe_effect);
-  void UnregisterKeyframeEffectForElement(ElementId element_id,
-                                          KeyframeEffect* keyframe_effect);
+  void RegisterAnimationForElement(ElementId element_id, Animation* animation);
+  void UnregisterAnimationForElement(ElementId element_id,
+                                     Animation* animation);
 
   scoped_refptr<ElementAnimations> GetElementAnimationsForElementId(
       ElementId element_id) const;
diff --git a/cc/animation/animation_host_perftest.cc b/cc/animation/animation_host_perftest.cc
index b9926f4..faf7a36d 100644
--- a/cc/animation/animation_host_perftest.cc
+++ b/cc/animation/animation_host_perftest.cc
@@ -6,10 +6,9 @@
 
 #include "base/threading/thread_task_runner_handle.h"
 #include "base/timer/lap_timer.h"
+#include "cc/animation/animation.h"
 #include "cc/animation/animation_id_provider.h"
 #include "cc/animation/animation_timeline.h"
-#include "cc/animation/keyframe_effect.h"
-#include "cc/animation/single_keyframe_effect_animation.h"
 #include "cc/test/fake_impl_task_runner_provider.h"
 #include "cc/test/fake_layer_tree_host.h"
 #include "cc/test/fake_layer_tree_host_client.h"
@@ -70,14 +69,13 @@
       root_layer_->AddChild(layer);
       layer->SetElementId(LayerIdToElementIdForTesting(layer->id()));
 
-      scoped_refptr<SingleKeyframeEffectAnimation> animation =
-          SingleKeyframeEffectAnimation::Create(last_animation_id_);
+      scoped_refptr<Animation> animation =
+          Animation::Create(last_animation_id_);
       last_animation_id_ = AnimationIdProvider::NextAnimationId();
 
       all_animations_timeline_->AttachAnimation(animation);
       animation->AttachElement(layer->element_id());
-      EXPECT_TRUE(
-          animation->element_animations(animation->keyframe_effect()->id()));
+      EXPECT_TRUE(animation->element_animations());
     }
 
     // Create impl animations.
diff --git a/cc/animation/animation_timeline.cc b/cc/animation/animation_timeline.cc
index 0d57f639..143745c 100644
--- a/cc/animation/animation_timeline.cc
+++ b/cc/animation/animation_timeline.cc
@@ -118,7 +118,7 @@
 }
 
 void AnimationTimeline::EraseAnimation(scoped_refptr<Animation> animation) {
-  if (animation->has_element_animations())
+  if (animation->element_animations())
     animation->DetachElement();
   animation->SetAnimationTimeline(nullptr);
   animation->SetAnimationHost(nullptr);
diff --git a/cc/animation/animation_timeline_unittest.cc b/cc/animation/animation_timeline_unittest.cc
index e6c9874..3d6220f 100644
--- a/cc/animation/animation_timeline_unittest.cc
+++ b/cc/animation/animation_timeline_unittest.cc
@@ -4,9 +4,9 @@
 
 #include "cc/animation/animation_timeline.h"
 
+#include "cc/animation/animation.h"
 #include "cc/animation/animation_host.h"
 #include "cc/animation/animation_id_provider.h"
-#include "cc/animation/single_keyframe_effect_animation.h"
 #include "cc/test/animation_test_common.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -34,8 +34,7 @@
   host_impl->AddAnimationTimeline(timeline_impl.get());
   EXPECT_TRUE(timeline_impl->animation_host());
 
-  scoped_refptr<SingleKeyframeEffectAnimation> animation(
-      SingleKeyframeEffectAnimation::Create(animation_id));
+  scoped_refptr<Animation> animation(Animation::Create(animation_id));
   timeline->AttachAnimation(animation.get());
   EXPECT_TRUE(animation->animation_timeline());
 
@@ -79,11 +78,9 @@
   host->AddAnimationTimeline(timeline.get());
   host_impl->AddAnimationTimeline(timeline_impl.get());
 
-  scoped_refptr<SingleKeyframeEffectAnimation> animation1(
-      SingleKeyframeEffectAnimation::Create(animation_id1));
+  scoped_refptr<Animation> animation1(Animation::Create(animation_id1));
   timeline->AttachAnimation(animation1.get());
-  scoped_refptr<SingleKeyframeEffectAnimation> animation2(
-      SingleKeyframeEffectAnimation::Create(animation_id2));
+  scoped_refptr<Animation> animation2(Animation::Create(animation_id2));
   timeline->AttachAnimation(animation2.get());
 
   timeline->PushPropertiesTo(timeline_impl.get());
diff --git a/cc/animation/animation_unittest.cc b/cc/animation/animation_unittest.cc
index 51249fec..360400e 100644
--- a/cc/animation/animation_unittest.cc
+++ b/cc/animation/animation_unittest.cc
@@ -9,10 +9,10 @@
 #include "base/strings/stringprintf.h"
 #include "cc/animation/animation_delegate.h"
 #include "cc/animation/animation_host.h"
+#include "cc/animation/animation_id_provider.h"
 #include "cc/animation/animation_timeline.h"
 #include "cc/animation/element_animations.h"
 #include "cc/animation/keyframe_effect.h"
-#include "cc/animation/keyframed_animation_curve.h"
 #include "cc/test/animation_test_common.h"
 #include "cc/test/animation_timelines_test_common.h"
 
@@ -21,45 +21,22 @@
 
 class AnimationTest : public AnimationTimelinesTest {
  public:
-  AnimationTest() : animation_(Animation::Create(animation_id_)) {
-    keyframe_effect_id_ = animation_->NextKeyframeEffectId();
-  }
+  AnimationTest() = default;
   ~AnimationTest() override = default;
-
-  void CheckKeyframeEffectAndTimelineNeedsPushProperties(
-      bool needs_push_properties,
-      KeyframeEffectId keyframe_effect_id) const {
-    KeyframeEffect* keyframe_effect =
-        animation_->GetKeyframeEffectById(keyframe_effect_id);
-    EXPECT_EQ(keyframe_effect->needs_push_properties(), needs_push_properties);
-    EXPECT_EQ(timeline_->needs_push_properties(), needs_push_properties);
-  }
-
- protected:
-  scoped_refptr<Animation> animation_;
-  scoped_refptr<Animation> animation_impl_;
-  KeyframeEffectId keyframe_effect_id_;
 };
 // See element_animations_unittest.cc for active/pending observers tests.
 
 TEST_F(AnimationTest, AttachDetachLayerIfTimelineAttached) {
-  animation_->AddKeyframeEffect(
-      std::make_unique<KeyframeEffect>(keyframe_effect_id_));
-  ASSERT_TRUE(animation_->GetKeyframeEffectById(keyframe_effect_id_));
-  EXPECT_FALSE(animation_->GetKeyframeEffectById(keyframe_effect_id_)
-                   ->needs_push_properties());
-  CheckKeyframeEffectAndTimelineNeedsPushProperties(false, keyframe_effect_id_);
+  EXPECT_TRUE(CheckKeyframeEffectTimelineNeedsPushProperties(false));
 
   host_->AddAnimationTimeline(timeline_);
   EXPECT_TRUE(timeline_->needs_push_properties());
+  EXPECT_FALSE(animation_->keyframe_effect()->needs_push_properties());
 
   timeline_->AttachAnimation(animation_);
-  EXPECT_FALSE(animation_->element_animations(keyframe_effect_id_));
+  EXPECT_FALSE(animation_->element_animations());
   EXPECT_TRUE(timeline_->needs_push_properties());
-  EXPECT_FALSE(
-      animation_->GetKeyframeEffectById(keyframe_effect_id_)->element_id());
-  EXPECT_FALSE(animation_->GetKeyframeEffectById(keyframe_effect_id_)
-                   ->needs_push_properties());
+  EXPECT_FALSE(animation_->keyframe_effect()->needs_push_properties());
 
   host_->PushPropertiesTo(host_impl_);
 
@@ -70,106 +47,78 @@
   animation_impl_ = timeline_impl_->GetAnimationById(animation_id_);
   EXPECT_TRUE(animation_impl_);
 
-  EXPECT_FALSE(animation_impl_->element_animations(keyframe_effect_id_));
-  EXPECT_FALSE(animation_impl_->GetKeyframeEffectById(keyframe_effect_id_)
-                   ->element_id());
-  EXPECT_FALSE(animation_->GetKeyframeEffectById(keyframe_effect_id_)
-                   ->needs_push_properties());
+  EXPECT_FALSE(animation_impl_->element_animations());
+  EXPECT_FALSE(animation_impl_->keyframe_effect()->element_id());
+  EXPECT_FALSE(animation_->keyframe_effect()->needs_push_properties());
   EXPECT_FALSE(timeline_->needs_push_properties());
 
-  animation_->AttachElementForKeyframeEffect(element_id_, keyframe_effect_id_);
-  EXPECT_EQ(animation_->GetKeyframeEffectById(keyframe_effect_id_),
+  animation_->AttachElement(element_id_);
+  EXPECT_EQ(animation_->keyframe_effect(),
             GetKeyframeEffectForElementId(element_id_));
-  EXPECT_TRUE(animation_->element_animations(keyframe_effect_id_));
-  EXPECT_EQ(
-      animation_->GetKeyframeEffectById(keyframe_effect_id_)->element_id(),
-      element_id_);
-  CheckKeyframeEffectAndTimelineNeedsPushProperties(true, keyframe_effect_id_);
+  EXPECT_TRUE(animation_->element_animations());
+  EXPECT_EQ(animation_->keyframe_effect()->element_id(), element_id_);
+  CheckKeyframeEffectTimelineNeedsPushProperties(true);
 
   host_->PushPropertiesTo(host_impl_);
 
-  EXPECT_EQ(animation_impl_->GetKeyframeEffectById(keyframe_effect_id_),
+  EXPECT_EQ(animation_impl_->keyframe_effect(),
             GetImplKeyframeEffectForLayerId(element_id_));
-  EXPECT_TRUE(animation_impl_->element_animations(keyframe_effect_id_));
-  EXPECT_EQ(
-      animation_impl_->GetKeyframeEffectById(keyframe_effect_id_)->element_id(),
-      element_id_);
-  CheckKeyframeEffectAndTimelineNeedsPushProperties(false, keyframe_effect_id_);
+  EXPECT_TRUE(animation_impl_->element_animations());
+  EXPECT_EQ(animation_impl_->keyframe_effect()->element_id(), element_id_);
+  CheckKeyframeEffectTimelineNeedsPushProperties(false);
 
   animation_->DetachElement();
   EXPECT_FALSE(GetKeyframeEffectForElementId(element_id_));
-  EXPECT_FALSE(animation_->element_animations(keyframe_effect_id_));
-  EXPECT_FALSE(
-      animation_->GetKeyframeEffectById(keyframe_effect_id_)->element_id());
-  CheckKeyframeEffectAndTimelineNeedsPushProperties(true, keyframe_effect_id_);
+  EXPECT_FALSE(animation_->element_animations());
+  EXPECT_FALSE(animation_->keyframe_effect()->element_id());
+  CheckKeyframeEffectTimelineNeedsPushProperties(true);
 
   host_->PushPropertiesTo(host_impl_);
 
   EXPECT_FALSE(GetImplKeyframeEffectForLayerId(element_id_));
-  EXPECT_FALSE(animation_impl_->element_animations(keyframe_effect_id_));
-  EXPECT_FALSE(animation_impl_->GetKeyframeEffectById(keyframe_effect_id_)
-                   ->element_id());
-  CheckKeyframeEffectAndTimelineNeedsPushProperties(false, keyframe_effect_id_);
+  EXPECT_FALSE(animation_impl_->element_animations());
+  EXPECT_FALSE(animation_impl_->keyframe_effect()->element_id());
+  CheckKeyframeEffectTimelineNeedsPushProperties(false);
 
   timeline_->DetachAnimation(animation_);
   EXPECT_FALSE(animation_->animation_timeline());
-  EXPECT_FALSE(animation_->element_animations(keyframe_effect_id_));
-  EXPECT_FALSE(
-      animation_->GetKeyframeEffectById(keyframe_effect_id_)->element_id());
+  EXPECT_FALSE(animation_->element_animations());
+  EXPECT_FALSE(animation_->keyframe_effect()->element_id());
   EXPECT_TRUE(timeline_->needs_push_properties());
-  EXPECT_FALSE(animation_->GetKeyframeEffectById(keyframe_effect_id_)
-                   ->needs_push_properties());
+  EXPECT_FALSE(animation_->keyframe_effect()->needs_push_properties());
   host_->PushPropertiesTo(host_impl_);
-  CheckKeyframeEffectAndTimelineNeedsPushProperties(false, keyframe_effect_id_);
+  CheckKeyframeEffectTimelineNeedsPushProperties(false);
 }
 
 TEST_F(AnimationTest, AttachDetachTimelineIfLayerAttached) {
   host_->AddAnimationTimeline(timeline_);
 
-  animation_->AddKeyframeEffect(
-      std::make_unique<KeyframeEffect>(keyframe_effect_id_));
-  ASSERT_TRUE(animation_->GetKeyframeEffectById(keyframe_effect_id_));
+  EXPECT_FALSE(animation_->keyframe_effect()->element_animations());
+  EXPECT_FALSE(animation_->keyframe_effect()->element_id());
+  EXPECT_FALSE(animation_->keyframe_effect()->needs_push_properties());
 
-  EXPECT_FALSE(animation_->GetKeyframeEffectById(keyframe_effect_id_)
-                   ->element_animations());
-  EXPECT_FALSE(
-      animation_->GetKeyframeEffectById(keyframe_effect_id_)->element_id());
-  EXPECT_FALSE(animation_->GetKeyframeEffectById(keyframe_effect_id_)
-                   ->needs_push_properties());
-
-  animation_->AttachElementForKeyframeEffect(element_id_, keyframe_effect_id_);
+  animation_->AttachElement(element_id_);
   EXPECT_FALSE(animation_->animation_timeline());
   EXPECT_FALSE(GetKeyframeEffectForElementId(element_id_));
-  EXPECT_FALSE(animation_->GetKeyframeEffectById(keyframe_effect_id_)
-                   ->element_animations());
-  EXPECT_EQ(
-      animation_->GetKeyframeEffectById(keyframe_effect_id_)->element_id(),
-      element_id_);
-  EXPECT_FALSE(animation_->GetKeyframeEffectById(keyframe_effect_id_)
-                   ->needs_push_properties());
+  EXPECT_FALSE(animation_->keyframe_effect()->element_animations());
+  EXPECT_EQ(animation_->keyframe_effect()->element_id(), element_id_);
+  EXPECT_FALSE(animation_->keyframe_effect()->needs_push_properties());
 
   timeline_->AttachAnimation(animation_);
   EXPECT_EQ(timeline_, animation_->animation_timeline());
-  EXPECT_EQ(animation_->GetKeyframeEffectById(keyframe_effect_id_),
+  EXPECT_EQ(animation_->keyframe_effect(),
             GetKeyframeEffectForElementId(element_id_));
-  EXPECT_TRUE(animation_->GetKeyframeEffectById(keyframe_effect_id_)
-                  ->element_animations());
-  EXPECT_EQ(
-      animation_->GetKeyframeEffectById(keyframe_effect_id_)->element_id(),
-      element_id_);
-  EXPECT_TRUE(animation_->GetKeyframeEffectById(keyframe_effect_id_)
-                  ->needs_push_properties());
+  EXPECT_TRUE(animation_->keyframe_effect()->element_animations());
+  EXPECT_EQ(animation_->keyframe_effect()->element_id(), element_id_);
+  EXPECT_TRUE(animation_->keyframe_effect()->needs_push_properties());
 
   // Removing animation from timeline detaches layer.
   timeline_->DetachAnimation(animation_);
   EXPECT_FALSE(animation_->animation_timeline());
   EXPECT_FALSE(GetKeyframeEffectForElementId(element_id_));
-  EXPECT_FALSE(animation_->GetKeyframeEffectById(keyframe_effect_id_)
-                   ->element_animations());
-  EXPECT_FALSE(
-      animation_->GetKeyframeEffectById(keyframe_effect_id_)->element_id());
-  EXPECT_TRUE(animation_->GetKeyframeEffectById(keyframe_effect_id_)
-                  ->needs_push_properties());
+  EXPECT_FALSE(animation_->keyframe_effect()->element_animations());
+  EXPECT_FALSE(animation_->keyframe_effect()->element_id());
+  EXPECT_TRUE(animation_->keyframe_effect()->needs_push_properties());
 }
 
 TEST_F(AnimationTest, PropertiesMutate) {
@@ -179,16 +128,12 @@
 
   host_->AddAnimationTimeline(timeline_);
 
-  animation_->AddKeyframeEffect(
-      std::make_unique<KeyframeEffect>(keyframe_effect_id_));
-  ASSERT_TRUE(animation_->GetKeyframeEffectById(keyframe_effect_id_));
-
   timeline_->AttachAnimation(animation_);
-  animation_->AttachElementForKeyframeEffect(element_id_, keyframe_effect_id_);
-  CheckKeyframeEffectAndTimelineNeedsPushProperties(true, keyframe_effect_id_);
+  animation_->AttachElement(element_id_);
+  CheckKeyframeEffectTimelineNeedsPushProperties(true);
 
   host_->PushPropertiesTo(host_impl_);
-  CheckKeyframeEffectAndTimelineNeedsPushProperties(false, keyframe_effect_id_);
+  CheckKeyframeEffectTimelineNeedsPushProperties(false);
 
   const float start_opacity = .7f;
   const float end_opacity = .3f;
@@ -205,18 +150,18 @@
   const double duration = 1.;
 
   AddOpacityTransitionToAnimation(animation_.get(), duration, start_opacity,
-                                  end_opacity, false, keyframe_effect_id_);
+                                  end_opacity, false);
 
   AddAnimatedTransformToAnimation(animation_.get(), duration, transform_x,
-                                  transform_y, keyframe_effect_id_);
+                                  transform_y);
   AddAnimatedFilterToAnimation(animation_.get(), duration, start_brightness,
-                               end_brightness, keyframe_effect_id_);
+                               end_brightness);
   AddAnimatedBackdropFilterToAnimation(animation_.get(), duration, start_invert,
-                                       end_invert, keyframe_effect_id_);
-  CheckKeyframeEffectAndTimelineNeedsPushProperties(true, keyframe_effect_id_);
+                                       end_invert);
+  CheckKeyframeEffectTimelineNeedsPushProperties(true);
 
   host_->PushPropertiesTo(host_impl_);
-  CheckKeyframeEffectAndTimelineNeedsPushProperties(false, keyframe_effect_id_);
+  CheckKeyframeEffectTimelineNeedsPushProperties(false);
 
   EXPECT_FALSE(client_.IsPropertyMutated(element_id_, ElementListType::ACTIVE,
                                          TargetProperty::OPACITY));
@@ -241,11 +186,11 @@
   base::TimeTicks time;
   time += base::TimeDelta::FromSecondsD(0.1);
   TickAnimationsTransferEvents(time, 4u);
-  CheckKeyframeEffectAndTimelineNeedsPushProperties(false, keyframe_effect_id_);
+  CheckKeyframeEffectTimelineNeedsPushProperties(false);
 
   time += base::TimeDelta::FromSecondsD(duration);
   TickAnimationsTransferEvents(time, 4u);
-  CheckKeyframeEffectAndTimelineNeedsPushProperties(true, keyframe_effect_id_);
+  CheckKeyframeEffectTimelineNeedsPushProperties(true);
 
   client_.ExpectOpacityPropertyMutated(element_id_, ElementListType::ACTIVE,
                                        end_opacity);
@@ -283,17 +228,10 @@
   client_impl_.RegisterElementId(element_id_, ElementListType::PENDING);
   client_impl_.RegisterElementId(element_id_, ElementListType::ACTIVE);
 
-  scoped_refptr<Animation> animation1 = Animation::Create(100);
-  scoped_refptr<Animation> animation2 = Animation::Create(200);
-
-  KeyframeEffectId keyframe_effect_id1 = animation1->NextKeyframeEffectId();
-  animation1->AddKeyframeEffect(
-      std::make_unique<KeyframeEffect>(keyframe_effect_id1));
-  ASSERT_TRUE(animation1->GetKeyframeEffectById(keyframe_effect_id1));
-  KeyframeEffectId keyframe_effect_id2 = animation2->NextKeyframeEffectId();
-  animation2->AddKeyframeEffect(
-      std::make_unique<KeyframeEffect>(keyframe_effect_id2));
-  ASSERT_TRUE(animation2->GetKeyframeEffectById(keyframe_effect_id2));
+  scoped_refptr<Animation> animation1 =
+      Animation::Create(AnimationIdProvider::NextAnimationId());
+  scoped_refptr<Animation> animation2 =
+      Animation::Create(AnimationIdProvider::NextAnimationId());
 
   host_->AddAnimationTimeline(timeline_);
 
@@ -307,8 +245,8 @@
   animation2->set_animation_delegate(&delegate2);
 
   // Attach animations to the same layer.
-  animation1->AttachElementForKeyframeEffect(element_id_, keyframe_effect_id1);
-  animation2->AttachElementForKeyframeEffect(element_id_, keyframe_effect_id2);
+  animation1->AttachElement(element_id_);
+  animation2->AttachElement(element_id_);
 
   const float start_opacity = .7f;
   const float end_opacity = .3f;
@@ -319,9 +257,9 @@
   const double duration = 1.;
 
   AddOpacityTransitionToAnimation(animation1.get(), duration, start_opacity,
-                                  end_opacity, false, keyframe_effect_id1);
+                                  end_opacity, false);
   AddAnimatedTransformToAnimation(animation2.get(), duration, transform_x,
-                                  transform_y, keyframe_effect_id2);
+                                  transform_y);
 
   host_->PushPropertiesTo(host_impl_);
   host_impl_->ActivateAnimations(nullptr);
@@ -342,10 +280,8 @@
   EXPECT_TRUE(delegate2.started());
   EXPECT_FALSE(delegate2.finished());
 
-  EXPECT_FALSE(animation1->GetKeyframeEffectById(keyframe_effect_id1)
-                   ->needs_push_properties());
-  EXPECT_FALSE(animation2->GetKeyframeEffectById(keyframe_effect_id2)
-                   ->needs_push_properties());
+  EXPECT_FALSE(animation1->keyframe_effect()->needs_push_properties());
+  EXPECT_FALSE(animation2->keyframe_effect()->needs_push_properties());
 
   time += base::TimeDelta::FromSecondsD(duration);
   TickAnimationsTransferEvents(time, 2u);
@@ -353,10 +289,8 @@
   EXPECT_TRUE(delegate1.finished());
   EXPECT_TRUE(delegate2.finished());
 
-  EXPECT_TRUE(animation1->GetKeyframeEffectById(keyframe_effect_id1)
-                  ->needs_push_properties());
-  EXPECT_TRUE(animation2->GetKeyframeEffectById(keyframe_effect_id2)
-                  ->needs_push_properties());
+  EXPECT_TRUE(animation1->keyframe_effect()->needs_push_properties());
+  EXPECT_TRUE(animation2->keyframe_effect()->needs_push_properties());
 
   client_.ExpectOpacityPropertyMutated(element_id_, ElementListType::ACTIVE,
                                        end_opacity);
@@ -379,46 +313,35 @@
   client_impl_.RegisterElementId(element_id_, ElementListType::PENDING);
   client_impl_.RegisterElementId(element_id_, ElementListType::ACTIVE);
 
-  animation_->AddKeyframeEffect(
-      std::make_unique<KeyframeEffect>(keyframe_effect_id_));
-  ASSERT_TRUE(animation_->GetKeyframeEffectById(keyframe_effect_id_));
-
   const double duration = 1.;
   const float start_opacity = .7f;
   const float end_opacity = .3f;
 
-  const int filter_id = AddAnimatedFilterToAnimation(
-      animation_.get(), duration, 0.1f, 0.9f, keyframe_effect_id_);
+  const int filter_id =
+      AddAnimatedFilterToAnimation(animation_.get(), duration, 0.1f, 0.9f);
   AddOpacityTransitionToAnimation(animation_.get(), duration, start_opacity,
-                                  end_opacity, false, keyframe_effect_id_);
+                                  end_opacity, false);
 
-  EXPECT_FALSE(animation_->GetKeyframeEffectById(keyframe_effect_id_)
-                   ->needs_push_properties());
+  EXPECT_FALSE(animation_->keyframe_effect()->needs_push_properties());
 
   host_->AddAnimationTimeline(timeline_);
   timeline_->AttachAnimation(animation_);
 
-  EXPECT_FALSE(animation_->GetKeyframeEffectById(keyframe_effect_id_)
-                   ->needs_push_properties());
-  EXPECT_FALSE(animation_->GetKeyframeEffectById(keyframe_effect_id_)
-                   ->element_animations());
-  animation_->RemoveKeyframeModelForKeyframeEffect(filter_id,
-                                                   keyframe_effect_id_);
-  EXPECT_FALSE(animation_->GetKeyframeEffectById(keyframe_effect_id_)
-                   ->needs_push_properties());
+  EXPECT_FALSE(animation_->keyframe_effect()->needs_push_properties());
+  EXPECT_FALSE(animation_->keyframe_effect()->element_animations());
+  animation_->RemoveKeyframeModel(filter_id);
+  EXPECT_FALSE(animation_->keyframe_effect()->needs_push_properties());
 
-  animation_->AttachElementForKeyframeEffect(element_id_, keyframe_effect_id_);
+  animation_->AttachElement(element_id_);
 
-  EXPECT_TRUE(animation_->GetKeyframeEffectById(keyframe_effect_id_)
-                  ->element_animations());
-  EXPECT_FALSE(animation_->GetKeyframeEffectById(keyframe_effect_id_)
+  EXPECT_TRUE(animation_->keyframe_effect()->element_animations());
+  EXPECT_FALSE(animation_->keyframe_effect()
                    ->element_animations()
                    ->HasAnyAnimationTargetingProperty(TargetProperty::FILTER));
-  EXPECT_TRUE(animation_->GetKeyframeEffectById(keyframe_effect_id_)
+  EXPECT_TRUE(animation_->keyframe_effect()
                   ->element_animations()
                   ->HasAnyAnimationTargetingProperty(TargetProperty::OPACITY));
-  EXPECT_TRUE(animation_->GetKeyframeEffectById(keyframe_effect_id_)
-                  ->needs_push_properties());
+  EXPECT_TRUE(animation_->keyframe_effect()->needs_push_properties());
 
   host_->PushPropertiesTo(host_impl_);
 
@@ -457,29 +380,24 @@
 TEST_F(AnimationTest, AddRemoveAnimationCausesSetNeedsCommit) {
   client_.RegisterElementId(element_id_, ElementListType::ACTIVE);
   host_->AddAnimationTimeline(timeline_);
-  animation_->AddKeyframeEffect(
-      std::make_unique<KeyframeEffect>(keyframe_effect_id_));
-  ASSERT_TRUE(animation_->GetKeyframeEffectById(keyframe_effect_id_));
-
   timeline_->AttachAnimation(animation_);
-  animation_->AttachElementForKeyframeEffect(element_id_, keyframe_effect_id_);
+  animation_->AttachElement(element_id_);
 
   EXPECT_TRUE(client_.mutators_need_commit());
   client_.set_mutators_need_commit(false);
 
-  const int keyframe_model_id = AddOpacityTransitionToAnimation(
-      animation_.get(), 1., .7f, .3f, false, keyframe_effect_id_);
+  const int keyframe_model_id =
+      AddOpacityTransitionToAnimation(animation_.get(), 1., .7f, .3f, false);
 
   EXPECT_TRUE(client_.mutators_need_commit());
   client_.set_mutators_need_commit(false);
 
-  animation_->PauseKeyframeModelForKeyframeEffect(
-      keyframe_model_id, base::TimeDelta::FromSeconds(1), keyframe_effect_id_);
+  animation_->PauseKeyframeModel(keyframe_model_id,
+                                 base::TimeDelta::FromSeconds(1));
   EXPECT_TRUE(client_.mutators_need_commit());
   client_.set_mutators_need_commit(false);
 
-  animation_->RemoveKeyframeModelForKeyframeEffect(keyframe_model_id,
-                                                   keyframe_effect_id_);
+  animation_->RemoveKeyframeModel(keyframe_model_id);
   EXPECT_TRUE(client_.mutators_need_commit());
   client_.set_mutators_need_commit(false);
 }
@@ -488,10 +406,8 @@
 // impl-thread animation must be switched as well.
 TEST_F(AnimationTest, SwitchToLayer) {
   host_->AddAnimationTimeline(timeline_);
-  animation_->AddKeyframeEffect(
-      std::make_unique<KeyframeEffect>(keyframe_effect_id_));
   timeline_->AttachAnimation(animation_);
-  animation_->AttachElementForKeyframeEffect(element_id_, keyframe_effect_id_);
+  animation_->AttachElement(element_id_);
 
   host_->PushPropertiesTo(host_impl_);
 
@@ -500,65 +416,49 @@
   animation_impl_ = timeline_impl_->GetAnimationById(animation_id_);
   EXPECT_TRUE(animation_impl_);
 
-  EXPECT_EQ(animation_->GetKeyframeEffectById(keyframe_effect_id_),
+  EXPECT_EQ(animation_->keyframe_effect(),
             GetKeyframeEffectForElementId(element_id_));
-  EXPECT_TRUE(animation_->GetKeyframeEffectById(keyframe_effect_id_)
-                  ->element_animations());
-  EXPECT_EQ(
-      animation_->GetKeyframeEffectById(keyframe_effect_id_)->element_id(),
-      element_id_);
+  EXPECT_TRUE(animation_->keyframe_effect()->element_animations());
+  EXPECT_EQ(animation_->keyframe_effect()->element_id(), element_id_);
 
   timeline_impl_ = host_impl_->GetTimelineById(timeline_id_);
   EXPECT_TRUE(timeline_impl_);
   animation_impl_ = timeline_impl_->GetAnimationById(animation_id_);
   EXPECT_TRUE(animation_impl_);
-  EXPECT_EQ(animation_impl_->GetKeyframeEffectById(keyframe_effect_id_),
+  EXPECT_EQ(animation_impl_->keyframe_effect(),
             GetImplKeyframeEffectForLayerId(element_id_));
-  EXPECT_TRUE(animation_impl_->GetKeyframeEffectById(keyframe_effect_id_)
-                  ->element_animations());
-  EXPECT_EQ(
-      animation_impl_->GetKeyframeEffectById(keyframe_effect_id_)->element_id(),
-      element_id_);
-  CheckKeyframeEffectAndTimelineNeedsPushProperties(false, keyframe_effect_id_);
+  EXPECT_TRUE(animation_impl_->keyframe_effect()->element_animations());
+  EXPECT_EQ(animation_impl_->keyframe_effect()->element_id(), element_id_);
+  CheckKeyframeEffectTimelineNeedsPushProperties(false);
 
   const ElementId new_element_id(NextTestLayerId());
   animation_->DetachElement();
-  animation_->AttachElementForKeyframeEffect(new_element_id,
-                                             keyframe_effect_id_);
+  animation_->AttachElement(new_element_id);
 
-  EXPECT_EQ(animation_->GetKeyframeEffectById(keyframe_effect_id_),
+  EXPECT_EQ(animation_->keyframe_effect(),
             GetKeyframeEffectForElementId(new_element_id));
-  EXPECT_TRUE(animation_->GetKeyframeEffectById(keyframe_effect_id_)
-                  ->element_animations());
-  EXPECT_EQ(
-      animation_->GetKeyframeEffectById(keyframe_effect_id_)->element_id(),
-      new_element_id);
-  CheckKeyframeEffectAndTimelineNeedsPushProperties(true, keyframe_effect_id_);
+  EXPECT_TRUE(animation_->keyframe_effect()->element_animations());
+  EXPECT_EQ(animation_->keyframe_effect()->element_id(), new_element_id);
+  CheckKeyframeEffectTimelineNeedsPushProperties(true);
 
   host_->PushPropertiesTo(host_impl_);
 
-  EXPECT_EQ(animation_impl_->GetKeyframeEffectById(keyframe_effect_id_),
+  EXPECT_EQ(animation_impl_->keyframe_effect(),
             GetImplKeyframeEffectForLayerId(new_element_id));
-  EXPECT_TRUE(animation_impl_->GetKeyframeEffectById(keyframe_effect_id_)
-                  ->element_animations());
-  EXPECT_EQ(
-      animation_impl_->GetKeyframeEffectById(keyframe_effect_id_)->element_id(),
-      new_element_id);
+  EXPECT_TRUE(animation_impl_->keyframe_effect()->element_animations());
+  EXPECT_EQ(animation_impl_->keyframe_effect()->element_id(), new_element_id);
 }
 
 TEST_F(AnimationTest, ToString) {
-  animation_->AddKeyframeEffect(
-      std::make_unique<KeyframeEffect>(keyframe_effect_id_));
-  animation_->AttachElementForKeyframeEffect(element_id_, keyframe_effect_id_);
+  animation_->AttachElement(element_id_);
   EXPECT_EQ(
       base::StringPrintf("Animation{id=%d, element_id=%s, keyframe_models=[]}",
                          animation_->id(), element_id_.ToString().c_str()),
       animation_->ToString());
 
-  animation_->AddKeyframeModelForKeyframeEffect(
+  animation_->AddKeyframeModel(
       KeyframeModel::Create(std::make_unique<FakeFloatAnimationCurve>(15), 42,
-                            73, TargetProperty::OPACITY),
-      keyframe_effect_id_);
+                            73, TargetProperty::OPACITY));
   EXPECT_EQ(
       base::StringPrintf("Animation{id=%d, element_id=%s, "
                          "keyframe_models=[KeyframeModel{id=42, "
@@ -567,10 +467,9 @@
                          animation_->id(), element_id_.ToString().c_str()),
       animation_->ToString());
 
-  animation_->AddKeyframeModelForKeyframeEffect(
+  animation_->AddKeyframeModel(
       KeyframeModel::Create(std::make_unique<FakeFloatAnimationCurve>(18), 45,
-                            76, TargetProperty::BOUNDS),
-      keyframe_effect_id_);
+                            76, TargetProperty::BOUNDS));
   EXPECT_EQ(
       base::StringPrintf(
           "Animation{id=%d, element_id=%s, "
@@ -581,429 +480,6 @@
           "target_property_id=5, run_state=WAITING_FOR_TARGET_AVAILABILITY}]}",
           animation_->id(), element_id_.ToString().c_str()),
       animation_->ToString());
-
-  KeyframeEffectId second_keyframe_effect_id =
-      animation_->NextKeyframeEffectId();
-  ElementId second_element_id(NextTestLayerId());
-  animation_->AddKeyframeEffect(
-      std::make_unique<KeyframeEffect>(second_keyframe_effect_id));
-  animation_->AttachElementForKeyframeEffect(second_element_id,
-                                             second_keyframe_effect_id);
-  animation_->AddKeyframeModelForKeyframeEffect(
-      KeyframeModel::Create(std::make_unique<FakeFloatAnimationCurve>(20), 48,
-                            78, TargetProperty::OPACITY),
-      second_keyframe_effect_id);
-  EXPECT_EQ(
-      base::StringPrintf(
-          "Animation{id=%d, element_id=%s, "
-          "keyframe_models=[KeyframeModel{id=42, "
-          "group=73, target_property_id=1, "
-          "run_state=WAITING_FOR_TARGET_AVAILABILITY}, KeyframeModel{id=45, "
-          "group=76, "
-          "target_property_id=5, run_state=WAITING_FOR_TARGET_AVAILABILITY}]"
-          ", element_id=%s, "
-          "keyframe_models=[KeyframeModel{id=48, "
-          "group=78, target_property_id=1, "
-          "run_state=WAITING_FOR_TARGET_AVAILABILITY}]}",
-          animation_->id(), element_id_.ToString().c_str(),
-          second_element_id.ToString().c_str()),
-      animation_->ToString());
-}
-
-TEST_F(AnimationTest,
-       AddTwoKeyframeEffectsFromTheSameElementToOneAnimationTest) {
-  host_->AddAnimationTimeline(timeline_);
-  EXPECT_TRUE(timeline_->needs_push_properties());
-
-  KeyframeEffectId keyframe_effect_id1 = animation_->NextKeyframeEffectId();
-
-  animation_->AddKeyframeEffect(
-      std::make_unique<KeyframeEffect>(keyframe_effect_id1));
-  ASSERT_TRUE(animation_->GetKeyframeEffectById(keyframe_effect_id1));
-  EXPECT_FALSE(animation_->GetKeyframeEffectById(keyframe_effect_id1)
-                   ->needs_push_properties());
-
-  KeyframeEffectId keyframe_effect_id2 = animation_->NextKeyframeEffectId();
-  animation_->AddKeyframeEffect(
-      std::make_unique<KeyframeEffect>(keyframe_effect_id2));
-  ASSERT_TRUE(animation_->GetKeyframeEffectById(keyframe_effect_id2));
-  EXPECT_FALSE(animation_->GetKeyframeEffectById(keyframe_effect_id2)
-                   ->needs_push_properties());
-
-  timeline_->AttachAnimation(animation_);
-  EXPECT_FALSE(animation_->element_animations(keyframe_effect_id1));
-  EXPECT_FALSE(animation_->element_animations(keyframe_effect_id2));
-  EXPECT_FALSE(
-      animation_->GetKeyframeEffectById(keyframe_effect_id1)->element_id());
-  EXPECT_FALSE(
-      animation_->GetKeyframeEffectById(keyframe_effect_id2)->element_id());
-  EXPECT_TRUE(timeline_->needs_push_properties());
-  EXPECT_FALSE(animation_->GetKeyframeEffectById(keyframe_effect_id1)
-                   ->needs_push_properties());
-  EXPECT_FALSE(animation_->GetKeyframeEffectById(keyframe_effect_id2)
-                   ->needs_push_properties());
-
-  host_->PushPropertiesTo(host_impl_);
-
-  timeline_impl_ = host_impl_->GetTimelineById(timeline_id_);
-  EXPECT_TRUE(timeline_impl_);
-  animation_impl_ = timeline_impl_->GetAnimationById(animation_id_);
-  EXPECT_TRUE(animation_impl_);
-
-  animation_->AttachElementForKeyframeEffect(element_id_, keyframe_effect_id1);
-  EXPECT_TRUE(animation_->element_animations(keyframe_effect_id1));
-  EXPECT_EQ(
-      animation_->GetKeyframeEffectById(keyframe_effect_id1)->element_id(),
-      element_id_);
-  EXPECT_TRUE(animation_->GetKeyframeEffectById(keyframe_effect_id1)
-                  ->needs_push_properties());
-
-  EXPECT_FALSE(animation_->element_animations(keyframe_effect_id2));
-  EXPECT_NE(
-      animation_->GetKeyframeEffectById(keyframe_effect_id2)->element_id(),
-      element_id_);
-  EXPECT_FALSE(animation_->GetKeyframeEffectById(keyframe_effect_id2)
-                   ->needs_push_properties());
-
-  const scoped_refptr<ElementAnimations> element_animations =
-      host_->GetElementAnimationsForElementId(element_id_);
-  EXPECT_TRUE(element_animations->HasKeyframeEffectForTesting(
-      animation_->GetKeyframeEffectById(keyframe_effect_id1)));
-  EXPECT_FALSE(element_animations->HasKeyframeEffectForTesting(
-      animation_->GetKeyframeEffectById(keyframe_effect_id2)));
-
-  animation_->AttachElementForKeyframeEffect(element_id_, keyframe_effect_id2);
-  EXPECT_TRUE(animation_->element_animations(keyframe_effect_id2));
-  EXPECT_EQ(
-      animation_->GetKeyframeEffectById(keyframe_effect_id2)->element_id(),
-      element_id_);
-  EXPECT_TRUE(animation_->GetKeyframeEffectById(keyframe_effect_id2)
-                  ->needs_push_properties());
-
-  EXPECT_TRUE(element_animations->HasKeyframeEffectForTesting(
-      animation_->GetKeyframeEffectById(keyframe_effect_id2)));
-
-  host_->PushPropertiesTo(host_impl_);
-
-  const scoped_refptr<ElementAnimations> element_animations_impl =
-      host_impl_->GetElementAnimationsForElementId(element_id_);
-  EXPECT_TRUE(element_animations_impl->HasKeyframeEffectForTesting(
-      animation_impl_->GetKeyframeEffectById(keyframe_effect_id1)));
-  EXPECT_TRUE(element_animations_impl->HasKeyframeEffectForTesting(
-      animation_impl_->GetKeyframeEffectById(keyframe_effect_id2)));
-
-  EXPECT_TRUE(animation_impl_->element_animations(keyframe_effect_id1));
-  EXPECT_EQ(
-      animation_impl_->GetKeyframeEffectById(keyframe_effect_id1)->element_id(),
-      element_id_);
-  EXPECT_TRUE(animation_impl_->element_animations(keyframe_effect_id2));
-  EXPECT_EQ(
-      animation_impl_->GetKeyframeEffectById(keyframe_effect_id2)->element_id(),
-      element_id_);
-
-  animation_->DetachElement();
-  EXPECT_FALSE(animation_->element_animations(keyframe_effect_id1));
-  EXPECT_FALSE(
-      animation_->GetKeyframeEffectById(keyframe_effect_id1)->element_id());
-  EXPECT_FALSE(element_animations->HasKeyframeEffectForTesting(
-      animation_->GetKeyframeEffectById(keyframe_effect_id1)));
-
-  EXPECT_FALSE(animation_->element_animations(keyframe_effect_id2));
-  EXPECT_FALSE(
-      animation_->GetKeyframeEffectById(keyframe_effect_id2)->element_id());
-  EXPECT_FALSE(element_animations->HasKeyframeEffectForTesting(
-      animation_->GetKeyframeEffectById(keyframe_effect_id2)));
-
-  EXPECT_TRUE(element_animations_impl->HasKeyframeEffectForTesting(
-      animation_impl_->GetKeyframeEffectById(keyframe_effect_id1)));
-  EXPECT_TRUE(element_animations_impl->HasKeyframeEffectForTesting(
-      animation_impl_->GetKeyframeEffectById(keyframe_effect_id2)));
-
-  host_->PushPropertiesTo(host_impl_);
-
-  EXPECT_FALSE(animation_impl_->element_animations(keyframe_effect_id1));
-  EXPECT_FALSE(animation_impl_->GetKeyframeEffectById(keyframe_effect_id1)
-                   ->element_id());
-  EXPECT_FALSE(element_animations_impl->HasKeyframeEffectForTesting(
-      animation_impl_->GetKeyframeEffectById(keyframe_effect_id1)));
-  EXPECT_FALSE(animation_impl_->element_animations(keyframe_effect_id2));
-  EXPECT_FALSE(animation_impl_->GetKeyframeEffectById(keyframe_effect_id2)
-                   ->element_id());
-  EXPECT_FALSE(element_animations_impl->HasKeyframeEffectForTesting(
-      animation_impl_->GetKeyframeEffectById(keyframe_effect_id2)));
-
-  timeline_->DetachAnimation(animation_);
-  EXPECT_FALSE(animation_->animation_timeline());
-
-  EXPECT_FALSE(animation_->element_animations(keyframe_effect_id1));
-  EXPECT_FALSE(
-      animation_->GetKeyframeEffectById(keyframe_effect_id1)->element_id());
-  EXPECT_FALSE(animation_->element_animations(keyframe_effect_id2));
-  EXPECT_FALSE(
-      animation_->GetKeyframeEffectById(keyframe_effect_id2)->element_id());
-
-  EXPECT_TRUE(timeline_->needs_push_properties());
-  EXPECT_FALSE(animation_->GetKeyframeEffectById(keyframe_effect_id1)
-                   ->needs_push_properties());
-  EXPECT_FALSE(animation_->GetKeyframeEffectById(keyframe_effect_id2)
-                   ->needs_push_properties());
-}
-
-TEST_F(AnimationTest,
-       AddTwoKeyframeEffectsFromDifferentElementsToOneAnimationTest) {
-  host_->AddAnimationTimeline(timeline_);
-
-  KeyframeEffectId keyframe_effect_id1 = animation_->NextKeyframeEffectId();
-
-  animation_->AddKeyframeEffect(
-      std::make_unique<KeyframeEffect>(keyframe_effect_id1));
-  ASSERT_TRUE(animation_->GetKeyframeEffectById(keyframe_effect_id1));
-  EXPECT_FALSE(animation_->GetKeyframeEffectById(keyframe_effect_id1)
-                   ->needs_push_properties());
-
-  KeyframeEffectId keyframe_effect_id2 = animation_->NextKeyframeEffectId();
-  animation_->AddKeyframeEffect(
-      std::make_unique<KeyframeEffect>(keyframe_effect_id2));
-  ASSERT_TRUE(animation_->GetKeyframeEffectById(keyframe_effect_id2));
-  EXPECT_FALSE(animation_->GetKeyframeEffectById(keyframe_effect_id2)
-                   ->needs_push_properties());
-
-  EXPECT_FALSE(animation_->element_animations(keyframe_effect_id1));
-  EXPECT_FALSE(animation_->element_animations(keyframe_effect_id2));
-  EXPECT_FALSE(
-      animation_->GetKeyframeEffectById(keyframe_effect_id1)->element_id());
-  EXPECT_FALSE(
-      animation_->GetKeyframeEffectById(keyframe_effect_id2)->element_id());
-  EXPECT_TRUE(timeline_->needs_push_properties());
-  EXPECT_FALSE(animation_->GetKeyframeEffectById(keyframe_effect_id1)
-                   ->needs_push_properties());
-  EXPECT_FALSE(animation_->GetKeyframeEffectById(keyframe_effect_id2)
-                   ->needs_push_properties());
-
-  ElementId element1(NextTestLayerId());
-  ElementId element2(NextTestLayerId());
-
-  animation_->AttachElementForKeyframeEffect(element1, keyframe_effect_id1);
-  animation_->AttachElementForKeyframeEffect(element2, keyframe_effect_id2);
-
-  EXPECT_FALSE(animation_->animation_timeline());
-
-  scoped_refptr<ElementAnimations> element_animations =
-      host_->GetElementAnimationsForElementId(element1);
-  EXPECT_FALSE(element_animations);
-  EXPECT_FALSE(animation_->GetKeyframeEffectById(keyframe_effect_id1)
-                   ->element_animations());
-  EXPECT_EQ(
-      animation_->GetKeyframeEffectById(keyframe_effect_id1)->element_id(),
-      element1);
-  EXPECT_FALSE(animation_->GetKeyframeEffectById(keyframe_effect_id1)
-                   ->needs_push_properties());
-
-  timeline_->AttachAnimation(animation_);
-  EXPECT_EQ(timeline_, animation_->animation_timeline());
-  EXPECT_TRUE(animation_->GetKeyframeEffectById(keyframe_effect_id1)
-                  ->element_animations());
-  EXPECT_EQ(
-      animation_->GetKeyframeEffectById(keyframe_effect_id1)->element_id(),
-      element1);
-  EXPECT_TRUE(animation_->GetKeyframeEffectById(keyframe_effect_id1)
-                  ->needs_push_properties());
-
-  element_animations = host_->GetElementAnimationsForElementId(element1);
-  EXPECT_TRUE(element_animations->HasKeyframeEffectForTesting(
-      animation_->GetKeyframeEffectById(keyframe_effect_id1)));
-  EXPECT_FALSE(element_animations->HasKeyframeEffectForTesting(
-      animation_->GetKeyframeEffectById(keyframe_effect_id2)));
-
-  element_animations = host_->GetElementAnimationsForElementId(element2);
-  EXPECT_TRUE(element_animations->HasKeyframeEffectForTesting(
-      animation_->GetKeyframeEffectById(keyframe_effect_id2)));
-
-  animation_->DetachElement();
-  EXPECT_TRUE(animation_->animation_timeline());
-  EXPECT_FALSE(element_animations->HasKeyframeEffectForTesting(
-      animation_->GetKeyframeEffectById(keyframe_effect_id2)));
-  EXPECT_FALSE(animation_->GetKeyframeEffectById(keyframe_effect_id1)
-                   ->element_animations());
-  EXPECT_FALSE(
-      animation_->GetKeyframeEffectById(keyframe_effect_id1)->element_id());
-  EXPECT_TRUE(animation_->GetKeyframeEffectById(keyframe_effect_id1)
-                  ->needs_push_properties());
-  EXPECT_FALSE(animation_->GetKeyframeEffectById(keyframe_effect_id2)
-                   ->element_animations());
-  EXPECT_FALSE(
-      animation_->GetKeyframeEffectById(keyframe_effect_id2)->element_id());
-  EXPECT_TRUE(animation_->GetKeyframeEffectById(keyframe_effect_id2)
-                  ->needs_push_properties());
-
-  // Removing animation from timeline detaches layer.
-  timeline_->DetachAnimation(animation_);
-  EXPECT_FALSE(animation_->animation_timeline());
-  EXPECT_FALSE(animation_->GetKeyframeEffectById(keyframe_effect_id1)
-                   ->element_animations());
-  EXPECT_FALSE(
-      animation_->GetKeyframeEffectById(keyframe_effect_id1)->element_id());
-  EXPECT_TRUE(animation_->GetKeyframeEffectById(keyframe_effect_id1)
-                  ->needs_push_properties());
-  EXPECT_FALSE(animation_->GetKeyframeEffectById(keyframe_effect_id2)
-                   ->element_animations());
-  EXPECT_FALSE(
-      animation_->GetKeyframeEffectById(keyframe_effect_id2)->element_id());
-  EXPECT_TRUE(animation_->GetKeyframeEffectById(keyframe_effect_id2)
-                  ->needs_push_properties());
-}
-
-TEST_F(AnimationTest, TickingAnimationsFromTwoKeyframeEffects) {
-  TestAnimationDelegate delegate1;
-
-  client_.RegisterElementId(element_id_, ElementListType::ACTIVE);
-  client_impl_.RegisterElementId(element_id_, ElementListType::PENDING);
-  client_impl_.RegisterElementId(element_id_, ElementListType::ACTIVE);
-
-  KeyframeEffectId keyframe_effect_id1 = animation_->NextKeyframeEffectId();
-
-  animation_->AddKeyframeEffect(
-      std::make_unique<KeyframeEffect>(keyframe_effect_id1));
-  ASSERT_TRUE(animation_->GetKeyframeEffectById(keyframe_effect_id1));
-  EXPECT_FALSE(animation_->GetKeyframeEffectById(keyframe_effect_id1)
-                   ->needs_push_properties());
-
-  KeyframeEffectId keyframe_effect_id2 = animation_->NextKeyframeEffectId();
-  animation_->AddKeyframeEffect(
-      std::make_unique<KeyframeEffect>(keyframe_effect_id2));
-  ASSERT_TRUE(animation_->GetKeyframeEffectById(keyframe_effect_id2));
-  EXPECT_FALSE(animation_->GetKeyframeEffectById(keyframe_effect_id2)
-                   ->needs_push_properties());
-
-  host_->AddAnimationTimeline(timeline_);
-
-  timeline_->AttachAnimation(animation_);
-  EXPECT_TRUE(timeline_->needs_push_properties());
-
-  animation_->set_animation_delegate(&delegate1);
-
-  animation_->AttachElementForKeyframeEffect(element_id_, keyframe_effect_id1);
-  animation_->AttachElementForKeyframeEffect(element_id_, keyframe_effect_id2);
-
-  const float start_opacity = .7f;
-  const float end_opacity = .3f;
-
-  const int transform_x = 10;
-  const int transform_y = 20;
-
-  const double duration = 1.;
-
-  AddOpacityTransitionToAnimation(animation_.get(), duration, start_opacity,
-                                  end_opacity, false, keyframe_effect_id1);
-  AddAnimatedTransformToAnimation(animation_.get(), duration, transform_x,
-                                  transform_y, keyframe_effect_id2);
-  host_->PushPropertiesTo(host_impl_);
-  host_impl_->ActivateAnimations(nullptr);
-
-  EXPECT_FALSE(delegate1.started());
-  EXPECT_FALSE(delegate1.finished());
-
-  base::TimeTicks time;
-  time += base::TimeDelta::FromSecondsD(0.1);
-  TickAnimationsTransferEvents(time, 2u);
-
-  EXPECT_TRUE(delegate1.started());
-  EXPECT_FALSE(delegate1.finished());
-
-  EXPECT_FALSE(animation_->GetKeyframeEffectById(keyframe_effect_id1)
-                   ->needs_push_properties());
-  EXPECT_FALSE(animation_->GetKeyframeEffectById(keyframe_effect_id2)
-                   ->needs_push_properties());
-
-  time += base::TimeDelta::FromSecondsD(duration);
-  TickAnimationsTransferEvents(time, 2u);
-
-  EXPECT_TRUE(delegate1.finished());
-
-  EXPECT_TRUE(animation_->GetKeyframeEffectById(keyframe_effect_id1)
-                  ->needs_push_properties());
-  EXPECT_TRUE(animation_->GetKeyframeEffectById(keyframe_effect_id2)
-                  ->needs_push_properties());
-
-  client_.ExpectOpacityPropertyMutated(element_id_, ElementListType::ACTIVE,
-                                       end_opacity);
-  client_.ExpectTransformPropertyMutated(element_id_, ElementListType::ACTIVE,
-                                         transform_x, transform_y);
-
-  client_impl_.ExpectOpacityPropertyMutated(
-      element_id_, ElementListType::ACTIVE, end_opacity);
-  client_impl_.ExpectTransformPropertyMutated(
-      element_id_, ElementListType::ACTIVE, transform_x, transform_y);
-
-  client_impl_.ExpectOpacityPropertyMutated(
-      element_id_, ElementListType::PENDING, end_opacity);
-  client_impl_.ExpectTransformPropertyMutated(
-      element_id_, ElementListType::PENDING, transform_x, transform_y);
-}
-
-TEST_F(AnimationTest, TickingState) {
-  KeyframeEffectId keyframe_effect_id = animation_->NextKeyframeEffectId();
-
-  animation_->AddKeyframeEffect(
-      std::make_unique<KeyframeEffect>(keyframe_effect_id));
-
-  host_->AddAnimationTimeline(timeline_);
-  timeline_->AttachAnimation(animation_);
-
-  const int transform_x = 10;
-  const int transform_y = 20;
-  const double duration = 1.;
-  animation_->AttachElementForKeyframeEffect(element_id_, keyframe_effect_id);
-  AddAnimatedTransformToAnimation(animation_.get(), duration, transform_x,
-                                  transform_y, keyframe_effect_id);
-  KeyframeEffect* keyframe_effect =
-      animation_->GetKeyframeEffectById(keyframe_effect_id);
-  EXPECT_FALSE(keyframe_effect->is_ticking());
-  client_.RegisterElementId(element_id_, ElementListType::ACTIVE);
-  EXPECT_TRUE(keyframe_effect->is_ticking());
-
-  client_.UnregisterElementId(element_id_, ElementListType::ACTIVE);
-  // The keyframe keeps ticking until the next call to UpdateState where it can
-  // generate a finished event.
-  EXPECT_TRUE(keyframe_effect->is_ticking());
-
-  // The next call to UpdateState should remove the animation from ticking. We
-  // could also assert that the finish event was generated if we also track the
-  // state in the KeyframeModel correctly.
-  host_->UpdateAnimationState(true, nullptr);
-  EXPECT_FALSE(keyframe_effect->is_ticking());
-}
-
-TEST_F(AnimationTest, KeyframeEffectSyncToImplTest) {
-  host_->AddAnimationTimeline(timeline_);
-  EXPECT_TRUE(timeline_->needs_push_properties());
-  timeline_->AttachAnimation(animation_);
-
-  KeyframeEffectId keyframe_effect_id1 = animation_->NextKeyframeEffectId();
-  animation_->AddKeyframeEffect(
-      std::make_unique<KeyframeEffect>(keyframe_effect_id1));
-  EXPECT_TRUE(animation_->GetKeyframeEffectById(keyframe_effect_id1));
-  EXPECT_FALSE(animation_->GetKeyframeEffectById(keyframe_effect_id1)
-                   ->needs_push_properties());
-
-  host_->PushPropertiesTo(host_impl_);
-
-  timeline_impl_ = host_impl_->GetTimelineById(timeline_id_);
-  EXPECT_TRUE(timeline_impl_);
-  animation_impl_ = timeline_impl_->GetAnimationById(animation_id_);
-  EXPECT_TRUE(animation_impl_);
-  EXPECT_TRUE(animation_impl_->GetKeyframeEffectById(keyframe_effect_id1));
-
-  EXPECT_FALSE(timeline_->needs_push_properties());
-
-  KeyframeEffectId keyframe_effect_id2 = animation_->NextKeyframeEffectId();
-  animation_->AddKeyframeEffect(
-      std::make_unique<KeyframeEffect>(keyframe_effect_id2));
-  EXPECT_TRUE(timeline_->needs_push_properties());
-
-  host_->PushPropertiesTo(host_impl_);
-
-  EXPECT_TRUE(animation_impl_->GetKeyframeEffectById(keyframe_effect_id2));
 }
 
 }  // namespace
diff --git a/cc/animation/element_animations_unittest.cc b/cc/animation/element_animations_unittest.cc
index 0a87324..fe0eab53 100644
--- a/cc/animation/element_animations_unittest.cc
+++ b/cc/animation/element_animations_unittest.cc
@@ -5,6 +5,7 @@
 #include "cc/animation/element_animations.h"
 
 #include "base/memory/ptr_util.h"
+#include "cc/animation/animation.h"
 #include "cc/animation/animation_delegate.h"
 #include "cc/animation/animation_events.h"
 #include "cc/animation/animation_host.h"
@@ -14,7 +15,6 @@
 #include "cc/animation/keyframed_animation_curve.h"
 #include "cc/animation/scroll_offset_animation_curve.h"
 #include "cc/animation/scroll_offset_animation_curve_factory.h"
-#include "cc/animation/single_keyframe_effect_animation.h"
 #include "cc/animation/transform_operations.h"
 #include "cc/test/animation_test_common.h"
 #include "cc/test/animation_timelines_test_common.h"
@@ -42,7 +42,6 @@
 
   void SetUp() override {
     AnimationTimelinesTest::SetUp();
-    animation_ = SingleKeyframeEffectAnimation::Create(animation_id_);
   }
 
   void CreateImplTimelineAndAnimation() override {
@@ -177,12 +176,10 @@
       animation_->keyframe_effect()->element_animations();
   EXPECT_TRUE(element_animations);
 
-  scoped_refptr<SingleKeyframeEffectAnimation> animation1 =
-      SingleKeyframeEffectAnimation::Create(
-          AnimationIdProvider::NextAnimationId());
-  scoped_refptr<SingleKeyframeEffectAnimation> animation2 =
-      SingleKeyframeEffectAnimation::Create(
-          AnimationIdProvider::NextAnimationId());
+  scoped_refptr<Animation> animation1 =
+      Animation::Create(AnimationIdProvider::NextAnimationId());
+  scoped_refptr<Animation> animation2 =
+      Animation::Create(AnimationIdProvider::NextAnimationId());
 
   timeline_->AttachAnimation(animation1);
   timeline_->AttachAnimation(animation2);
@@ -239,7 +236,7 @@
       keyframe_model_id));
 
   PushProperties();
-  animation_impl_->ActivateKeyframeEffects();
+  animation_impl_->ActivateKeyframeModels();
 
   EXPECT_TRUE(animation_impl_->keyframe_effect()->GetKeyframeModelById(
       keyframe_model_id));
@@ -315,16 +312,15 @@
     timeline_->DetachAnimation(animation_);
   }
 
-  void setTimelineAndAnimation(
-      scoped_refptr<AnimationTimeline> timeline,
-      scoped_refptr<SingleKeyframeEffectAnimation> animation) {
+  void setTimelineAndAnimation(scoped_refptr<AnimationTimeline> timeline,
+                               scoped_refptr<Animation> animation) {
     timeline_ = timeline;
     animation_ = animation;
   }
 
  private:
   scoped_refptr<AnimationTimeline> timeline_;
-  scoped_refptr<SingleKeyframeEffectAnimation> animation_;
+  scoped_refptr<Animation> animation_;
 };
 
 // Test that we don't crash if a animation is deleted while ElementAnimations is
@@ -338,8 +334,7 @@
   TestAnimationDelegateThatDestroysAnimation delegate;
 
   const int animation2_id = AnimationIdProvider::NextAnimationId();
-  scoped_refptr<SingleKeyframeEffectAnimation> animation2 =
-      SingleKeyframeEffectAnimation::Create(animation2_id);
+  scoped_refptr<Animation> animation2 = Animation::Create(animation2_id);
   delegate.setTimelineAndAnimation(timeline_, animation2);
 
   timeline_->AttachAnimation(animation2);
@@ -351,12 +346,11 @@
 
   PushProperties();
 
-  scoped_refptr<SingleKeyframeEffectAnimation> animation2_impl =
-      (SingleKeyframeEffectAnimation*)timeline_impl_->GetAnimationById(
-          animation2_id);
+  scoped_refptr<Animation> animation2_impl =
+      timeline_impl_->GetAnimationById(animation2_id);
   DCHECK(animation2_impl);
 
-  animation2_impl->ActivateKeyframeEffects();
+  animation2_impl->ActivateKeyframeModels();
   EXPECT_TRUE(animation2_impl->keyframe_effect()->GetKeyframeModelById(
       keyframe_model_id));
 
@@ -385,7 +379,7 @@
       AddOpacityTransitionToAnimation(animation_.get(), 1, 0, 1, false);
 
   PushProperties();
-  animation_impl_->ActivateKeyframeEffects();
+  animation_impl_->ActivateKeyframeModels();
 
   EXPECT_TRUE(animation_impl_->keyframe_effect()->GetKeyframeModelById(
       keyframe_model_id));
@@ -432,7 +426,7 @@
       ->set_start_time(start_time);
 
   PushProperties();
-  animation_impl_->ActivateKeyframeEffects();
+  animation_impl_->ActivateKeyframeModels();
 
   EXPECT_TRUE(animation_impl_->keyframe_effect()->GetKeyframeModelById(
       keyframe_model_id));
@@ -496,7 +490,7 @@
   EXPECT_EQ(1u, host->ticking_animations_for_testing().size());
 
   PushProperties();
-  animation_impl_->ActivateKeyframeEffects();
+  animation_impl_->ActivateKeyframeModels();
   // Both animationss should now be active.
   EXPECT_EQ(1u, host->ticking_animations_for_testing().size());
   EXPECT_EQ(1u, host_impl->ticking_animations_for_testing().size());
@@ -541,7 +535,7 @@
   EXPECT_EQ(0u, host->ticking_animations_for_testing().size());
 
   PushProperties();
-  animation_impl_->ActivateKeyframeEffects();
+  animation_impl_->ActivateKeyframeModels();
   EXPECT_FALSE(animation_->keyframe_effect()->has_any_keyframe_model());
   EXPECT_FALSE(animation_impl_->keyframe_effect()->has_any_keyframe_model());
   EXPECT_EQ(0u, host->ticking_animations_for_testing().size());
@@ -566,7 +560,7 @@
       ->set_time_offset(TimeDelta::FromSecondsD(1.01));
 
   PushProperties();
-  animation_impl_->ActivateKeyframeEffects();
+  animation_impl_->ActivateKeyframeModels();
 
   EXPECT_TRUE(animation_impl_->keyframe_effect()->GetKeyframeModelById(
       keyframe_model_id));
@@ -617,7 +611,7 @@
 
   // The pause run state change should make it to the impl thread animations.
   PushProperties();
-  animation_impl_->ActivateKeyframeEffects();
+  animation_impl_->ActivateKeyframeModels();
 
   // Advance time so it stays within the first range.
   time += TimeDelta::FromMilliseconds(10);
@@ -647,7 +641,7 @@
       AddOpacityTransitionToAnimation(animation_.get(), 1, 0, 1, false);
 
   PushProperties();
-  animation_impl_->ActivateKeyframeEffects();
+  animation_impl_->ActivateKeyframeModels();
 
   EXPECT_TRUE(animation_impl_->keyframe_effect()->GetKeyframeModelById(
       keyframe_model_id));
@@ -678,7 +672,7 @@
   animation_->UpdateState(true, nullptr);
 
   PushProperties();
-  animation_impl_->ActivateKeyframeEffects();
+  animation_impl_->ActivateKeyframeModels();
   EXPECT_FALSE(
       animation_->keyframe_effect()->GetKeyframeModelById(keyframe_model_id));
   EXPECT_FALSE(animation_impl_->keyframe_effect()->GetKeyframeModelById(
@@ -705,7 +699,7 @@
   EXPECT_FALSE(host_->needs_push_properties());
   EXPECT_FALSE(host_impl_->needs_push_properties());
 
-  animation_impl_->ActivateKeyframeEffects();
+  animation_impl_->ActivateKeyframeModels();
 
   animation_impl_->Tick(kInitialTickTime + TimeDelta::FromMilliseconds(500));
   animation_impl_->UpdateState(true, events.get());
@@ -901,7 +895,7 @@
 
   client_impl_.SetScrollOffsetForAnimation(initial_value);
   PushProperties();
-  animation_impl_->ActivateKeyframeEffects();
+  animation_impl_->ActivateKeyframeModels();
   EXPECT_TRUE(animation_impl_->GetKeyframeModel(TargetProperty::SCROLL_OFFSET));
   TimeDelta duration =
       animation_impl_->GetKeyframeModel(TargetProperty::SCROLL_OFFSET)
@@ -1072,7 +1066,7 @@
 
   client_.SetScrollOffsetForAnimation(initial_value);
   PushProperties();
-  animation_impl_->ActivateKeyframeEffects();
+  animation_impl_->ActivateKeyframeModels();
   EXPECT_TRUE(animation_impl_->GetKeyframeModel(TargetProperty::SCROLL_OFFSET));
   TimeDelta duration =
       animation_impl_->GetKeyframeModel(TargetProperty::SCROLL_OFFSET)
@@ -1149,7 +1143,7 @@
   keyframe_model->set_needs_synchronized_start_time(true);
   animation_->AddKeyframeModel(std::move(keyframe_model));
   PushProperties();
-  animation_impl_->ActivateKeyframeEffects();
+  animation_impl_->ActivateKeyframeModels();
   EXPECT_FALSE(
       animation_->keyframe_effect()->scroll_offset_animation_was_interrupted());
   EXPECT_FALSE(animation_impl_->keyframe_effect()
@@ -1165,7 +1159,7 @@
   EXPECT_FALSE(
       animation_->keyframe_effect()->scroll_offset_animation_was_interrupted());
 
-  animation_impl_->ActivateKeyframeEffects();
+  animation_impl_->ActivateKeyframeModels();
   EXPECT_FALSE(animation_impl_->keyframe_effect()
                    ->scroll_offset_animation_was_interrupted());
 
@@ -1177,7 +1171,7 @@
   keyframe_model->set_needs_synchronized_start_time(true);
   animation_->AddKeyframeModel(std::move(keyframe_model));
   PushProperties();
-  animation_impl_->ActivateKeyframeEffects();
+  animation_impl_->ActivateKeyframeModels();
   EXPECT_FALSE(
       animation_->keyframe_effect()->scroll_offset_animation_was_interrupted());
   EXPECT_FALSE(animation_impl_->keyframe_effect()
@@ -1193,7 +1187,7 @@
   EXPECT_FALSE(
       animation_->keyframe_effect()->scroll_offset_animation_was_interrupted());
 
-  animation_impl_->ActivateKeyframeEffects();
+  animation_impl_->ActivateKeyframeModels();
   EXPECT_FALSE(animation_impl_->keyframe_effect()
                    ->scroll_offset_animation_was_interrupted());
 
@@ -1202,7 +1196,7 @@
   keyframe_model_id =
       AddAnimatedTransformToAnimation(animation_.get(), 1.0, 1, 2);
   PushProperties();
-  animation_impl_->ActivateKeyframeEffects();
+  animation_impl_->ActivateKeyframeModels();
   EXPECT_FALSE(
       animation_->keyframe_effect()->scroll_offset_animation_was_interrupted());
   EXPECT_FALSE(animation_impl_->keyframe_effect()
@@ -1218,14 +1212,14 @@
   EXPECT_FALSE(
       animation_->keyframe_effect()->scroll_offset_animation_was_interrupted());
 
-  animation_impl_->ActivateKeyframeEffects();
+  animation_impl_->ActivateKeyframeModels();
   EXPECT_FALSE(animation_impl_->keyframe_effect()
                    ->scroll_offset_animation_was_interrupted());
 
   keyframe_model_id =
       AddAnimatedFilterToAnimation(animation_.get(), 1.0, 0.1f, 0.2f);
   PushProperties();
-  animation_impl_->ActivateKeyframeEffects();
+  animation_impl_->ActivateKeyframeModels();
   EXPECT_FALSE(
       animation_->keyframe_effect()->scroll_offset_animation_was_interrupted());
   EXPECT_FALSE(animation_impl_->keyframe_effect()
@@ -1241,7 +1235,7 @@
   EXPECT_FALSE(
       animation_->keyframe_effect()->scroll_offset_animation_was_interrupted());
 
-  animation_impl_->ActivateKeyframeEffects();
+  animation_impl_->ActivateKeyframeModels();
   EXPECT_FALSE(animation_impl_->keyframe_effect()
                    ->scroll_offset_animation_was_interrupted());
 }
@@ -1309,7 +1303,7 @@
       ->set_start_time(start_time);
 
   PushProperties();
-  animation_impl_->ActivateKeyframeEffects();
+  animation_impl_->ActivateKeyframeModels();
 
   EXPECT_TRUE(animation_impl_->keyframe_effect()->GetKeyframeModelById(
       keyframe_model_id));
@@ -1365,7 +1359,7 @@
   animation_->DispatchAndDelegateAnimationEvent(
       AnimationEvent(AnimationEvent::STARTED,
                      {animation_->animation_timeline()->id(), animation_->id(),
-                      animation_->keyframe_effect()->id(), keyframe_model_id},
+                      keyframe_model_id},
                      1, TargetProperty::OPACITY,
                      kInitialTickTime + TimeDelta::FromMilliseconds(2000)));
   animation_->Tick(kInitialTickTime + TimeDelta::FromMilliseconds(5000));
@@ -1741,7 +1735,7 @@
 
   EXPECT_TRUE(animation_->keyframe_effect()->needs_push_properties());
   PushProperties();
-  animation_impl_->ActivateKeyframeEffects();
+  animation_impl_->ActivateKeyframeModels();
 
   active_keyframe_model =
       animation_impl_->GetKeyframeModel(TargetProperty::OPACITY);
@@ -1946,7 +1940,7 @@
 
   PushProperties();
 
-  animation_impl_->ActivateKeyframeEffects();
+  animation_impl_->ActivateKeyframeModels();
 
   EXPECT_TRUE(animation_impl_->keyframe_effect()->GetKeyframeModelById(
       keyframe_model_id));
@@ -1990,7 +1984,7 @@
   PushProperties();
   EXPECT_FALSE(host_->needs_push_properties());
 
-  animation_impl_->ActivateKeyframeEffects();
+  animation_impl_->ActivateKeyframeModels();
   EXPECT_TRUE(animation_impl_->keyframe_effect()->GetKeyframeModelById(
       keyframe_model_id));
 
@@ -2025,7 +2019,7 @@
 
   PushProperties();
 
-  animation_impl_->ActivateKeyframeEffects();
+  animation_impl_->ActivateKeyframeModels();
   EXPECT_FALSE(
       animation_->keyframe_effect()->GetKeyframeModelById(keyframe_model_id));
   EXPECT_FALSE(animation_impl_->keyframe_effect()->GetKeyframeModelById(
@@ -2061,7 +2055,7 @@
   PushProperties();
   EXPECT_FALSE(host_->needs_push_properties());
 
-  animation_impl_->ActivateKeyframeEffects();
+  animation_impl_->ActivateKeyframeModels();
   EXPECT_TRUE(animation_impl_->keyframe_effect()->GetKeyframeModelById(
       keyframe_model_id));
 
@@ -2090,15 +2084,15 @@
   animation_->DispatchAndDelegateAnimationEvent(events->events_[0]);
   EXPECT_TRUE(delegate.takeover());
 
-  // SingleKeyframeEffectAnimation::NotifyAnimationTakeover requests
-  // SetNeedsPushProperties to purge CT animations marked for deletion.
+  // Animation::NotifyAnimationTakeover requests SetNeedsPushProperties to purge
+  // CT animations marked for deletion.
   EXPECT_TRUE(animation_->keyframe_effect()->needs_push_properties());
 
   // ElementAnimations::PurgeAnimationsMarkedForDeletion call happens only in
   // ElementAnimations::PushPropertiesTo.
   PushProperties();
 
-  animation_impl_->ActivateKeyframeEffects();
+  animation_impl_->ActivateKeyframeModels();
   EXPECT_FALSE(
       animation_->keyframe_effect()->GetKeyframeModelById(keyframe_model_id));
   EXPECT_FALSE(animation_impl_->keyframe_effect()->GetKeyframeModelById(
@@ -2294,7 +2288,7 @@
   EXPECT_EQ(kNotScaled, max_scale);
   EXPECT_EQ(kNotScaled, start_scale);
 
-  animation_impl_->ActivateKeyframeEffects();
+  animation_impl_->ActivateKeyframeModels();
   EXPECT_TRUE(animation_impl_->keyframe_effect()->GetAnimationScales(
       ElementListType::PENDING, &max_scale, &start_scale));
   EXPECT_EQ(5.f, max_scale);
@@ -2351,7 +2345,7 @@
   EXPECT_EQ(kNotScaled, max_scale);
   EXPECT_EQ(kNotScaled, start_scale);
 
-  animation_impl_->ActivateKeyframeEffects();
+  animation_impl_->ActivateKeyframeModels();
   EXPECT_TRUE(animation_impl_->keyframe_effect()->GetAnimationScales(
       ElementListType::PENDING, &max_scale, &start_scale));
   EXPECT_EQ(3.5f, max_scale);
@@ -2541,7 +2535,7 @@
             client_impl_.GetOpacity(element_id_, ElementListType::PENDING));
   EXPECT_EQ(0.f, client_impl_.GetOpacity(element_id_, ElementListType::ACTIVE));
 
-  animation_impl_->ActivateKeyframeEffects();
+  animation_impl_->ActivateKeyframeModels();
   EXPECT_TRUE(animation_impl_->keyframe_effect()
                   ->GetKeyframeModelById(keyframe_model_id)
                   ->affects_pending_elements());
@@ -2597,7 +2591,7 @@
             client_impl_.GetOpacity(element_id_, ElementListType::PENDING));
   EXPECT_EQ(0.f, client_impl_.GetOpacity(element_id_, ElementListType::ACTIVE));
 
-  animation_impl_->ActivateKeyframeEffects();
+  animation_impl_->ActivateKeyframeModels();
   EXPECT_TRUE(animation_impl_->keyframe_effect()
                   ->GetKeyframeModelById(keyframe_model_id)
                   ->affects_pending_elements());
@@ -2660,7 +2654,7 @@
   EXPECT_FALSE(client_impl_.GetTransformIsCurrentlyAnimating(
       element_id_, ElementListType::ACTIVE));
 
-  animation_impl_->ActivateKeyframeEffects();
+  animation_impl_->ActivateKeyframeModels();
   EXPECT_TRUE(client_impl_.GetHasPotentialTransformAnimation(
       element_id_, ElementListType::PENDING));
   EXPECT_TRUE(client_impl_.GetTransformIsCurrentlyAnimating(
@@ -2734,7 +2728,7 @@
   EXPECT_FALSE(client_impl_.GetTransformIsCurrentlyAnimating(
       element_id_, ElementListType::ACTIVE));
 
-  animation_impl_->ActivateKeyframeEffects();
+  animation_impl_->ActivateKeyframeModels();
   EXPECT_TRUE(client_impl_.GetHasPotentialTransformAnimation(
       element_id_, ElementListType::ACTIVE));
   // animation1 is in effect currently and animation2 isn't. As the element has
@@ -2766,7 +2760,7 @@
   EXPECT_TRUE(client_impl_.GetTransformIsCurrentlyAnimating(
       element_id_, ElementListType::ACTIVE));
 
-  animation_impl_->ActivateKeyframeEffects();
+  animation_impl_->ActivateKeyframeModels();
   EXPECT_FALSE(client_impl_.GetHasPotentialTransformAnimation(
       element_id_, ElementListType::ACTIVE));
   EXPECT_FALSE(client_impl_.GetTransformIsCurrentlyAnimating(
@@ -2790,7 +2784,7 @@
   EXPECT_FALSE(client_impl_.GetTransformIsCurrentlyAnimating(
       element_id_, ElementListType::ACTIVE));
 
-  animation_impl_->ActivateKeyframeEffects();
+  animation_impl_->ActivateKeyframeModels();
   EXPECT_TRUE(client_impl_.GetHasPotentialTransformAnimation(
       element_id_, ElementListType::ACTIVE));
   EXPECT_TRUE(client_impl_.GetTransformIsCurrentlyAnimating(
@@ -2842,7 +2836,7 @@
   EXPECT_FALSE(client_impl_.GetTransformIsCurrentlyAnimating(
       element_id_, ElementListType::ACTIVE));
 
-  animation_impl_->ActivateKeyframeEffects();
+  animation_impl_->ActivateKeyframeModels();
   EXPECT_TRUE(client_impl_.GetHasPotentialTransformAnimation(
       element_id_, ElementListType::ACTIVE));
   EXPECT_FALSE(client_impl_.GetTransformIsCurrentlyAnimating(
@@ -2887,7 +2881,7 @@
   EXPECT_FALSE(client_impl_.GetOpacityIsCurrentlyAnimating(
       element_id_, ElementListType::ACTIVE));
 
-  animation_impl_->ActivateKeyframeEffects();
+  animation_impl_->ActivateKeyframeModels();
   EXPECT_TRUE(client_impl_.GetHasPotentialOpacityAnimation(
       element_id_, ElementListType::PENDING));
   EXPECT_TRUE(client_impl_.GetOpacityIsCurrentlyAnimating(
@@ -2953,7 +2947,7 @@
   EXPECT_FALSE(client_impl_.GetOpacityIsCurrentlyAnimating(
       element_id_, ElementListType::ACTIVE));
 
-  animation_impl_->ActivateKeyframeEffects();
+  animation_impl_->ActivateKeyframeModels();
   EXPECT_TRUE(client_impl_.GetHasPotentialOpacityAnimation(
       element_id_, ElementListType::ACTIVE));
   EXPECT_TRUE(client_impl_.GetOpacityIsCurrentlyAnimating(
@@ -2981,7 +2975,7 @@
   EXPECT_TRUE(client_impl_.GetOpacityIsCurrentlyAnimating(
       element_id_, ElementListType::ACTIVE));
 
-  animation_impl_->ActivateKeyframeEffects();
+  animation_impl_->ActivateKeyframeModels();
   EXPECT_FALSE(client_impl_.GetHasPotentialOpacityAnimation(
       element_id_, ElementListType::ACTIVE));
   EXPECT_FALSE(client_impl_.GetOpacityIsCurrentlyAnimating(
@@ -3005,7 +2999,7 @@
   EXPECT_FALSE(client_impl_.GetOpacityIsCurrentlyAnimating(
       element_id_, ElementListType::ACTIVE));
 
-  animation_impl_->ActivateKeyframeEffects();
+  animation_impl_->ActivateKeyframeModels();
   EXPECT_TRUE(client_impl_.GetHasPotentialOpacityAnimation(
       element_id_, ElementListType::ACTIVE));
   EXPECT_TRUE(client_impl_.GetOpacityIsCurrentlyAnimating(
@@ -3057,7 +3051,7 @@
   EXPECT_FALSE(client_impl_.GetOpacityIsCurrentlyAnimating(
       element_id_, ElementListType::ACTIVE));
 
-  animation_impl_->ActivateKeyframeEffects();
+  animation_impl_->ActivateKeyframeModels();
   EXPECT_TRUE(client_impl_.GetHasPotentialOpacityAnimation(
       element_id_, ElementListType::ACTIVE));
   EXPECT_FALSE(client_impl_.GetOpacityIsCurrentlyAnimating(
@@ -3101,7 +3095,7 @@
   EXPECT_FALSE(client_impl_.GetFilterIsCurrentlyAnimating(
       element_id_, ElementListType::ACTIVE));
 
-  animation_impl_->ActivateKeyframeEffects();
+  animation_impl_->ActivateKeyframeModels();
   EXPECT_TRUE(client_impl_.GetHasPotentialFilterAnimation(
       element_id_, ElementListType::PENDING));
   EXPECT_TRUE(client_impl_.GetFilterIsCurrentlyAnimating(
@@ -3167,7 +3161,7 @@
   EXPECT_FALSE(client_impl_.GetFilterIsCurrentlyAnimating(
       element_id_, ElementListType::ACTIVE));
 
-  animation_impl_->ActivateKeyframeEffects();
+  animation_impl_->ActivateKeyframeModels();
   EXPECT_TRUE(client_impl_.GetHasPotentialFilterAnimation(
       element_id_, ElementListType::ACTIVE));
   EXPECT_TRUE(client_impl_.GetFilterIsCurrentlyAnimating(
@@ -3195,7 +3189,7 @@
   EXPECT_TRUE(client_impl_.GetFilterIsCurrentlyAnimating(
       element_id_, ElementListType::ACTIVE));
 
-  animation_impl_->ActivateKeyframeEffects();
+  animation_impl_->ActivateKeyframeModels();
   EXPECT_FALSE(client_impl_.GetHasPotentialFilterAnimation(
       element_id_, ElementListType::ACTIVE));
   EXPECT_FALSE(client_impl_.GetFilterIsCurrentlyAnimating(
@@ -3219,7 +3213,7 @@
   EXPECT_FALSE(client_impl_.GetFilterIsCurrentlyAnimating(
       element_id_, ElementListType::ACTIVE));
 
-  animation_impl_->ActivateKeyframeEffects();
+  animation_impl_->ActivateKeyframeModels();
   EXPECT_TRUE(client_impl_.GetHasPotentialFilterAnimation(
       element_id_, ElementListType::ACTIVE));
   EXPECT_TRUE(client_impl_.GetFilterIsCurrentlyAnimating(
@@ -3271,7 +3265,7 @@
   EXPECT_FALSE(client_impl_.GetFilterIsCurrentlyAnimating(
       element_id_, ElementListType::ACTIVE));
 
-  animation_impl_->ActivateKeyframeEffects();
+  animation_impl_->ActivateKeyframeModels();
   EXPECT_TRUE(client_impl_.GetHasPotentialFilterAnimation(
       element_id_, ElementListType::ACTIVE));
   EXPECT_FALSE(client_impl_.GetFilterIsCurrentlyAnimating(
@@ -3316,7 +3310,7 @@
   EXPECT_FALSE(client_impl_.GetBackdropFilterIsCurrentlyAnimating(
       element_id_, ElementListType::ACTIVE));
 
-  animation_impl_->ActivateKeyframeEffects();
+  animation_impl_->ActivateKeyframeModels();
   EXPECT_TRUE(client_impl_.GetHasPotentialBackdropFilterAnimation(
       element_id_, ElementListType::PENDING));
   EXPECT_TRUE(client_impl_.GetBackdropFilterIsCurrentlyAnimating(
@@ -3382,7 +3376,7 @@
   EXPECT_FALSE(client_impl_.GetBackdropFilterIsCurrentlyAnimating(
       element_id_, ElementListType::ACTIVE));
 
-  animation_impl_->ActivateKeyframeEffects();
+  animation_impl_->ActivateKeyframeModels();
   EXPECT_TRUE(client_impl_.GetHasPotentialBackdropFilterAnimation(
       element_id_, ElementListType::ACTIVE));
   EXPECT_TRUE(client_impl_.GetBackdropFilterIsCurrentlyAnimating(
@@ -3410,7 +3404,7 @@
   EXPECT_TRUE(client_impl_.GetBackdropFilterIsCurrentlyAnimating(
       element_id_, ElementListType::ACTIVE));
 
-  animation_impl_->ActivateKeyframeEffects();
+  animation_impl_->ActivateKeyframeModels();
   EXPECT_FALSE(client_impl_.GetHasPotentialBackdropFilterAnimation(
       element_id_, ElementListType::ACTIVE));
   EXPECT_FALSE(client_impl_.GetBackdropFilterIsCurrentlyAnimating(
@@ -3434,7 +3428,7 @@
   EXPECT_FALSE(client_impl_.GetBackdropFilterIsCurrentlyAnimating(
       element_id_, ElementListType::ACTIVE));
 
-  animation_impl_->ActivateKeyframeEffects();
+  animation_impl_->ActivateKeyframeModels();
   EXPECT_TRUE(client_impl_.GetHasPotentialBackdropFilterAnimation(
       element_id_, ElementListType::ACTIVE));
   EXPECT_TRUE(client_impl_.GetBackdropFilterIsCurrentlyAnimating(
@@ -3486,7 +3480,7 @@
   EXPECT_FALSE(client_impl_.GetBackdropFilterIsCurrentlyAnimating(
       element_id_, ElementListType::ACTIVE));
 
-  animation_impl_->ActivateKeyframeEffects();
+  animation_impl_->ActivateKeyframeModels();
   EXPECT_TRUE(client_impl_.GetHasPotentialBackdropFilterAnimation(
       element_id_, ElementListType::ACTIVE));
   EXPECT_FALSE(client_impl_.GetBackdropFilterIsCurrentlyAnimating(
@@ -3531,7 +3525,7 @@
   const int keyframe_model_id =
       AddOpacityTransitionToAnimation(animation_.get(), 1, 0.5f, 1.f, true);
   PushProperties();
-  animation_impl_->ActivateKeyframeEffects();
+  animation_impl_->ActivateKeyframeModels();
   animation_impl_->Tick(kInitialTickTime);
   animation_impl_->UpdateState(true, events.get());
   EXPECT_EQ(KeyframeModel::RUNNING,
@@ -3572,7 +3566,7 @@
   EXPECT_EQ(0.75f,
             client_impl_.GetOpacity(element_id_, ElementListType::ACTIVE));
 
-  animation_impl_->ActivateKeyframeEffects();
+  animation_impl_->ActivateKeyframeModels();
   events = CreateEventsForTesting();
   animation_impl_->UpdateState(true, events.get());
 
@@ -3605,7 +3599,7 @@
       AddOpacityTransitionToAnimation(animation_.get(), 1, 0.f, 1.f, true);
 
   PushProperties();
-  animation_impl_->ActivateKeyframeEffects();
+  animation_impl_->ActivateKeyframeModels();
   animation_impl_->Tick(kInitialTickTime);
   animation_impl_->UpdateState(true, events.get());
 
@@ -3653,7 +3647,7 @@
   EXPECT_EQ(0.5f,
             client_impl_.GetOpacity(element_id_, ElementListType::ACTIVE));
 
-  animation_impl_->ActivateKeyframeEffects();
+  animation_impl_->ActivateKeyframeModels();
 
   // The original animation no longer affect either elements, and the new
   // animation should now affect both elements.
@@ -3718,7 +3712,7 @@
   EXPECT_FALSE(animation_->keyframe_effect()->IsCurrentlyAnimatingProperty(
       TargetProperty::FILTER, ElementListType::ACTIVE));
 
-  animation_->ActivateKeyframeEffects();
+  animation_->ActivateKeyframeModels();
 
   EXPECT_TRUE(animation_->keyframe_effect()->IsCurrentlyAnimatingProperty(
       TargetProperty::OPACITY, ElementListType::PENDING));
@@ -3793,7 +3787,7 @@
   EXPECT_FALSE(animation_->keyframe_effect()->IsPotentiallyAnimatingProperty(
       TargetProperty::FILTER, ElementListType::ACTIVE));
 
-  animation_->ActivateKeyframeEffects();
+  animation_->ActivateKeyframeModels();
 
   EXPECT_TRUE(animation_->keyframe_effect()->IsPotentiallyAnimatingProperty(
       TargetProperty::OPACITY, ElementListType::PENDING));
diff --git a/cc/animation/keyframe_effect.cc b/cc/animation/keyframe_effect.cc
index cfd2a61..4c14471 100644
--- a/cc/animation/keyframe_effect.cc
+++ b/cc/animation/keyframe_effect.cc
@@ -46,9 +46,8 @@
 
 }  // namespace
 
-KeyframeEffect::KeyframeEffect(KeyframeEffectId id)
-    : animation_(),
-      id_(id),
+KeyframeEffect::KeyframeEffect(Animation* animation)
+    : animation_(animation),
       element_animations_(),
       needs_to_start_keyframe_models_(false),
       scroll_offset_animation_was_interrupted_(false),
@@ -59,14 +58,6 @@
   DCHECK(!has_bound_element_animations());
 }
 
-std::unique_ptr<KeyframeEffect> KeyframeEffect::Create(KeyframeEffectId id) {
-  return std::make_unique<KeyframeEffect>(id);
-}
-
-std::unique_ptr<KeyframeEffect> KeyframeEffect::CreateImplInstance() const {
-  return KeyframeEffect::Create(id());
-}
-
 void KeyframeEffect::SetNeedsPushProperties() {
   needs_push_properties_ = true;
 
@@ -364,7 +355,7 @@
   }
 }
 
-void KeyframeEffect::ActivateKeyframeEffects() {
+void KeyframeEffect::ActivateKeyframeModels() {
   DCHECK(has_bound_element_animations());
 
   bool keyframe_model_activated = false;
@@ -770,14 +761,10 @@
   if (element_id_ != keyframe_effect_impl->element_id_) {
     // We have to detach/attach via the Animation as it may need to inform
     // the host as well.
-    if (keyframe_effect_impl->has_attached_element()) {
-      keyframe_effect_impl->animation_->DetachElementForKeyframeEffect(
-          keyframe_effect_impl->element_id_, keyframe_effect_impl->id_);
-    }
-    if (element_id_) {
-      keyframe_effect_impl->animation_->AttachElementForKeyframeEffect(
-          element_id_, id_);
-    }
+    if (keyframe_effect_impl->has_attached_element())
+      keyframe_effect_impl->animation_->DetachElement();
+    if (element_id_)
+      keyframe_effect_impl->animation_->AttachElement(element_id_);
   }
 
   keyframe_effect_impl->scroll_offset_animation_was_interrupted_ =
@@ -809,10 +796,6 @@
   keyframe_effect_impl->UpdateTickingState();
 }
 
-void KeyframeEffect::SetAnimation(Animation* animation) {
-  animation_ = animation;
-}
-
 std::string KeyframeEffect::KeyframeModelsToString() const {
   std::string str;
   for (size_t i = 0; i < keyframe_models_.size(); i++) {
@@ -1087,7 +1070,7 @@
 
   AnimationEvent event(type,
                        {animation_->animation_timeline()->id(),
-                        animation_->id(), id(), keyframe_model.id()},
+                        animation_->id(), keyframe_model.id()},
                        keyframe_model.group(),
                        keyframe_model.target_property_id(), monotonic_time);
   event.is_impl_only = keyframe_model.is_impl_only();
@@ -1109,7 +1092,7 @@
 
   AnimationEvent takeover_event(AnimationEvent::TAKEOVER,
                                 {animation_->animation_timeline()->id(),
-                                 animation_->id(), id(), keyframe_model.id()},
+                                 animation_->id(), keyframe_model.id()},
                                 keyframe_model.group(),
                                 keyframe_model.target_property_id(),
                                 monotonic_time);
@@ -1122,7 +1105,7 @@
 
   AnimationEvent finished_event(AnimationEvent::FINISHED,
                                 {animation_->animation_timeline()->id(),
-                                 animation_->id(), id(), keyframe_model.id()},
+                                 animation_->id(), keyframe_model.id()},
                                 keyframe_model.group(),
                                 keyframe_model.target_property_id(),
                                 monotonic_time);
diff --git a/cc/animation/keyframe_effect.h b/cc/animation/keyframe_effect.h
index f30251d..1d26553 100644
--- a/cc/animation/keyframe_effect.h
+++ b/cc/animation/keyframe_effect.h
@@ -24,8 +24,6 @@
 class Animation;
 struct PropertyAnimationState;
 
-typedef size_t KeyframeEffectId;
-
 // A KeyframeEffect owns a group of KeyframeModels for a single target
 // (identified by an ElementId). It is responsible for managing the
 // KeyframeModels' running states (starting, running, paused, etc), as well as
@@ -39,15 +37,12 @@
 // given target.
 class CC_ANIMATION_EXPORT KeyframeEffect {
  public:
-  explicit KeyframeEffect(KeyframeEffectId id);
+  explicit KeyframeEffect(Animation* animation);
   KeyframeEffect(const KeyframeEffect&) = delete;
   virtual ~KeyframeEffect();
 
   KeyframeEffect& operator=(const KeyframeEffect&) = delete;
 
-  static std::unique_ptr<KeyframeEffect> Create(KeyframeEffectId id);
-  std::unique_ptr<KeyframeEffect> CreateImplInstance() const;
-
   // ElementAnimations object where this controller is listed.
   scoped_refptr<ElementAnimations> element_animations() const {
     return element_animations_;
@@ -87,7 +82,6 @@
                                 KeyframeModel* keyframe_model,
                                 AnimationTarget* target);
   void RemoveFromTicking();
-  bool is_ticking() const { return is_ticking_; }
 
   void UpdateState(bool start_ready_keyframe_models, AnimationEvents* events);
   void UpdateTickingState();
@@ -101,7 +95,7 @@
   void AbortKeyframeModelsWithProperty(TargetProperty::Type target_property,
                                        bool needs_completion);
 
-  void ActivateKeyframeEffects();
+  void ActivateKeyframeModels();
 
   void KeyframeModelAdded();
 
@@ -156,10 +150,7 @@
       KeyframeEffect* element_keyframe_effect_impl) const;
   void PushPropertiesTo(KeyframeEffect* keyframe_effect_impl);
 
-  void SetAnimation(Animation* animation);
-
   std::string KeyframeModelsToString() const;
-  KeyframeEffectId id() const { return id_; }
 
  private:
   void StartKeyframeModels(base::TimeTicks monotonic_time);
@@ -183,7 +174,6 @@
   std::vector<std::unique_ptr<KeyframeModel>> keyframe_models_;
   Animation* animation_;
 
-  KeyframeEffectId id_;
   ElementId element_id_;
 
   // element_animations_ is non-null if controller is attached to an element.
diff --git a/cc/animation/scroll_offset_animations_impl.cc b/cc/animation/scroll_offset_animations_impl.cc
index 1a15151..f7475aa 100644
--- a/cc/animation/scroll_offset_animations_impl.cc
+++ b/cc/animation/scroll_offset_animations_impl.cc
@@ -6,12 +6,12 @@
 
 #include "base/trace_event/trace_event.h"
 #include "base/trace_event/traced_value.h"
+#include "cc/animation/animation.h"
 #include "cc/animation/animation_host.h"
 #include "cc/animation/animation_id_provider.h"
 #include "cc/animation/animation_timeline.h"
 #include "cc/animation/element_animations.h"
 #include "cc/animation/scroll_offset_animation_curve_factory.h"
-#include "cc/animation/single_keyframe_effect_animation.h"
 #include "cc/animation/timing_function.h"
 
 namespace cc {
@@ -21,8 +21,8 @@
     : animation_host_(animation_host),
       scroll_offset_timeline_(
           AnimationTimeline::Create(AnimationIdProvider::NextTimelineId())),
-      scroll_offset_animation_(SingleKeyframeEffectAnimation::Create(
-          AnimationIdProvider::NextAnimationId())) {
+      scroll_offset_animation_(
+          Animation::Create(AnimationIdProvider::NextAnimationId())) {
   scroll_offset_timeline_->set_is_impl_only(true);
   scroll_offset_animation_->set_animation_delegate(this);
 
@@ -93,7 +93,7 @@
     base::TimeTicks frame_monotonic_time,
     base::TimeDelta delayed_by) {
   DCHECK(scroll_offset_animation_);
-  if (!scroll_offset_animation_->has_element_animations()) {
+  if (!scroll_offset_animation_->element_animations()) {
     TRACE_EVENT_INSTANT0("cc", "No element animation exists",
                          TRACE_EVENT_SCOPE_THREAD);
     return false;
@@ -149,7 +149,7 @@
     return;
   }
 
-  if (!scroll_offset_animation_->has_element_animations()) {
+  if (!scroll_offset_animation_->element_animations()) {
     TRACE_EVENT_INSTANT0("cc", "no scroll adjustment no element animation",
                          TRACE_EVENT_SCOPE_THREAD);
     return;
@@ -205,7 +205,7 @@
 }
 
 bool ScrollOffsetAnimationsImpl::IsAnimating() const {
-  if (!scroll_offset_animation_->has_element_animations())
+  if (!scroll_offset_animation_->element_animations())
     return false;
 
   KeyframeModel* keyframe_model =
diff --git a/cc/animation/scroll_offset_animations_impl.h b/cc/animation/scroll_offset_animations_impl.h
index e9f192b6..8e0a3116 100644
--- a/cc/animation/scroll_offset_animations_impl.h
+++ b/cc/animation/scroll_offset_animations_impl.h
@@ -13,9 +13,9 @@
 
 namespace cc {
 
+class Animation;
 class AnimationHost;
 class AnimationTimeline;
-class SingleKeyframeEffectAnimation;
 
 // Contains an AnimationTimeline and its Animation that owns the impl
 // only scroll offset animations running on a particular CC Layer.
@@ -92,7 +92,7 @@
   // We have just one animation for impl-only scroll offset animations.
   // I.e. only one element can have an impl-only scroll offset animation at
   // any given time.
-  scoped_refptr<SingleKeyframeEffectAnimation> scroll_offset_animation_;
+  scoped_refptr<Animation> scroll_offset_animation_;
 };
 
 }  // namespace cc
diff --git a/cc/animation/single_keyframe_effect_animation.cc b/cc/animation/single_keyframe_effect_animation.cc
deleted file mode 100644
index 53e4ff7..0000000
--- a/cc/animation/single_keyframe_effect_animation.cc
+++ /dev/null
@@ -1,117 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "cc/animation/single_keyframe_effect_animation.h"
-
-#include <inttypes.h>
-#include <algorithm>
-
-#include "base/stl_util.h"
-#include "base/strings/stringprintf.h"
-#include "cc/animation/animation_delegate.h"
-#include "cc/animation/animation_events.h"
-#include "cc/animation/animation_host.h"
-#include "cc/animation/animation_timeline.h"
-#include "cc/animation/keyframe_effect.h"
-#include "cc/animation/scroll_offset_animation_curve.h"
-#include "cc/animation/transform_operations.h"
-#include "cc/trees/property_animation_state.h"
-
-namespace cc {
-
-scoped_refptr<SingleKeyframeEffectAnimation>
-SingleKeyframeEffectAnimation::Create(int id) {
-  return base::WrapRefCounted(new SingleKeyframeEffectAnimation(id));
-}
-
-SingleKeyframeEffectAnimation::SingleKeyframeEffectAnimation(int id)
-    : SingleKeyframeEffectAnimation(id, nullptr) {}
-
-SingleKeyframeEffectAnimation::SingleKeyframeEffectAnimation(
-    int id,
-    size_t keyframe_effect_id)
-    : SingleKeyframeEffectAnimation(
-          id,
-          std::make_unique<KeyframeEffect>(keyframe_effect_id)) {}
-
-SingleKeyframeEffectAnimation::SingleKeyframeEffectAnimation(
-    int id,
-    std::unique_ptr<KeyframeEffect> keyframe_effect)
-    : Animation(id) {
-  DCHECK(id_);
-  if (!keyframe_effect)
-    keyframe_effect.reset(new KeyframeEffect(NextKeyframeEffectId()));
-
-  AddKeyframeEffect(std::move(keyframe_effect));
-}
-
-SingleKeyframeEffectAnimation::~SingleKeyframeEffectAnimation() {}
-
-KeyframeEffect* SingleKeyframeEffectAnimation::GetKeyframeEffect() const {
-  DCHECK_EQ(keyframe_effects_.size(), 1u);
-  return keyframe_effects_[0].get();
-}
-
-scoped_refptr<Animation> SingleKeyframeEffectAnimation::CreateImplInstance()
-    const {
-  DCHECK(GetKeyframeEffect());
-  scoped_refptr<SingleKeyframeEffectAnimation> animation = base::WrapRefCounted(
-      new SingleKeyframeEffectAnimation(id(), GetKeyframeEffect()->id()));
-  return animation;
-}
-
-ElementId SingleKeyframeEffectAnimation::element_id() const {
-  return GetKeyframeEffect()->element_id();
-}
-
-void SingleKeyframeEffectAnimation::AttachElement(ElementId element_id) {
-  AttachElementForKeyframeEffect(element_id, GetKeyframeEffect()->id());
-}
-
-KeyframeEffect* SingleKeyframeEffectAnimation::keyframe_effect() const {
-  return GetKeyframeEffect();
-}
-
-void SingleKeyframeEffectAnimation::AddKeyframeModel(
-    std::unique_ptr<KeyframeModel> keyframe_model) {
-  AddKeyframeModelForKeyframeEffect(std::move(keyframe_model),
-                                    GetKeyframeEffect()->id());
-}
-
-void SingleKeyframeEffectAnimation::PauseKeyframeModel(
-    int keyframe_model_id,
-    base::TimeDelta time_offset) {
-  PauseKeyframeModelForKeyframeEffect(keyframe_model_id, time_offset,
-                                      GetKeyframeEffect()->id());
-}
-
-void SingleKeyframeEffectAnimation::RemoveKeyframeModel(int keyframe_model_id) {
-  RemoveKeyframeModelForKeyframeEffect(keyframe_model_id,
-                                       GetKeyframeEffect()->id());
-}
-
-void SingleKeyframeEffectAnimation::AbortKeyframeModel(int keyframe_model_id) {
-  AbortKeyframeModelForKeyframeEffect(keyframe_model_id,
-                                      GetKeyframeEffect()->id());
-}
-
-void SingleKeyframeEffectAnimation::NotifyKeyframeModelFinishedForTesting(
-    int timeline_id,
-    int keyframe_model_id,
-    TargetProperty::Type target_property,
-    int group_id) {
-  AnimationEvent event(
-      AnimationEvent::FINISHED,
-      {timeline_id, id(), GetKeyframeEffect()->id(), keyframe_model_id},
-      group_id, target_property, base::TimeTicks());
-  DispatchAndDelegateAnimationEvent(event);
-}
-
-KeyframeModel* SingleKeyframeEffectAnimation::GetKeyframeModel(
-    TargetProperty::Type target_property) const {
-  return GetKeyframeModelForKeyframeEffect(target_property,
-                                           GetKeyframeEffect()->id());
-}
-
-}  // namespace cc
diff --git a/cc/animation/single_keyframe_effect_animation.h b/cc/animation/single_keyframe_effect_animation.h
deleted file mode 100644
index de6a45df..0000000
--- a/cc/animation/single_keyframe_effect_animation.h
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CC_ANIMATION_SINGLE_KEYFRAME_EFFECT_ANIMATION_H_
-#define CC_ANIMATION_SINGLE_KEYFRAME_EFFECT_ANIMATION_H_
-
-#include <vector>
-
-#include <memory>
-#include "base/memory/ref_counted.h"
-#include "base/time/time.h"
-#include "cc/animation/animation.h"
-#include "cc/animation/animation_curve.h"
-#include "cc/animation/animation_export.h"
-#include "cc/animation/element_animations.h"
-#include "cc/animation/keyframe_model.h"
-#include "cc/paint/element_id.h"
-
-namespace cc {
-
-class KeyframeEffect;
-
-// SingleKeyframeEffectAnimation is a sub-class of Animation. It
-// serves as a bridge between the cc animation clients and cc because we
-// previously only supported single effect(keyframe_effect) per animation.
-//
-// There is a 1:1 relationship between SingleKeyframeEffectAnimation and
-// the KeyframeEffect. In general, the base class Animation is a 1:N
-// relationship to allow for grouped animations.
-//
-// TODO(yigu): Deprecate SingleKeyframeEffectAnimation once grouped
-// animations are fully supported by all clients.
-class CC_ANIMATION_EXPORT SingleKeyframeEffectAnimation : public Animation {
- public:
-  static scoped_refptr<SingleKeyframeEffectAnimation> Create(int id);
-  scoped_refptr<Animation> CreateImplInstance() const override;
-
-  SingleKeyframeEffectAnimation(const SingleKeyframeEffectAnimation&) = delete;
-  SingleKeyframeEffectAnimation& operator=(
-      const SingleKeyframeEffectAnimation&) = delete;
-
-  ElementId element_id() const;
-
-  void AttachElement(ElementId element_id);
-
-  KeyframeEffect* keyframe_effect() const;
-  void AddKeyframeModel(std::unique_ptr<KeyframeModel> keyframe_model);
-  void PauseKeyframeModel(int keyframe_model_id, base::TimeDelta time_offset);
-  virtual void RemoveKeyframeModel(int keyframe_model_id);
-  void AbortKeyframeModel(int keyframe_model_id);
-
-  void NotifyKeyframeModelFinishedForTesting(
-      int timeline_id,
-      int keyframe_model_id,
-      TargetProperty::Type target_property,
-      int group_id);
-  KeyframeModel* GetKeyframeModel(TargetProperty::Type target_property) const;
-
- private:
-  friend class base::RefCounted<SingleKeyframeEffectAnimation>;
-
-  KeyframeEffect* GetKeyframeEffect() const;
-
- protected:
-  explicit SingleKeyframeEffectAnimation(int id);
-  explicit SingleKeyframeEffectAnimation(int id, size_t keyframe_effect_id);
-  explicit SingleKeyframeEffectAnimation(int id,
-                                         std::unique_ptr<KeyframeEffect>);
-
-  ~SingleKeyframeEffectAnimation() override;
-};
-
-}  // namespace cc
-
-#endif  // CC_ANIMATION_SINGLE_KEYFRAME_EFFECT_ANIMATION_H_
diff --git a/cc/animation/worklet_animation.cc b/cc/animation/worklet_animation.cc
index 811b9e4..bf22c2d 100644
--- a/cc/animation/worklet_animation.cc
+++ b/cc/animation/worklet_animation.cc
@@ -44,7 +44,7 @@
     std::unique_ptr<AnimationEffectTimings> effect_timings,
     bool is_controlling_instance,
     std::unique_ptr<KeyframeEffect> effect)
-    : SingleKeyframeEffectAnimation(cc_animation_id, std::move(effect)),
+    : Animation(cc_animation_id, std::move(effect)),
       worklet_animation_id_(worklet_animation_id),
       name_(name),
       scroll_timeline_(std::move(scroll_timeline)),
@@ -106,8 +106,8 @@
   // animations lifecycle. To avoid this we pause the underlying keyframe effect
   // at the local time obtained from the user script - essentially turning each
   // call to |WorkletAnimation::Tick| into a seek in the effect.
-  keyframe_effect()->Pause(local_time_.value());
-  keyframe_effect()->Tick(monotonic_time);
+  keyframe_effect_->Pause(local_time_.value());
+  keyframe_effect_->Tick(monotonic_time);
 }
 
 void WorkletAnimation::UpdateState(bool start_ready_animations,
@@ -288,7 +288,7 @@
 
 void WorkletAnimation::RemoveKeyframeModel(int keyframe_model_id) {
   state_ = State::REMOVED;
-  SingleKeyframeEffectAnimation::RemoveKeyframeModel(keyframe_model_id);
+  Animation::RemoveKeyframeModel(keyframe_model_id);
 }
 
 bool WorkletAnimation::IsWorkletAnimation() const {
diff --git a/cc/animation/worklet_animation.h b/cc/animation/worklet_animation.h
index 84e52079..5c988fb 100644
--- a/cc/animation/worklet_animation.h
+++ b/cc/animation/worklet_animation.h
@@ -8,9 +8,9 @@
 #include "base/gtest_prod_util.h"
 #include "base/optional.h"
 #include "base/time/time.h"
+#include "cc/animation/animation.h"
 #include "cc/animation/animation_export.h"
 #include "cc/animation/animation_host.h"
-#include "cc/animation/single_keyframe_effect_animation.h"
 #include "cc/trees/property_tree.h"
 
 namespace cc {
@@ -33,8 +33,7 @@
 // When Blink WorkletAnimation is updated, it calls the UI thread instance to
 // modify its properties. The updated properties are pushed by the UI thread
 // instance to the Impl thread instance during commit.
-class CC_ANIMATION_EXPORT WorkletAnimation final
-    : public SingleKeyframeEffectAnimation {
+class CC_ANIMATION_EXPORT WorkletAnimation final : public Animation {
  public:
   enum class State { PENDING, RUNNING, REMOVED };
   WorkletAnimation(int cc_animation_id,
diff --git a/cc/animation/worklet_animation_unittest.cc b/cc/animation/worklet_animation_unittest.cc
index cd33dee..c763f49 100644
--- a/cc/animation/worklet_animation_unittest.cc
+++ b/cc/animation/worklet_animation_unittest.cc
@@ -6,6 +6,7 @@
 
 #include <utility>
 #include "base/memory/ptr_util.h"
+#include "cc/animation/keyframe_effect.h"
 #include "cc/animation/scroll_timeline.h"
 #include "cc/test/animation_test_common.h"
 #include "cc/test/animation_timelines_test_common.h"
@@ -25,7 +26,8 @@
 
 class MockKeyframeEffect : public KeyframeEffect {
  public:
-  MockKeyframeEffect() : KeyframeEffect(0) {}
+  explicit MockKeyframeEffect(Animation* animation)
+      : KeyframeEffect(animation) {}
   MOCK_METHOD1(Tick, void(base::TimeTicks monotonic_time));
 };
 
@@ -65,7 +67,7 @@
 
 TEST_F(WorkletAnimationTest, NonImplInstanceDoesNotTickKeyframe) {
   std::unique_ptr<MockKeyframeEffect> effect =
-      std::make_unique<MockKeyframeEffect>();
+      std::make_unique<MockKeyframeEffect>(worklet_animation_.get());
   MockKeyframeEffect* mock_effect = effect.get();
 
   scoped_refptr<WorkletAnimation> worklet_animation =
diff --git a/cc/test/animation_test_common.cc b/cc/test/animation_test_common.cc
index c8b598ef..f1957d8 100644
--- a/cc/test/animation_test_common.cc
+++ b/cc/test/animation_test_common.cc
@@ -5,6 +5,7 @@
 #include "cc/test/animation_test_common.h"
 
 #include "base/memory/ptr_util.h"
+#include "cc/animation/animation.h"
 #include "cc/animation/animation_host.h"
 #include "cc/animation/animation_id_provider.h"
 #include "cc/animation/element_animations.h"
@@ -12,7 +13,6 @@
 #include "cc/animation/keyframed_animation_curve.h"
 #include "cc/animation/scroll_offset_animation_curve.h"
 #include "cc/animation/scroll_offset_animation_curve_factory.h"
-#include "cc/animation/single_keyframe_effect_animation.h"
 #include "cc/animation/timing_function.h"
 #include "cc/animation/transform_operations.h"
 #include "cc/base/time_util.h"
@@ -33,8 +33,7 @@
                          double duration,
                          float start_opacity,
                          float end_opacity,
-                         bool use_timing_function,
-                         KeyframeEffectId effect_id) {
+                         bool use_timing_function) {
   std::unique_ptr<KeyframedFloatAnimationCurve> curve(
       KeyframedFloatAnimationCurve::Create());
 
@@ -55,16 +54,14 @@
       TargetProperty::OPACITY));
   keyframe_model->set_needs_synchronized_start_time(true);
 
-  target->AddKeyframeModelForKeyframeEffect(std::move(keyframe_model),
-                                            effect_id);
+  target->AddKeyframeModel(std::move(keyframe_model));
   return id;
 }
 
 int AddAnimatedTransform(Animation* target,
                          double duration,
                          TransformOperations start_operations,
-                         TransformOperations operations,
-                         KeyframeEffectId effect_id) {
+                         TransformOperations operations) {
   std::unique_ptr<KeyframedTransformAnimationCurve> curve(
       KeyframedTransformAnimationCurve::Create());
 
@@ -83,16 +80,14 @@
       TargetProperty::TRANSFORM));
   keyframe_model->set_needs_synchronized_start_time(true);
 
-  target->AddKeyframeModelForKeyframeEffect(std::move(keyframe_model),
-                                            effect_id);
+  target->AddKeyframeModel(std::move(keyframe_model));
   return id;
 }
 
 int AddAnimatedTransform(Animation* target,
                          double duration,
                          int delta_x,
-                         int delta_y,
-                         KeyframeEffectId effect_id) {
+                         int delta_y) {
   TransformOperations start_operations;
   if (duration > 0.0) {
     start_operations.AppendTranslate(0, 0, 0.0);
@@ -100,15 +95,13 @@
 
   TransformOperations operations;
   operations.AppendTranslate(delta_x, delta_y, 0.0);
-  return AddAnimatedTransform(target, duration, start_operations, operations,
-                              effect_id);
+  return AddAnimatedTransform(target, duration, start_operations, operations);
 }
 
 int AddAnimatedFilter(Animation* target,
                       double duration,
                       float start_brightness,
-                      float end_brightness,
-                      KeyframeEffectId effect_id) {
+                      float end_brightness) {
   std::unique_ptr<KeyframedFilterAnimationCurve> curve(
       KeyframedFilterAnimationCurve::Create());
 
@@ -132,16 +125,14 @@
       TargetProperty::FILTER));
   keyframe_model->set_needs_synchronized_start_time(true);
 
-  target->AddKeyframeModelForKeyframeEffect(std::move(keyframe_model),
-                                            effect_id);
+  target->AddKeyframeModel(std::move(keyframe_model));
   return id;
 }
 
 int AddAnimatedBackdropFilter(Animation* target,
                               double duration,
                               float start_invert,
-                              float end_invert,
-                              KeyframeEffectId effect_id) {
+                              float end_invert) {
   std::unique_ptr<KeyframedFilterAnimationCurve> curve(
       KeyframedFilterAnimationCurve::Create());
 
@@ -164,8 +155,7 @@
       TargetProperty::BACKDROP_FILTER));
   keyframe_model->set_needs_synchronized_start_time(true);
 
-  target->AddKeyframeModelForKeyframeEffect(std::move(keyframe_model),
-                                            effect_id);
+  target->AddKeyframeModel(std::move(keyframe_model));
   return id;
 }
 
@@ -251,8 +241,7 @@
 
 int AddScrollOffsetAnimationToAnimation(Animation* animation,
                                         gfx::ScrollOffset initial_value,
-                                        gfx::ScrollOffset target_value,
-                                        KeyframeEffectId effect_id) {
+                                        gfx::ScrollOffset target_value) {
   std::unique_ptr<ScrollOffsetAnimationCurve> curve(
       ScrollOffsetAnimationCurveFactory::CreateEaseInOutAnimationForTesting(
           target_value));
@@ -265,8 +254,7 @@
       TargetProperty::SCROLL_OFFSET));
   keyframe_model->SetIsImplOnly();
 
-  animation->AddKeyframeModelForKeyframeEffect(std::move(keyframe_model),
-                                               effect_id);
+  animation->AddKeyframeModel(std::move(keyframe_model));
 
   return id;
 }
@@ -274,54 +262,48 @@
 int AddAnimatedTransformToAnimation(Animation* animation,
                                     double duration,
                                     int delta_x,
-                                    int delta_y,
-                                    KeyframeEffectId effect_id) {
-  return AddAnimatedTransform(animation, duration, delta_x, delta_y, effect_id);
+                                    int delta_y) {
+  return AddAnimatedTransform(animation, duration, delta_x, delta_y);
 }
 
 int AddAnimatedTransformToAnimation(Animation* animation,
                                     double duration,
                                     TransformOperations start_operations,
-                                    TransformOperations operations,
-                                    KeyframeEffectId effect_id) {
-  return AddAnimatedTransform(animation, duration, start_operations, operations,
-                              effect_id);
+                                    TransformOperations operations) {
+  return AddAnimatedTransform(animation, duration, start_operations,
+                              operations);
 }
 
 int AddOpacityTransitionToAnimation(Animation* animation,
                                     double duration,
                                     float start_opacity,
                                     float end_opacity,
-                                    bool use_timing_function,
-                                    KeyframeEffectId effect_id) {
+                                    bool use_timing_function) {
   return AddOpacityTransition(animation, duration, start_opacity, end_opacity,
-                              use_timing_function, effect_id);
+                              use_timing_function);
 }
 
 int AddAnimatedFilterToAnimation(Animation* animation,
                                  double duration,
                                  float start_brightness,
-                                 float end_brightness,
-                                 KeyframeEffectId effect_id) {
+                                 float end_brightness) {
   return AddAnimatedFilter(animation, duration, start_brightness,
-                           end_brightness, effect_id);
+                           end_brightness);
 }
 
 int AddAnimatedBackdropFilterToAnimation(Animation* animation,
                                          double duration,
                                          float start_invert,
-                                         float end_invert,
-                                         KeyframeEffectId effect_id) {
+                                         float end_invert) {
   return AddAnimatedBackdropFilter(animation, duration, start_invert,
-                                   end_invert, effect_id);
+                                   end_invert);
 }
 
 int AddOpacityStepsToAnimation(Animation* animation,
                                double duration,
                                float start_opacity,
                                float end_opacity,
-                               int num_steps,
-                               KeyframeEffectId effect_id) {
+                               int num_steps) {
   std::unique_ptr<KeyframedFloatAnimationCurve> curve(
       KeyframedFloatAnimationCurve::Create());
 
@@ -340,8 +322,7 @@
       TargetProperty::OPACITY));
   keyframe_model->set_needs_synchronized_start_time(true);
 
-  animation->AddKeyframeModelForKeyframeEffect(std::move(keyframe_model),
-                                               effect_id);
+  animation->AddKeyframeModel(std::move(keyframe_model));
   return id;
 }
 
@@ -349,9 +330,8 @@
     ElementId element_id,
     scoped_refptr<AnimationTimeline> timeline,
     std::unique_ptr<KeyframeModel> keyframe_model) {
-  scoped_refptr<SingleKeyframeEffectAnimation> animation =
-      SingleKeyframeEffectAnimation::Create(
-          AnimationIdProvider::NextAnimationId());
+  scoped_refptr<Animation> animation =
+      Animation::Create(AnimationIdProvider::NextAnimationId());
   timeline->AttachAnimation(animation);
   animation->AttachElement(element_id);
   DCHECK(animation->keyframe_effect()->element_animations());
@@ -403,9 +383,8 @@
     double duration,
     float start_brightness,
     float end_brightness) {
-  scoped_refptr<SingleKeyframeEffectAnimation> animation =
-      SingleKeyframeEffectAnimation::Create(
-          AnimationIdProvider::NextAnimationId());
+  scoped_refptr<Animation> animation =
+      Animation::Create(AnimationIdProvider::NextAnimationId());
   timeline->AttachAnimation(animation);
   animation->AttachElement(element_id);
   DCHECK(animation->keyframe_effect()->element_animations());
@@ -419,9 +398,8 @@
     double duration,
     int delta_x,
     int delta_y) {
-  scoped_refptr<SingleKeyframeEffectAnimation> animation =
-      SingleKeyframeEffectAnimation::Create(
-          AnimationIdProvider::NextAnimationId());
+  scoped_refptr<Animation> animation =
+      Animation::Create(AnimationIdProvider::NextAnimationId());
   timeline->AttachAnimation(animation);
   animation->AttachElement(element_id);
   DCHECK(animation->keyframe_effect()->element_animations());
@@ -435,9 +413,8 @@
     double duration,
     TransformOperations start_operations,
     TransformOperations operations) {
-  scoped_refptr<SingleKeyframeEffectAnimation> animation =
-      SingleKeyframeEffectAnimation::Create(
-          AnimationIdProvider::NextAnimationId());
+  scoped_refptr<Animation> animation =
+      Animation::Create(AnimationIdProvider::NextAnimationId());
   timeline->AttachAnimation(animation);
   animation->AttachElement(element_id);
   DCHECK(animation->keyframe_effect()->element_animations());
@@ -452,9 +429,8 @@
     float start_opacity,
     float end_opacity,
     bool use_timing_function) {
-  scoped_refptr<SingleKeyframeEffectAnimation> animation =
-      SingleKeyframeEffectAnimation::Create(
-          AnimationIdProvider::NextAnimationId());
+  scoped_refptr<Animation> animation =
+      Animation::Create(AnimationIdProvider::NextAnimationId());
   timeline->AttachAnimation(animation);
   animation->AttachElement(element_id);
   DCHECK(animation->keyframe_effect()->element_animations());
diff --git a/cc/test/animation_test_common.h b/cc/test/animation_test_common.h
index a58b19379..bb54bbb 100644
--- a/cc/test/animation_test_common.h
+++ b/cc/test/animation_test_common.h
@@ -7,7 +7,6 @@
 
 #include "cc/animation/animation_curve.h"
 #include "cc/animation/animation_timeline.h"
-#include "cc/animation/keyframe_effect.h"
 #include "cc/animation/keyframe_model.h"
 #include "cc/animation/transform_operations.h"
 #include "cc/paint/element_id.h"
@@ -72,46 +71,39 @@
 
 int AddScrollOffsetAnimationToAnimation(Animation* animation,
                                         gfx::ScrollOffset initial_value,
-                                        gfx::ScrollOffset target_value,
-                                        KeyframeEffectId effect_id = 0);
+                                        gfx::ScrollOffset target_value);
 
 int AddAnimatedTransformToAnimation(Animation* animation,
                                     double duration,
                                     int delta_x,
-                                    int delta_y,
-                                    KeyframeEffectId effect_id = 0);
+                                    int delta_y);
 
 int AddAnimatedTransformToAnimation(Animation* animation,
                                     double duration,
                                     TransformOperations start_operations,
-                                    TransformOperations operations,
-                                    KeyframeEffectId effect_id = 0);
+                                    TransformOperations operations);
 
 int AddOpacityTransitionToAnimation(Animation* animation,
                                     double duration,
                                     float start_opacity,
                                     float end_opacity,
-                                    bool use_timing_function,
-                                    KeyframeEffectId effect_id = 0);
+                                    bool use_timing_function);
 
 int AddAnimatedFilterToAnimation(Animation* animation,
                                  double duration,
                                  float start_brightness,
-                                 float end_brightness,
-                                 KeyframeEffectId effect_id = 0);
+                                 float end_brightness);
 
 int AddAnimatedBackdropFilterToAnimation(Animation* animation,
                                          double duration,
                                          float start_invert,
-                                         float end_invert,
-                                         KeyframeEffectId effect_id = 0);
+                                         float end_invert);
 
 int AddOpacityStepsToAnimation(Animation* animation,
                                double duration,
                                float start_opacity,
                                float end_opacity,
-                               int num_steps,
-                               KeyframeEffectId effect_id = 0);
+                               int num_steps);
 
 void AddKeyframeModelToElementWithAnimation(
     ElementId element_id,
diff --git a/cc/test/animation_timelines_test_common.cc b/cc/test/animation_timelines_test_common.cc
index 8ddf05b..4af487f 100644
--- a/cc/test/animation_timelines_test_common.cc
+++ b/cc/test/animation_timelines_test_common.cc
@@ -5,12 +5,12 @@
 #include "cc/test/animation_timelines_test_common.h"
 
 #include "base/memory/ptr_util.h"
+#include "cc/animation/animation.h"
 #include "cc/animation/animation_events.h"
 #include "cc/animation/animation_id_provider.h"
 #include "cc/animation/animation_timeline.h"
 #include "cc/animation/element_animations.h"
 #include "cc/animation/keyframe_effect.h"
-#include "cc/animation/single_keyframe_effect_animation.h"
 #include "cc/paint/filter_operation.h"
 #include "cc/paint/filter_operations.h"
 #include "cc/trees/property_tree.h"
@@ -426,6 +426,7 @@
 
 void AnimationTimelinesTest::SetUp() {
   timeline_ = AnimationTimeline::Create(timeline_id_);
+  animation_ = Animation::Create(animation_id_);
 }
 
 void AnimationTimelinesTest::TearDown() {
@@ -462,7 +463,7 @@
   timeline_->AttachAnimation(animation_);
   animation_->AttachElement(element_id_);
 
-  element_animations_ = animation_->keyframe_effect()->element_animations();
+  element_animations_ = animation_->element_animations();
 }
 
 void AnimationTimelinesTest::CreateImplTimelineAndAnimation() {
@@ -473,12 +474,10 @@
 void AnimationTimelinesTest::GetImplTimelineAndAnimationByID() {
   timeline_impl_ = host_impl_->GetTimelineById(timeline_id_);
   EXPECT_TRUE(timeline_impl_);
-  animation_impl_ = static_cast<SingleKeyframeEffectAnimation*>(
-      timeline_impl_->GetAnimationById(animation_id_));
+  animation_impl_ = timeline_impl_->GetAnimationById(animation_id_);
   EXPECT_TRUE(animation_impl_);
 
-  element_animations_impl_ =
-      animation_impl_->keyframe_effect()->element_animations();
+  element_animations_impl_ = animation_impl_->element_animations();
 }
 
 void AnimationTimelinesTest::ReleaseRefPtrs() {
diff --git a/cc/test/animation_timelines_test_common.h b/cc/test/animation_timelines_test_common.h
index 34041fd..e7ab3cd 100644
--- a/cc/test/animation_timelines_test_common.h
+++ b/cc/test/animation_timelines_test_common.h
@@ -18,8 +18,8 @@
 
 namespace cc {
 
+class Animation;
 class KeyframeEffect;
-class SingleKeyframeEffectAnimation;
 
 class TestLayer {
  public:
@@ -311,11 +311,11 @@
   int next_test_layer_id_;
 
   scoped_refptr<AnimationTimeline> timeline_;
-  scoped_refptr<SingleKeyframeEffectAnimation> animation_;
+  scoped_refptr<Animation> animation_;
   scoped_refptr<ElementAnimations> element_animations_;
 
   scoped_refptr<AnimationTimeline> timeline_impl_;
-  scoped_refptr<SingleKeyframeEffectAnimation> animation_impl_;
+  scoped_refptr<Animation> animation_impl_;
   scoped_refptr<ElementAnimations> element_animations_impl_;
 };
 
diff --git a/cc/test/layer_tree_test.cc b/cc/test/layer_tree_test.cc
index 6aaed1eb..69601f1 100644
--- a/cc/test/layer_tree_test.cc
+++ b/cc/test/layer_tree_test.cc
@@ -17,10 +17,10 @@
 #include "base/threading/thread_task_runner_handle.h"
 #include "base/time/time.h"
 #include "build/build_config.h"
+#include "cc/animation/animation.h"
 #include "cc/animation/animation_host.h"
 #include "cc/animation/keyframe_effect.h"
 #include "cc/animation/keyframe_model.h"
-#include "cc/animation/single_keyframe_effect_animation.h"
 #include "cc/animation/timing_function.h"
 #include "cc/base/switches.h"
 #include "cc/input/input_handler.h"
@@ -318,7 +318,7 @@
     LayerTreeHostImpl::UpdateAnimationState(start_ready_animations);
     bool has_unfinished_animation = false;
     for (const auto& it : animation_host()->ticking_animations_for_testing()) {
-      if (it.get()->TickingKeyframeModelsCount()) {
+      if (it->keyframe_effect()->HasTickingKeyframeModel()) {
         has_unfinished_animation = true;
         break;
       }
@@ -672,7 +672,7 @@
 }
 
 void LayerTreeTest::PostAddNoDamageAnimationToMainThread(
-    SingleKeyframeEffectAnimation* animation_to_receive_animation) {
+    Animation* animation_to_receive_animation) {
   main_task_runner_->PostTask(
       FROM_HERE,
       base::BindOnce(&LayerTreeTest::DispatchAddNoDamageAnimation,
@@ -681,7 +681,7 @@
 }
 
 void LayerTreeTest::PostAddOpacityAnimationToMainThread(
-    SingleKeyframeEffectAnimation* animation_to_receive_animation) {
+    Animation* animation_to_receive_animation) {
   main_task_runner_->PostTask(
       FROM_HERE,
       base::BindOnce(
@@ -690,7 +690,7 @@
 }
 
 void LayerTreeTest::PostAddOpacityAnimationToMainThreadInstantly(
-    SingleKeyframeEffectAnimation* animation_to_receive_animation) {
+    Animation* animation_to_receive_animation) {
   main_task_runner_->PostTask(
       FROM_HERE,
       base::BindOnce(&LayerTreeTest::DispatchAddOpacityAnimation,
@@ -699,7 +699,7 @@
 }
 
 void LayerTreeTest::PostAddOpacityAnimationToMainThreadDelayed(
-    SingleKeyframeEffectAnimation* animation_to_receive_animation) {
+    Animation* animation_to_receive_animation) {
   main_task_runner_->PostTask(
       FROM_HERE,
       base::BindOnce(&LayerTreeTest::DispatchAddOpacityAnimation,
@@ -924,7 +924,7 @@
 }
 
 void LayerTreeTest::DispatchAddNoDamageAnimation(
-    SingleKeyframeEffectAnimation* animation_to_receive_animation,
+    Animation* animation_to_receive_animation,
     double animation_duration) {
   DCHECK(main_task_runner_->BelongsToCurrentThread());
 
@@ -935,7 +935,7 @@
 }
 
 void LayerTreeTest::DispatchAddOpacityAnimation(
-    SingleKeyframeEffectAnimation* animation_to_receive_animation,
+    Animation* animation_to_receive_animation,
     double animation_duration) {
   DCHECK(main_task_runner_->BelongsToCurrentThread());
 
diff --git a/cc/test/layer_tree_test.h b/cc/test/layer_tree_test.h
index 4bbc7e8..ecf9414 100644
--- a/cc/test/layer_tree_test.h
+++ b/cc/test/layer_tree_test.h
@@ -25,13 +25,13 @@
 
 namespace cc {
 
+class Animation;
 class AnimationHost;
 class LayerImpl;
 class LayerTreeHost;
 class LayerTreeHostForTesting;
 class LayerTreeTestLayerTreeFrameSinkClient;
 class Proxy;
-class SingleKeyframeEffectAnimation;
 class TestLayerTreeFrameSink;
 class TestTaskGraphRunner;
 
@@ -78,13 +78,13 @@
   void EndTestAfterDelayMs(int delay_milliseconds);
 
   void PostAddNoDamageAnimationToMainThread(
-      SingleKeyframeEffectAnimation* animation_to_receive_animation);
+      Animation* animation_to_receive_animation);
   void PostAddOpacityAnimationToMainThread(
-      SingleKeyframeEffectAnimation* animation_to_receive_animation);
+      Animation* animation_to_receive_animation);
   void PostAddOpacityAnimationToMainThreadInstantly(
-      SingleKeyframeEffectAnimation* animation_to_receive_animation);
+      Animation* animation_to_receive_animation);
   void PostAddOpacityAnimationToMainThreadDelayed(
-      SingleKeyframeEffectAnimation* animation_to_receive_animation);
+      Animation* animation_to_receive_animation);
   void PostSetLocalSurfaceIdAllocationToMainThread(
       const viz::LocalSurfaceIdAllocation& local_surface_id_allocation);
   void PostRequestNewLocalSurfaceIdToMainThread();
@@ -207,10 +207,10 @@
 
  private:
   virtual void DispatchAddNoDamageAnimation(
-      SingleKeyframeEffectAnimation* animation_to_receive_animation,
+      Animation* animation_to_receive_animation,
       double animation_duration);
   virtual void DispatchAddOpacityAnimation(
-      SingleKeyframeEffectAnimation* animation_to_receive_animation,
+      Animation* animation_to_receive_animation,
       double animation_duration);
   void DispatchSetLocalSurfaceIdAllocation(
       const viz::LocalSurfaceIdAllocation& local_surface_id_allocation);
diff --git a/cc/trees/draw_properties_unittest.cc b/cc/trees/draw_properties_unittest.cc
index d74ab14..69d3170d 100644
--- a/cc/trees/draw_properties_unittest.cc
+++ b/cc/trees/draw_properties_unittest.cc
@@ -12,10 +12,10 @@
 
 #include "base/memory/ptr_util.h"
 #include "base/stl_util.h"
+#include "cc/animation/animation.h"
 #include "cc/animation/animation_host.h"
 #include "cc/animation/animation_id_provider.h"
 #include "cc/animation/keyframed_animation_curve.h"
-#include "cc/animation/single_keyframe_effect_animation.h"
 #include "cc/animation/transform_operations.h"
 #include "cc/base/math_util.h"
 #include "cc/layers/content_layer_client.h"
@@ -5579,27 +5579,23 @@
   TransformOperations translation;
   translation.AppendTranslate(1.f, 2.f, 3.f);
 
-  scoped_refptr<SingleKeyframeEffectAnimation> grand_parent_animation =
-      SingleKeyframeEffectAnimation::Create(
-          AnimationIdProvider::NextAnimationId());
+  scoped_refptr<Animation> grand_parent_animation =
+      Animation::Create(AnimationIdProvider::NextAnimationId());
   timeline_impl()->AttachAnimation(grand_parent_animation);
   grand_parent_animation->AttachElement(grand_parent->element_id());
 
-  scoped_refptr<SingleKeyframeEffectAnimation> parent_animation =
-      SingleKeyframeEffectAnimation::Create(
-          AnimationIdProvider::NextAnimationId());
+  scoped_refptr<Animation> parent_animation =
+      Animation::Create(AnimationIdProvider::NextAnimationId());
   timeline_impl()->AttachAnimation(parent_animation);
   parent_animation->AttachElement(parent->element_id());
 
-  scoped_refptr<SingleKeyframeEffectAnimation> child_animation =
-      SingleKeyframeEffectAnimation::Create(
-          AnimationIdProvider::NextAnimationId());
+  scoped_refptr<Animation> child_animation =
+      Animation::Create(AnimationIdProvider::NextAnimationId());
   timeline_impl()->AttachAnimation(child_animation);
   child_animation->AttachElement(child->element_id());
 
-  scoped_refptr<SingleKeyframeEffectAnimation> grand_child_animation =
-      SingleKeyframeEffectAnimation::Create(
-          AnimationIdProvider::NextAnimationId());
+  scoped_refptr<Animation> grand_child_animation =
+      Animation::Create(AnimationIdProvider::NextAnimationId());
   timeline_impl()->AttachAnimation(grand_child_animation);
   grand_child_animation->AttachElement(grand_child->element_id());
 
@@ -6647,11 +6643,9 @@
       base::TimeDelta::FromSecondsD(1.0), operation, nullptr));
   std::unique_ptr<KeyframeModel> transform_animation(
       KeyframeModel::Create(std::move(curve), 3, 3, TargetProperty::TRANSFORM));
-  scoped_refptr<SingleKeyframeEffectAnimation> animation(
-      SingleKeyframeEffectAnimation::Create(1));
+  scoped_refptr<Animation> animation(Animation::Create(1));
   timeline()->AttachAnimation(animation);
-  animation->AttachElementForKeyframeEffect(parent->element_id(),
-                                            animation->keyframe_effect()->id());
+  animation->AttachElement(parent->element_id());
   animation->AddKeyframeModel(std::move(transform_animation));
   ImplOf(grandchild)->set_visible_layer_rect(gfx::Rect());
   parent->SetTransform(singular);
@@ -6681,8 +6675,7 @@
       base::TimeDelta::FromSecondsD(1.0), operation, nullptr));
   std::unique_ptr<KeyframeModel> transform_animation(
       KeyframeModel::Create(std::move(curve), 3, 3, TargetProperty::TRANSFORM));
-  scoped_refptr<SingleKeyframeEffectAnimation> animation(
-      SingleKeyframeEffectAnimation::Create(1));
+  scoped_refptr<Animation> animation(Animation::Create(1));
   timeline_impl()->AttachAnimation(animation);
   animation->AddKeyframeModel(std::move(transform_animation));
 
@@ -6740,8 +6733,8 @@
   // If the transform is singular, but there is an animation on it, we
   // should not skip the subtree.  Note that the animation has not started or
   // ticked, there is also code along that path.  This is not its test.
-  animation->AttachElementForKeyframeEffect(child->element_id(),
-                                            animation->keyframe_effect()->id());
+  animation->AttachElement(child->element_id());
+
   SetTransform(child, singular);
   grand_child->set_visible_layer_rect(gfx::Rect(1, 1));
   child->set_visible_layer_rect(gfx::Rect(1, 1));
@@ -6794,12 +6787,10 @@
       FloatKeyframe::Create(base::TimeDelta::FromSecondsD(1.0), 0.3f, nullptr));
   std::unique_ptr<KeyframeModel> keyframe_model(
       KeyframeModel::Create(std::move(curve), 3, 3, TargetProperty::OPACITY));
-  scoped_refptr<SingleKeyframeEffectAnimation> animation(
-      SingleKeyframeEffectAnimation::Create(1));
+  scoped_refptr<Animation> animation(Animation::Create(1));
   timeline()->AttachAnimation(animation);
   animation->AddKeyframeModel(std::move(keyframe_model));
-  animation->AttachElementForKeyframeEffect(root->element_id(),
-                                            animation->keyframe_effect()->id());
+  animation->AttachElement(root->element_id());
   // Repeat the calculation invocation.
   PendingImplOf(grandchild)->set_visible_layer_rect(gfx::Rect());
   Commit();
@@ -7592,9 +7583,8 @@
   animated->SetBounds(gfx::Size(20, 20));
   animated->SetOpacity(0.f);
 
-  scoped_refptr<SingleKeyframeEffectAnimation> animation =
-      SingleKeyframeEffectAnimation::Create(
-          AnimationIdProvider::NextAnimationId());
+  scoped_refptr<Animation> animation =
+      Animation::Create(AnimationIdProvider::NextAnimationId());
   timeline()->AttachAnimation(animation);
 
   animation->AttachElement(animated->element_id());
@@ -7641,9 +7631,8 @@
   root->SetForceRenderSurfaceForTesting(true);
   animated->SetBounds(gfx::Size(20, 20));
 
-  scoped_refptr<SingleKeyframeEffectAnimation> animation =
-      SingleKeyframeEffectAnimation::Create(
-          AnimationIdProvider::NextAnimationId());
+  scoped_refptr<Animation> animation =
+      Animation::Create(AnimationIdProvider::NextAnimationId());
   timeline()->AttachAnimation(animation);
   animation->AttachElement(animated->element_id());
 
diff --git a/cc/trees/layer_tree_host_unittest_animation.cc b/cc/trees/layer_tree_host_unittest_animation.cc
index 8d49e94..4541379 100644
--- a/cc/trees/layer_tree_host_unittest_animation.cc
+++ b/cc/trees/layer_tree_host_unittest_animation.cc
@@ -8,6 +8,7 @@
 #include <climits>
 
 #include "base/bind.h"
+#include "cc/animation/animation.h"
 #include "cc/animation/animation_curve.h"
 #include "cc/animation/animation_host.h"
 #include "cc/animation/animation_id_provider.h"
@@ -17,7 +18,6 @@
 #include "cc/animation/scroll_offset_animation_curve.h"
 #include "cc/animation/scroll_offset_animation_curve_factory.h"
 #include "cc/animation/scroll_offset_animations.h"
-#include "cc/animation/single_keyframe_effect_animation.h"
 #include "cc/animation/timing_function.h"
 #include "cc/animation/transform_operations.h"
 #include "cc/base/completion_event.h"
@@ -43,9 +43,8 @@
         animation_id_(AnimationIdProvider::NextAnimationId()),
         animation_child_id_(AnimationIdProvider::NextAnimationId()) {
     timeline_ = AnimationTimeline::Create(timeline_id_);
-    animation_ = SingleKeyframeEffectAnimation::Create(animation_id_);
-    animation_child_ =
-        SingleKeyframeEffectAnimation::Create(animation_child_id_);
+    animation_ = Animation::Create(animation_id_);
+    animation_child_ = Animation::Create(animation_child_id_);
 
     animation_->set_animation_delegate(this);
   }
@@ -61,11 +60,10 @@
     AnimationHost* animation_host_impl = GetImplAnimationHost(&host_impl);
     timeline_impl_ = animation_host_impl->GetTimelineById(timeline_id_);
     EXPECT_TRUE(timeline_impl_);
-    animation_impl_ = static_cast<SingleKeyframeEffectAnimation*>(
-        timeline_impl_->GetAnimationById(animation_id_));
+    animation_impl_ = timeline_impl_->GetAnimationById(animation_id_);
     EXPECT_TRUE(animation_impl_);
-    animation_child_impl_ = static_cast<SingleKeyframeEffectAnimation*>(
-        timeline_impl_->GetAnimationById(animation_child_id_));
+    animation_child_impl_ =
+        timeline_impl_->GetAnimationById(animation_child_id_);
     EXPECT_TRUE(animation_child_impl_);
   }
 
@@ -76,12 +74,12 @@
 
  protected:
   scoped_refptr<AnimationTimeline> timeline_;
-  scoped_refptr<SingleKeyframeEffectAnimation> animation_;
-  scoped_refptr<SingleKeyframeEffectAnimation> animation_child_;
+  scoped_refptr<Animation> animation_;
+  scoped_refptr<Animation> animation_child_;
 
   scoped_refptr<AnimationTimeline> timeline_impl_;
-  scoped_refptr<SingleKeyframeEffectAnimation> animation_impl_;
-  scoped_refptr<SingleKeyframeEffectAnimation> animation_child_impl_;
+  scoped_refptr<Animation> animation_impl_;
+  scoped_refptr<Animation> animation_child_impl_;
 
   const int timeline_id_;
   const int animation_id_;
@@ -371,9 +369,8 @@
 
     scoped_refptr<AnimationTimeline> timeline_impl =
         GetImplAnimationHost(host_impl)->GetTimelineById(timeline_id_);
-    scoped_refptr<SingleKeyframeEffectAnimation> animation_child_impl =
-        static_cast<SingleKeyframeEffectAnimation*>(
-            timeline_impl->GetAnimationById(animation_child_id_));
+    scoped_refptr<Animation> animation_child_impl =
+        timeline_impl->GetAnimationById(animation_child_id_);
 
     KeyframeModel* keyframe_model =
         animation_child_impl->GetKeyframeModel(TargetProperty::OPACITY);
@@ -437,9 +434,8 @@
                             bool has_unfinished_animation) override {
     scoped_refptr<AnimationTimeline> timeline_impl =
         GetImplAnimationHost(impl_host)->GetTimelineById(timeline_id_);
-    scoped_refptr<SingleKeyframeEffectAnimation> animation_child_impl =
-        static_cast<SingleKeyframeEffectAnimation*>(
-            timeline_impl->GetAnimationById(animation_child_id_));
+    scoped_refptr<Animation> animation_child_impl =
+        timeline_impl->GetAnimationById(animation_child_id_);
 
     KeyframeModel* keyframe_model =
         animation_child_impl->GetKeyframeModel(TargetProperty::OPACITY);
@@ -514,9 +510,8 @@
   void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
     scoped_refptr<AnimationTimeline> timeline_impl =
         GetImplAnimationHost(host_impl)->GetTimelineById(timeline_id_);
-    scoped_refptr<SingleKeyframeEffectAnimation> animation_impl =
-        static_cast<SingleKeyframeEffectAnimation*>(
-            timeline_impl->GetAnimationById(animation_id_));
+    scoped_refptr<Animation> animation_impl =
+        timeline_impl->GetAnimationById(animation_id_);
 
     KeyframeModel* keyframe_model_impl =
         animation_impl->GetKeyframeModel(TargetProperty::OPACITY);
@@ -1158,9 +1153,8 @@
 
     scoped_refptr<AnimationTimeline> timeline_impl =
         GetImplAnimationHost(host_impl)->GetTimelineById(timeline_id_);
-    scoped_refptr<SingleKeyframeEffectAnimation> animation_impl =
-        static_cast<SingleKeyframeEffectAnimation*>(
-            timeline_impl->GetAnimationById(animation_child_id_));
+    scoped_refptr<Animation> animation_impl =
+        timeline_impl->GetAnimationById(animation_child_id_);
 
     LayerImpl* scroll_layer_impl =
         host_impl->active_tree()->LayerById(scroll_layer_->id());
@@ -1360,15 +1354,13 @@
                             bool has_unfinished_animation) override {
     scoped_refptr<AnimationTimeline> timeline_impl =
         GetImplAnimationHost(host_impl)->GetTimelineById(timeline_id_);
-    scoped_refptr<SingleKeyframeEffectAnimation> animation_impl =
-        static_cast<SingleKeyframeEffectAnimation*>(
-            timeline_impl->GetAnimationById(animation_id_));
-    scoped_refptr<SingleKeyframeEffectAnimation> animation_child_impl =
-        static_cast<SingleKeyframeEffectAnimation*>(
-            timeline_impl->GetAnimationById(animation_child_id_));
+    scoped_refptr<Animation> animation_impl =
+        timeline_impl->GetAnimationById(animation_id_);
+    scoped_refptr<Animation> animation_child_impl =
+        timeline_impl->GetAnimationById(animation_child_id_);
 
     // wait for tree activation.
-    if (!animation_impl->keyframe_effect()->element_animations())
+    if (!animation_impl->element_animations())
       return;
 
     KeyframeModel* root_keyframe_model =
@@ -1445,9 +1437,8 @@
 
     scoped_refptr<AnimationTimeline> timeline_impl =
         GetImplAnimationHost(host_impl)->GetTimelineById(timeline_id_);
-    scoped_refptr<SingleKeyframeEffectAnimation> animation_impl =
-        static_cast<SingleKeyframeEffectAnimation*>(
-            timeline_impl->GetAnimationById(animation_id_));
+    scoped_refptr<Animation> animation_impl =
+        timeline_impl->GetAnimationById(animation_id_);
 
     LayerImpl* child = sync_tree->LayerById(layer_->id());
     KeyframeModel* keyframe_model =
@@ -1492,7 +1483,7 @@
     animation_host()->AddAnimationTimeline(timeline_.get());
     timeline_->AttachAnimation(animation_.get());
     animation_->AttachElement(layer_->element_id());
-    DCHECK(animation_->keyframe_effect()->element_animations());
+    DCHECK(animation_->element_animations());
 
     AddOpacityTransitionToAnimation(animation_.get(), 10000.0, 0.1f, 0.9f,
                                     true);
@@ -1503,34 +1494,28 @@
   void DidCommit() override {
     switch (layer_tree_host()->SourceFrameNumber()) {
       case 0:
-        EXPECT_TRUE(animation_->keyframe_effect()
-                        ->element_animations()
-                        ->has_element_in_active_list());
-        EXPECT_FALSE(animation_->keyframe_effect()
-                         ->element_animations()
-                         ->has_element_in_pending_list());
+        EXPECT_TRUE(
+            animation_->element_animations()->has_element_in_active_list());
+        EXPECT_FALSE(
+            animation_->element_animations()->has_element_in_pending_list());
         EXPECT_TRUE(animation_host()->NeedsTickAnimations());
         break;
       case 1:
         layer_->RemoveFromParent();
-        EXPECT_FALSE(animation_->keyframe_effect()
-                         ->element_animations()
-                         ->has_element_in_active_list());
-        EXPECT_FALSE(animation_->keyframe_effect()
-                         ->element_animations()
-                         ->has_element_in_pending_list());
+        EXPECT_FALSE(
+            animation_->element_animations()->has_element_in_active_list());
+        EXPECT_FALSE(
+            animation_->element_animations()->has_element_in_pending_list());
         // Animations still need one more tick to deliver finished event.
         EXPECT_TRUE(animation_host()->NeedsTickAnimations());
         break;
       case 2:
         EXPECT_FALSE(animation_host()->NeedsTickAnimations());
         layer_tree_host()->root_layer()->AddChild(layer_);
-        EXPECT_TRUE(animation_->keyframe_effect()
-                        ->element_animations()
-                        ->has_element_in_active_list());
-        EXPECT_FALSE(animation_->keyframe_effect()
-                         ->element_animations()
-                         ->has_element_in_pending_list());
+        EXPECT_TRUE(
+            animation_->element_animations()->has_element_in_active_list());
+        EXPECT_FALSE(
+            animation_->element_animations()->has_element_in_pending_list());
         EXPECT_TRUE(animation_host()->NeedsTickAnimations());
         break;
     }
@@ -1539,29 +1524,25 @@
   void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
     scoped_refptr<AnimationTimeline> timeline_impl =
         GetImplAnimationHost(host_impl)->GetTimelineById(timeline_id_);
-    scoped_refptr<SingleKeyframeEffectAnimation> animation_impl =
-        static_cast<SingleKeyframeEffectAnimation*>(
-            timeline_impl->GetAnimationById(animation_id_));
+    scoped_refptr<Animation> animation_impl =
+        timeline_impl->GetAnimationById(animation_id_);
 
     switch (host_impl->active_tree()->source_frame_number()) {
       case 0:
-        EXPECT_TRUE(animation_impl->keyframe_effect()
-                        ->element_animations()
-                        ->has_element_in_active_list());
+        EXPECT_TRUE(
+            animation_impl->element_animations()->has_element_in_active_list());
         EXPECT_TRUE(GetImplAnimationHost(host_impl)->NeedsTickAnimations());
         break;
       case 1:
-        EXPECT_FALSE(animation_impl->keyframe_effect()
-                         ->element_animations()
-                         ->has_element_in_active_list());
+        EXPECT_FALSE(
+            animation_impl->element_animations()->has_element_in_active_list());
         // Having updated state on the host_impl during the commit, we no longer
         // need to tick animations.
         EXPECT_FALSE(GetImplAnimationHost(host_impl)->NeedsTickAnimations());
         break;
       case 2:
-        EXPECT_TRUE(animation_impl->keyframe_effect()
-                        ->element_animations()
-                        ->has_element_in_active_list());
+        EXPECT_TRUE(
+            animation_impl->element_animations()->has_element_in_active_list());
         EXPECT_TRUE(GetImplAnimationHost(host_impl)->NeedsTickAnimations());
         EndTest();
         break;
@@ -2257,7 +2238,7 @@
 
 // Check that transform sync happens correctly at commit when we remove and add
 // a different animation animation to an element.
-class LayerTreeHostAnimationTestChangeSingleKeyframeEffectAnimation
+class LayerTreeHostAnimationTestChangeAnimation
     : public LayerTreeHostAnimationTest {
  public:
   void SetupTree() override {
@@ -2320,8 +2301,7 @@
   scoped_refptr<Layer> layer_;
 };
 
-SINGLE_AND_MULTI_THREAD_TEST_F(
-    LayerTreeHostAnimationTestChangeSingleKeyframeEffectAnimation);
+SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestChangeAnimation);
 
 // Check that SetTransformIsPotentiallyAnimatingChanged is called
 // if we destroy ElementAnimations.
@@ -2405,8 +2385,7 @@
 MULTI_THREAD_TEST_F(
     LayerTreeHostAnimationTestSetPotentiallyAnimatingOnLacDestruction);
 
-// Check that we invalidate property trees on
-// SingleKeyframeEffectAnimation::SetNeedsCommit.
+// Check that we invalidate property trees on Animation::SetNeedsCommit.
 class LayerTreeHostAnimationTestRebuildPropertyTreesOnAnimationSetNeedsCommit
     : public LayerTreeHostAnimationTest {
  public:
diff --git a/third_party/blink/renderer/platform/animation/compositor_animation.cc b/third_party/blink/renderer/platform/animation/compositor_animation.cc
index 7466dde..1c0230f3 100644
--- a/third_party/blink/renderer/platform/animation/compositor_animation.cc
+++ b/third_party/blink/renderer/platform/animation/compositor_animation.cc
@@ -14,8 +14,7 @@
 
 std::unique_ptr<CompositorAnimation> CompositorAnimation::Create() {
   return std::make_unique<CompositorAnimation>(
-      cc::SingleKeyframeEffectAnimation::Create(
-          cc::AnimationIdProvider::NextAnimationId()));
+      cc::Animation::Create(cc::AnimationIdProvider::NextAnimationId()));
 }
 
 std::unique_ptr<CompositorAnimation>
@@ -32,8 +31,7 @@
       std::move(effect_timings)));
 }
 
-CompositorAnimation::CompositorAnimation(
-    scoped_refptr<cc::SingleKeyframeEffectAnimation> animation)
+CompositorAnimation::CompositorAnimation(scoped_refptr<cc::Animation> animation)
     : animation_(animation), delegate_() {}
 
 CompositorAnimation::~CompositorAnimation() {
@@ -44,7 +42,7 @@
     animation_->animation_timeline()->DetachAnimation(animation_);
 }
 
-cc::SingleKeyframeEffectAnimation* CompositorAnimation::CcAnimation() const {
+cc::Animation* CompositorAnimation::CcAnimation() const {
   return animation_.get();
 }
 
diff --git a/third_party/blink/renderer/platform/animation/compositor_animation.h b/third_party/blink/renderer/platform/animation/compositor_animation.h
index 15d679af..ed663c3 100644
--- a/third_party/blink/renderer/platform/animation/compositor_animation.h
+++ b/third_party/blink/renderer/platform/animation/compositor_animation.h
@@ -10,9 +10,9 @@
 #include "base/macros.h"
 #include "base/memory/scoped_refptr.h"
 #include "base/optional.h"
+#include "cc/animation/animation.h"
 #include "cc/animation/animation_delegate.h"
 #include "cc/animation/scroll_timeline.h"
-#include "cc/animation/single_keyframe_effect_animation.h"
 #include "cc/animation/worklet_animation.h"
 #include "third_party/blink/renderer/platform/graphics/compositor_element_id.h"
 #include "third_party/blink/renderer/platform/platform_export.h"
@@ -41,11 +41,10 @@
       std::unique_ptr<cc::AnimationOptions>,
       std::unique_ptr<cc::AnimationEffectTimings> effect_timings);
 
-  explicit CompositorAnimation(
-      scoped_refptr<cc::SingleKeyframeEffectAnimation>);
+  explicit CompositorAnimation(scoped_refptr<cc::Animation>);
   ~CompositorAnimation() override;
 
-  cc::SingleKeyframeEffectAnimation* CcAnimation() const;
+  cc::Animation* CcAnimation() const;
 
   // An animation delegate is notified when animations are started and stopped.
   // The CompositorAnimation does not take ownership of the delegate, and
@@ -85,7 +84,7 @@
   void NotifyLocalTimeUpdated(
       base::Optional<base::TimeDelta> local_time) override;
 
-  scoped_refptr<cc::SingleKeyframeEffectAnimation> animation_;
+  scoped_refptr<cc::Animation> animation_;
   CompositorAnimationDelegate* delegate_;
 
   DISALLOW_COPY_AND_ASSIGN(CompositorAnimation);
diff --git a/third_party/blink/renderer/platform/animation/compositor_animation_test.cc b/third_party/blink/renderer/platform/animation/compositor_animation_test.cc
index c40fb382..25a9e0b3 100644
--- a/third_party/blink/renderer/platform/animation/compositor_animation_test.cc
+++ b/third_party/blink/renderer/platform/animation/compositor_animation_test.cc
@@ -60,7 +60,7 @@
   std::unique_ptr<CompositorAnimationTestClient> client(
       new CompositorAnimationTestClient);
   CompositorAnimation* animation = client->GetCompositorAnimation();
-  cc::SingleKeyframeEffectAnimation* cc_animation = animation->CcAnimation();
+  cc::Animation* cc_animation = animation->CcAnimation();
   timeline->AnimationAttached(*client);
   int timeline_id = cc_animation->animation_timeline()->id();
 
@@ -93,8 +93,7 @@
   std::unique_ptr<CompositorAnimationTestClient> client(
       new CompositorAnimationTestClient);
   CompositorAnimation* animation = client->GetCompositorAnimation();
-  scoped_refptr<cc::SingleKeyframeEffectAnimation> cc_animation =
-      animation->CcAnimation();
+  scoped_refptr<cc::Animation> cc_animation = animation->CcAnimation();
   timeline->AnimationAttached(*client);
   int timeline_id = cc_animation->animation_timeline()->id();
 
@@ -129,8 +128,7 @@
 
   scoped_refptr<cc::AnimationTimeline> cc_timeline =
       timeline->GetAnimationTimeline();
-  scoped_refptr<cc::SingleKeyframeEffectAnimation> cc_animation =
-      client->animation_->CcAnimation();
+  scoped_refptr<cc::Animation> cc_animation = client->animation_->CcAnimation();
   EXPECT_FALSE(cc_animation->animation_timeline());
 
   timeline->AnimationAttached(*client);
diff --git a/ui/compositor/layer_animator.cc b/ui/compositor/layer_animator.cc
index e32ef30..9f2eb41 100644
--- a/ui/compositor/layer_animator.cc
+++ b/ui/compositor/layer_animator.cc
@@ -11,11 +11,11 @@
 #include "base/logging.h"
 #include "base/stl_util.h"
 #include "base/trace_event/trace_event.h"
+#include "cc/animation/animation.h"
 #include "cc/animation/animation_host.h"
 #include "cc/animation/animation_id_provider.h"
 #include "cc/animation/animation_timeline.h"
 #include "cc/animation/element_animations.h"
-#include "cc/animation/single_keyframe_effect_animation.h"
 #include "components/viz/common/frame_sinks/begin_frame_args.h"
 #include "ui/compositor/compositor.h"
 #include "ui/compositor/layer.h"
@@ -56,8 +56,8 @@
       disable_timer_for_test_(false),
       adding_animations_(false),
       animation_metrics_reporter_(nullptr) {
-  animation_ = cc::SingleKeyframeEffectAnimation::Create(
-      cc::AnimationIdProvider::NextAnimationId());
+  animation_ =
+      cc::Animation::Create(cc::AnimationIdProvider::NextAnimationId());
 }
 
 LayerAnimator::~LayerAnimator() {
@@ -203,8 +203,7 @@
   animation_->RemoveKeyframeModel(keyframe_model_id);
 }
 
-cc::SingleKeyframeEffectAnimation* LayerAnimator::GetAnimationForTesting()
-    const {
+cc::Animation* LayerAnimator::GetAnimationForTesting() const {
   return animation_.get();
 }
 
diff --git a/ui/compositor/layer_animator.h b/ui/compositor/layer_animator.h
index c400361..c9a64b24 100644
--- a/ui/compositor/layer_animator.h
+++ b/ui/compositor/layer_animator.h
@@ -25,7 +25,6 @@
 class Animation;
 class AnimationTimeline;
 class Layer;
-class SingleKeyframeEffectAnimation;
 }
 
 namespace gfx {
@@ -126,7 +125,7 @@
   // Detach Animation from Layer and AnimationTimeline
   void DetachLayerAndTimeline(Compositor* compositor);
 
-  cc::SingleKeyframeEffectAnimation* GetAnimationForTesting() const;
+  cc::Animation* GetAnimationForTesting() const;
 
   // Sets the animation preemption strategy. This determines the behaviour if
   // a property is set during an animation. The default is
@@ -398,7 +397,7 @@
   LayerAnimationDelegate* delegate_;
 
   // Plays CC animations.
-  scoped_refptr<cc::SingleKeyframeEffectAnimation> animation_;
+  scoped_refptr<cc::Animation> animation_;
 
   // The currently running animations.
   RunningAnimations running_animations_;
diff --git a/ui/compositor/layer_owner_unittest.cc b/ui/compositor/layer_owner_unittest.cc
index 30a9fb4..8f0a935 100644
--- a/ui/compositor/layer_owner_unittest.cc
+++ b/ui/compositor/layer_owner_unittest.cc
@@ -8,7 +8,7 @@
 
 #include "base/macros.h"
 #include "base/test/null_task_runner.h"
-#include "cc/animation/single_keyframe_effect_animation.h"
+#include "cc/animation/animation.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/compositor/compositor.h"
 #include "ui/compositor/layer.h"
@@ -184,7 +184,7 @@
   layer->SetOpacity(0.5f);
   root_layer->Add(layer);
 
-  scoped_refptr<cc::SingleKeyframeEffectAnimation> animation =
+  scoped_refptr<cc::Animation> animation =
       layer->GetAnimator()->GetAnimationForTesting();
   EXPECT_TRUE(animation);
   EXPECT_TRUE(animation->animation_timeline());
@@ -207,7 +207,7 @@
 
   layer->SetOpacity(0.5f);
 
-  scoped_refptr<cc::SingleKeyframeEffectAnimation> animation =
+  scoped_refptr<cc::Animation> animation =
       layer->GetAnimator()->GetAnimationForTesting();
   EXPECT_TRUE(animation);
   EXPECT_TRUE(animation->animation_timeline());
diff --git a/ui/compositor/layer_unittest.cc b/ui/compositor/layer_unittest.cc
index f0ab12f..39cfd99 100644
--- a/ui/compositor/layer_unittest.cc
+++ b/ui/compositor/layer_unittest.cc
@@ -27,10 +27,10 @@
 #include "base/time/time.h"
 #include "base/trace_event/trace_event.h"
 #include "build/build_config.h"
+#include "cc/animation/animation.h"
 #include "cc/animation/animation_events.h"
 #include "cc/animation/animation_host.h"
 #include "cc/animation/keyframe_effect.h"
-#include "cc/animation/single_keyframe_effect_animation.h"
 #include "cc/layers/layer.h"
 #include "cc/layers/mirror_layer.h"
 #include "cc/test/pixel_comparator.h"