xref: /aosp_15_r20/external/skia/modules/skottie/src/SkottieTest.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1*c8dee2aaSAndroid Build Coastguard Worker /*
2*c8dee2aaSAndroid Build Coastguard Worker  * Copyright 2018 Google Inc.
3*c8dee2aaSAndroid Build Coastguard Worker  *
4*c8dee2aaSAndroid Build Coastguard Worker  * Use of this source code is governed by a BSD-style license that can be
5*c8dee2aaSAndroid Build Coastguard Worker  * found in the LICENSE file.
6*c8dee2aaSAndroid Build Coastguard Worker  */
7*c8dee2aaSAndroid Build Coastguard Worker 
8*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkStream.h"
9*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkSurface.h"
10*c8dee2aaSAndroid Build Coastguard Worker #include "modules/skottie/include/Skottie.h"
11*c8dee2aaSAndroid Build Coastguard Worker #include "tests/Test.h"
12*c8dee2aaSAndroid Build Coastguard Worker 
13*c8dee2aaSAndroid Build Coastguard Worker #include <cmath>
14*c8dee2aaSAndroid Build Coastguard Worker #include <string>
15*c8dee2aaSAndroid Build Coastguard Worker #include <tuple>
16*c8dee2aaSAndroid Build Coastguard Worker #include <vector>
17*c8dee2aaSAndroid Build Coastguard Worker 
18*c8dee2aaSAndroid Build Coastguard Worker using namespace skottie;
19*c8dee2aaSAndroid Build Coastguard Worker 
DEF_TEST(Skottie_OssFuzz8956,reporter)20*c8dee2aaSAndroid Build Coastguard Worker DEF_TEST(Skottie_OssFuzz8956, reporter) {
21*c8dee2aaSAndroid Build Coastguard Worker     static constexpr char json[] =
22*c8dee2aaSAndroid Build Coastguard Worker         "{\"v\":\" \",\"fr\":3,\"w\":4,\"h\":3,\"layers\":[{\"ty\": 1, \"sw\": 10, \"sh\": 10,"
23*c8dee2aaSAndroid Build Coastguard Worker             " \"sc\":\"#ffffff\", \"ks\":{\"o\":{\"a\": true, \"k\":"
24*c8dee2aaSAndroid Build Coastguard Worker             " [{\"t\": 0, \"s\": 0, \"e\": 1, \"i\": {\"x\":[]}}]}}}]}";
25*c8dee2aaSAndroid Build Coastguard Worker 
26*c8dee2aaSAndroid Build Coastguard Worker     SkMemoryStream stream(json, strlen(json));
27*c8dee2aaSAndroid Build Coastguard Worker 
28*c8dee2aaSAndroid Build Coastguard Worker     // Passes if parsing doesn't crash.
29*c8dee2aaSAndroid Build Coastguard Worker     auto animation = Animation::Make(&stream);
30*c8dee2aaSAndroid Build Coastguard Worker }
31*c8dee2aaSAndroid Build Coastguard Worker 
DEF_TEST(Skottie_Annotations,reporter)32*c8dee2aaSAndroid Build Coastguard Worker DEF_TEST(Skottie_Annotations, reporter) {
33*c8dee2aaSAndroid Build Coastguard Worker     static constexpr char json[] = R"({
34*c8dee2aaSAndroid Build Coastguard Worker                                      "v": "5.2.1",
35*c8dee2aaSAndroid Build Coastguard Worker                                      "w": 100,
36*c8dee2aaSAndroid Build Coastguard Worker                                      "h": 100,
37*c8dee2aaSAndroid Build Coastguard Worker                                      "fr": 10,
38*c8dee2aaSAndroid Build Coastguard Worker                                      "ip": 0,
39*c8dee2aaSAndroid Build Coastguard Worker                                      "op": 100,
40*c8dee2aaSAndroid Build Coastguard Worker                                      "layers": [
41*c8dee2aaSAndroid Build Coastguard Worker                                        {
42*c8dee2aaSAndroid Build Coastguard Worker                                          "ty": 1,
43*c8dee2aaSAndroid Build Coastguard Worker                                          "ind": 0,
44*c8dee2aaSAndroid Build Coastguard Worker                                          "ip": 0,
45*c8dee2aaSAndroid Build Coastguard Worker                                          "op": 1,
46*c8dee2aaSAndroid Build Coastguard Worker                                          "ks": {
47*c8dee2aaSAndroid Build Coastguard Worker                                            "o": { "a": 0, "k": 50 }
48*c8dee2aaSAndroid Build Coastguard Worker                                          },
49*c8dee2aaSAndroid Build Coastguard Worker                                          "sw": 100,
50*c8dee2aaSAndroid Build Coastguard Worker                                          "sh": 100,
51*c8dee2aaSAndroid Build Coastguard Worker                                          "sc": "#ffffff"
52*c8dee2aaSAndroid Build Coastguard Worker                                        }
53*c8dee2aaSAndroid Build Coastguard Worker                                      ],
54*c8dee2aaSAndroid Build Coastguard Worker                                      "markers": [
55*c8dee2aaSAndroid Build Coastguard Worker                                        {
56*c8dee2aaSAndroid Build Coastguard Worker                                            "cm": "marker_1",
57*c8dee2aaSAndroid Build Coastguard Worker                                            "dr": 25,
58*c8dee2aaSAndroid Build Coastguard Worker                                            "tm": 25
59*c8dee2aaSAndroid Build Coastguard Worker                                        },
60*c8dee2aaSAndroid Build Coastguard Worker                                        {
61*c8dee2aaSAndroid Build Coastguard Worker                                            "cm": "marker_2",
62*c8dee2aaSAndroid Build Coastguard Worker                                            "dr": 0,
63*c8dee2aaSAndroid Build Coastguard Worker                                            "tm": 75
64*c8dee2aaSAndroid Build Coastguard Worker                                        }
65*c8dee2aaSAndroid Build Coastguard Worker                                      ]
66*c8dee2aaSAndroid Build Coastguard Worker                                    })";
67*c8dee2aaSAndroid Build Coastguard Worker 
68*c8dee2aaSAndroid Build Coastguard Worker     class TestMarkerObserver final : public MarkerObserver {
69*c8dee2aaSAndroid Build Coastguard Worker     public:
70*c8dee2aaSAndroid Build Coastguard Worker         void onMarker(const char name[], float t0, float t1) override {
71*c8dee2aaSAndroid Build Coastguard Worker             fMarkers.push_back(std::make_tuple(name, t0, t1));
72*c8dee2aaSAndroid Build Coastguard Worker         }
73*c8dee2aaSAndroid Build Coastguard Worker 
74*c8dee2aaSAndroid Build Coastguard Worker         std::vector<std::tuple<std::string, float, float>> fMarkers;
75*c8dee2aaSAndroid Build Coastguard Worker     };
76*c8dee2aaSAndroid Build Coastguard Worker 
77*c8dee2aaSAndroid Build Coastguard Worker     SkMemoryStream stream(json, strlen(json));
78*c8dee2aaSAndroid Build Coastguard Worker     auto observer = sk_make_sp<TestMarkerObserver>();
79*c8dee2aaSAndroid Build Coastguard Worker 
80*c8dee2aaSAndroid Build Coastguard Worker     auto animation = skottie::Animation::Builder()
81*c8dee2aaSAndroid Build Coastguard Worker             .setMarkerObserver(observer)
82*c8dee2aaSAndroid Build Coastguard Worker             .make(&stream);
83*c8dee2aaSAndroid Build Coastguard Worker 
84*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, animation);
85*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, animation->duration() == 10);
86*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, animation->inPoint()  == 0.0);
87*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, animation->outPoint() == 100.0);
88*c8dee2aaSAndroid Build Coastguard Worker 
89*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, observer->fMarkers.size() == 2ul);
90*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, std::get<0>(observer->fMarkers[0]) == "marker_1");
91*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, std::get<1>(observer->fMarkers[0]) == 0.25f);
92*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, std::get<2>(observer->fMarkers[0]) == 0.50f);
93*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, std::get<0>(observer->fMarkers[1]) == "marker_2");
94*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, std::get<1>(observer->fMarkers[1]) == 0.75f);
95*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, std::get<2>(observer->fMarkers[1]) == 0.75f);
96*c8dee2aaSAndroid Build Coastguard Worker }
97*c8dee2aaSAndroid Build Coastguard Worker 
DEF_TEST(Skottie_Image_Loading,reporter)98*c8dee2aaSAndroid Build Coastguard Worker DEF_TEST(Skottie_Image_Loading, reporter) {
99*c8dee2aaSAndroid Build Coastguard Worker     class TestResourceProvider final : public skresources::ResourceProvider {
100*c8dee2aaSAndroid Build Coastguard Worker     public:
101*c8dee2aaSAndroid Build Coastguard Worker         TestResourceProvider(sk_sp<skresources::ImageAsset> single_asset,
102*c8dee2aaSAndroid Build Coastguard Worker                              sk_sp<skresources::ImageAsset>  multi_asset)
103*c8dee2aaSAndroid Build Coastguard Worker             : fSingleFrameAsset(std::move(single_asset))
104*c8dee2aaSAndroid Build Coastguard Worker             , fMultiFrameAsset (std::move( multi_asset)) {}
105*c8dee2aaSAndroid Build Coastguard Worker 
106*c8dee2aaSAndroid Build Coastguard Worker     private:
107*c8dee2aaSAndroid Build Coastguard Worker         sk_sp<ImageAsset> loadImageAsset(const char path[],
108*c8dee2aaSAndroid Build Coastguard Worker                                          const char name[],
109*c8dee2aaSAndroid Build Coastguard Worker                                          const char id[]) const override {
110*c8dee2aaSAndroid Build Coastguard Worker             return strcmp(id, "single_frame")
111*c8dee2aaSAndroid Build Coastguard Worker                     ? fMultiFrameAsset
112*c8dee2aaSAndroid Build Coastguard Worker                     : fSingleFrameAsset;
113*c8dee2aaSAndroid Build Coastguard Worker         }
114*c8dee2aaSAndroid Build Coastguard Worker 
115*c8dee2aaSAndroid Build Coastguard Worker         const sk_sp<skresources::ImageAsset> fSingleFrameAsset,
116*c8dee2aaSAndroid Build Coastguard Worker                                              fMultiFrameAsset;
117*c8dee2aaSAndroid Build Coastguard Worker     };
118*c8dee2aaSAndroid Build Coastguard Worker 
119*c8dee2aaSAndroid Build Coastguard Worker     auto make_animation = [&reporter] (sk_sp<skresources::ImageAsset> single_asset,
120*c8dee2aaSAndroid Build Coastguard Worker                                        sk_sp<skresources::ImageAsset>  multi_asset,
121*c8dee2aaSAndroid Build Coastguard Worker                                        bool deferred_image_loading) {
122*c8dee2aaSAndroid Build Coastguard Worker         static constexpr char json[] = R"({
123*c8dee2aaSAndroid Build Coastguard Worker                                          "v": "5.2.1",
124*c8dee2aaSAndroid Build Coastguard Worker                                          "w": 100,
125*c8dee2aaSAndroid Build Coastguard Worker                                          "h": 100,
126*c8dee2aaSAndroid Build Coastguard Worker                                          "fr": 10,
127*c8dee2aaSAndroid Build Coastguard Worker                                          "ip": 0,
128*c8dee2aaSAndroid Build Coastguard Worker                                          "op": 100,
129*c8dee2aaSAndroid Build Coastguard Worker                                          "assets": [
130*c8dee2aaSAndroid Build Coastguard Worker                                            {
131*c8dee2aaSAndroid Build Coastguard Worker                                              "id": "single_frame",
132*c8dee2aaSAndroid Build Coastguard Worker                                              "p" : "single_frame.png",
133*c8dee2aaSAndroid Build Coastguard Worker                                              "u" : "images/",
134*c8dee2aaSAndroid Build Coastguard Worker                                              "w" : 500,
135*c8dee2aaSAndroid Build Coastguard Worker                                              "h" : 500
136*c8dee2aaSAndroid Build Coastguard Worker                                            },
137*c8dee2aaSAndroid Build Coastguard Worker                                            {
138*c8dee2aaSAndroid Build Coastguard Worker                                              "id": "multi_frame",
139*c8dee2aaSAndroid Build Coastguard Worker                                              "p" : "multi_frame.png",
140*c8dee2aaSAndroid Build Coastguard Worker                                              "u" : "images/",
141*c8dee2aaSAndroid Build Coastguard Worker                                              "w" : 500,
142*c8dee2aaSAndroid Build Coastguard Worker                                              "h" : 500
143*c8dee2aaSAndroid Build Coastguard Worker                                            }
144*c8dee2aaSAndroid Build Coastguard Worker                                          ],
145*c8dee2aaSAndroid Build Coastguard Worker                                          "layers": [
146*c8dee2aaSAndroid Build Coastguard Worker                                            {
147*c8dee2aaSAndroid Build Coastguard Worker                                              "ty": 2,
148*c8dee2aaSAndroid Build Coastguard Worker                                              "refId": "single_frame",
149*c8dee2aaSAndroid Build Coastguard Worker                                              "ind": 0,
150*c8dee2aaSAndroid Build Coastguard Worker                                              "ip": 0,
151*c8dee2aaSAndroid Build Coastguard Worker                                              "op": 100,
152*c8dee2aaSAndroid Build Coastguard Worker                                              "ks": {}
153*c8dee2aaSAndroid Build Coastguard Worker                                            },
154*c8dee2aaSAndroid Build Coastguard Worker                                            {
155*c8dee2aaSAndroid Build Coastguard Worker                                              "ty": 2,
156*c8dee2aaSAndroid Build Coastguard Worker                                              "refId": "multi_frame",
157*c8dee2aaSAndroid Build Coastguard Worker                                              "ind": 1,
158*c8dee2aaSAndroid Build Coastguard Worker                                              "ip": 0,
159*c8dee2aaSAndroid Build Coastguard Worker                                              "op": 100,
160*c8dee2aaSAndroid Build Coastguard Worker                                              "ks": {}
161*c8dee2aaSAndroid Build Coastguard Worker                                            }
162*c8dee2aaSAndroid Build Coastguard Worker                                          ]
163*c8dee2aaSAndroid Build Coastguard Worker                                        })";
164*c8dee2aaSAndroid Build Coastguard Worker 
165*c8dee2aaSAndroid Build Coastguard Worker         SkMemoryStream stream(json, strlen(json));
166*c8dee2aaSAndroid Build Coastguard Worker 
167*c8dee2aaSAndroid Build Coastguard Worker         const auto flags = deferred_image_loading
168*c8dee2aaSAndroid Build Coastguard Worker             ? static_cast<uint32_t>(skottie::Animation::Builder::kDeferImageLoading)
169*c8dee2aaSAndroid Build Coastguard Worker             : 0;
170*c8dee2aaSAndroid Build Coastguard Worker         auto animation =
171*c8dee2aaSAndroid Build Coastguard Worker             skottie::Animation::Builder(flags)
172*c8dee2aaSAndroid Build Coastguard Worker                 .setResourceProvider(sk_make_sp<TestResourceProvider>(std::move(single_asset),
173*c8dee2aaSAndroid Build Coastguard Worker                                                                       std::move( multi_asset)))
174*c8dee2aaSAndroid Build Coastguard Worker                 .make(&stream);
175*c8dee2aaSAndroid Build Coastguard Worker 
176*c8dee2aaSAndroid Build Coastguard Worker         REPORTER_ASSERT(reporter, animation);
177*c8dee2aaSAndroid Build Coastguard Worker 
178*c8dee2aaSAndroid Build Coastguard Worker         return  animation;
179*c8dee2aaSAndroid Build Coastguard Worker     };
180*c8dee2aaSAndroid Build Coastguard Worker 
181*c8dee2aaSAndroid Build Coastguard Worker     class TestAsset final : public skresources::ImageAsset {
182*c8dee2aaSAndroid Build Coastguard Worker     public:
183*c8dee2aaSAndroid Build Coastguard Worker         explicit TestAsset(bool multi_frame) : fMultiFrame(multi_frame) {}
184*c8dee2aaSAndroid Build Coastguard Worker 
185*c8dee2aaSAndroid Build Coastguard Worker         const std::vector<float>& requestedFrames() const { return fRequestedFrames; }
186*c8dee2aaSAndroid Build Coastguard Worker 
187*c8dee2aaSAndroid Build Coastguard Worker     private:
188*c8dee2aaSAndroid Build Coastguard Worker         bool isMultiFrame() override { return fMultiFrame; }
189*c8dee2aaSAndroid Build Coastguard Worker 
190*c8dee2aaSAndroid Build Coastguard Worker         sk_sp<SkImage> getFrame(float t) override {
191*c8dee2aaSAndroid Build Coastguard Worker             fRequestedFrames.push_back(t);
192*c8dee2aaSAndroid Build Coastguard Worker 
193*c8dee2aaSAndroid Build Coastguard Worker             return SkSurfaces::Raster(SkImageInfo::MakeN32Premul(10, 10))->makeImageSnapshot();
194*c8dee2aaSAndroid Build Coastguard Worker         }
195*c8dee2aaSAndroid Build Coastguard Worker 
196*c8dee2aaSAndroid Build Coastguard Worker         const bool fMultiFrame;
197*c8dee2aaSAndroid Build Coastguard Worker 
198*c8dee2aaSAndroid Build Coastguard Worker         std::vector<float> fRequestedFrames;
199*c8dee2aaSAndroid Build Coastguard Worker     };
200*c8dee2aaSAndroid Build Coastguard Worker 
201*c8dee2aaSAndroid Build Coastguard Worker     {
202*c8dee2aaSAndroid Build Coastguard Worker         auto single_asset = sk_make_sp<TestAsset>(false),
203*c8dee2aaSAndroid Build Coastguard Worker               multi_asset = sk_make_sp<TestAsset>(true);
204*c8dee2aaSAndroid Build Coastguard Worker 
205*c8dee2aaSAndroid Build Coastguard Worker         // Default image loading: single-frame images are loaded upfront, multi-frame images are
206*c8dee2aaSAndroid Build Coastguard Worker         // loaded on-demand.
207*c8dee2aaSAndroid Build Coastguard Worker         auto animation = make_animation(single_asset, multi_asset, false);
208*c8dee2aaSAndroid Build Coastguard Worker 
209*c8dee2aaSAndroid Build Coastguard Worker         REPORTER_ASSERT(reporter, single_asset->requestedFrames().size() == 1);
210*c8dee2aaSAndroid Build Coastguard Worker         REPORTER_ASSERT(reporter,  multi_asset->requestedFrames().size() == 0);
211*c8dee2aaSAndroid Build Coastguard Worker         REPORTER_ASSERT(reporter, SkScalarNearlyZero(single_asset->requestedFrames()[0]));
212*c8dee2aaSAndroid Build Coastguard Worker 
213*c8dee2aaSAndroid Build Coastguard Worker         animation->seekFrameTime(1);
214*c8dee2aaSAndroid Build Coastguard Worker         REPORTER_ASSERT(reporter, single_asset->requestedFrames().size() == 1);
215*c8dee2aaSAndroid Build Coastguard Worker         REPORTER_ASSERT(reporter,  multi_asset->requestedFrames().size() == 1);
216*c8dee2aaSAndroid Build Coastguard Worker         REPORTER_ASSERT(reporter, SkScalarNearlyEqual(multi_asset->requestedFrames()[0], 1));
217*c8dee2aaSAndroid Build Coastguard Worker 
218*c8dee2aaSAndroid Build Coastguard Worker         animation->seekFrameTime(2);
219*c8dee2aaSAndroid Build Coastguard Worker         REPORTER_ASSERT(reporter, single_asset->requestedFrames().size() == 1);
220*c8dee2aaSAndroid Build Coastguard Worker         REPORTER_ASSERT(reporter,  multi_asset->requestedFrames().size() == 2);
221*c8dee2aaSAndroid Build Coastguard Worker         REPORTER_ASSERT(reporter, SkScalarNearlyEqual(multi_asset->requestedFrames()[1], 2));
222*c8dee2aaSAndroid Build Coastguard Worker     }
223*c8dee2aaSAndroid Build Coastguard Worker 
224*c8dee2aaSAndroid Build Coastguard Worker     {
225*c8dee2aaSAndroid Build Coastguard Worker         auto single_asset = sk_make_sp<TestAsset>(false),
226*c8dee2aaSAndroid Build Coastguard Worker               multi_asset = sk_make_sp<TestAsset>(true);
227*c8dee2aaSAndroid Build Coastguard Worker 
228*c8dee2aaSAndroid Build Coastguard Worker         // Deferred image loading: both single-frame and multi-frame images are loaded on-demand.
229*c8dee2aaSAndroid Build Coastguard Worker         auto animation = make_animation(single_asset, multi_asset, true);
230*c8dee2aaSAndroid Build Coastguard Worker 
231*c8dee2aaSAndroid Build Coastguard Worker         REPORTER_ASSERT(reporter, single_asset->requestedFrames().size() == 0);
232*c8dee2aaSAndroid Build Coastguard Worker         REPORTER_ASSERT(reporter,  multi_asset->requestedFrames().size() == 0);
233*c8dee2aaSAndroid Build Coastguard Worker 
234*c8dee2aaSAndroid Build Coastguard Worker         animation->seekFrameTime(1);
235*c8dee2aaSAndroid Build Coastguard Worker         REPORTER_ASSERT(reporter, single_asset->requestedFrames().size() == 1);
236*c8dee2aaSAndroid Build Coastguard Worker         REPORTER_ASSERT(reporter,  multi_asset->requestedFrames().size() == 1);
237*c8dee2aaSAndroid Build Coastguard Worker         REPORTER_ASSERT(reporter, SkScalarNearlyEqual(single_asset->requestedFrames()[0], 1));
238*c8dee2aaSAndroid Build Coastguard Worker         REPORTER_ASSERT(reporter, SkScalarNearlyEqual (multi_asset->requestedFrames()[0], 1));
239*c8dee2aaSAndroid Build Coastguard Worker 
240*c8dee2aaSAndroid Build Coastguard Worker         animation->seekFrameTime(2);
241*c8dee2aaSAndroid Build Coastguard Worker         REPORTER_ASSERT(reporter, single_asset->requestedFrames().size() == 1);
242*c8dee2aaSAndroid Build Coastguard Worker         REPORTER_ASSERT(reporter,  multi_asset->requestedFrames().size() == 2);
243*c8dee2aaSAndroid Build Coastguard Worker         REPORTER_ASSERT(reporter, SkScalarNearlyEqual(multi_asset->requestedFrames()[1], 2));
244*c8dee2aaSAndroid Build Coastguard Worker     }
245*c8dee2aaSAndroid Build Coastguard Worker }
246*c8dee2aaSAndroid Build Coastguard Worker 
DEF_TEST(Skottie_Layer_NoType,r)247*c8dee2aaSAndroid Build Coastguard Worker DEF_TEST(Skottie_Layer_NoType, r) {
248*c8dee2aaSAndroid Build Coastguard Worker     static constexpr char json[] =
249*c8dee2aaSAndroid Build Coastguard Worker         R"({
250*c8dee2aaSAndroid Build Coastguard Worker              "v": "5.2.1",
251*c8dee2aaSAndroid Build Coastguard Worker              "w": 100,
252*c8dee2aaSAndroid Build Coastguard Worker              "h": 100,
253*c8dee2aaSAndroid Build Coastguard Worker              "fr": 10,
254*c8dee2aaSAndroid Build Coastguard Worker              "ip": 0,
255*c8dee2aaSAndroid Build Coastguard Worker              "op": 100,
256*c8dee2aaSAndroid Build Coastguard Worker              "layers": [
257*c8dee2aaSAndroid Build Coastguard Worker                {
258*c8dee2aaSAndroid Build Coastguard Worker                  "ind": 0,
259*c8dee2aaSAndroid Build Coastguard Worker                  "ip": 0,
260*c8dee2aaSAndroid Build Coastguard Worker                  "op": 100,
261*c8dee2aaSAndroid Build Coastguard Worker                  "ks": {}
262*c8dee2aaSAndroid Build Coastguard Worker                }
263*c8dee2aaSAndroid Build Coastguard Worker              ]
264*c8dee2aaSAndroid Build Coastguard Worker            })";
265*c8dee2aaSAndroid Build Coastguard Worker 
266*c8dee2aaSAndroid Build Coastguard Worker     SkMemoryStream stream(json, strlen(json));
267*c8dee2aaSAndroid Build Coastguard Worker     auto anim = Animation::Make(&stream);
268*c8dee2aaSAndroid Build Coastguard Worker 
269*c8dee2aaSAndroid Build Coastguard Worker     // passes if we don't crash
270*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(r, anim);
271*c8dee2aaSAndroid Build Coastguard Worker }
272