1/* 2 * Copyright 2020 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8#include "modules/skottie/include/Skottie.h" 9 10#include "tests/Test.h" 11 12using namespace skottie; 13using namespace skresources; 14 15DEF_TEST(Skottie_AudioLayer, r) { 16 static constexpr char json[] = 17 R"({ 18 "v": "5.2.1", 19 "w": 100, 20 "h": 100, 21 "fr": 10, 22 "ip": 0, 23 "op": 100, 24 "assets": [ 25 { 26 "id": "audio_0", 27 "p" : "audio.mp3", 28 "u" : "assets/" 29 } 30 ], 31 "layers": [ 32 { 33 "ty" : 6, 34 "ind" : 0, 35 "ip" : 20, 36 "op" : 70, 37 "refId": "audio_0" 38 }, 39 { 40 "ty" : 6, 41 "ind" : 0, 42 "ip" : 50, 43 "op" : 80, 44 "refId": "audio_0" 45 }, 46 { 47 "ty": 1, 48 "ip": 0, 49 "op": 100, 50 "sw": 100, 51 "sh": 100, 52 "sc": "#ffffff" 53 } 54 ] 55 })"; 56 57 class MockTracker final : public ExternalTrackAsset { 58 public: 59 bool isPlaying() const { return fCurrentTime >= 0; } 60 float currentTime() const { return fCurrentTime; } 61 62 private: 63 void seek(float t) override { 64 fCurrentTime = t; 65 } 66 67 float fCurrentTime = 0; 68 }; 69 70 class MockResourceProvider final : public ResourceProvider { 71 public: 72 explicit MockResourceProvider(skiatest::Reporter* r) : fReporter(r) {} 73 74 const std::vector<sk_sp<MockTracker>>& tracks() const { return fTracks; } 75 76 private: 77 sk_sp<ExternalTrackAsset> loadAudioAsset(const char path[], 78 const char name[], 79 const char id[]) override { 80 REPORTER_ASSERT(fReporter, !strcmp(path, "assets/")); 81 REPORTER_ASSERT(fReporter, !strcmp(name, "audio.mp3")); 82 REPORTER_ASSERT(fReporter, !strcmp(id , "audio_0")); 83 84 fTracks.push_back(sk_make_sp<MockTracker>()); 85 86 return fTracks.back(); 87 } 88 89 skiatest::Reporter* fReporter; 90 std::vector<sk_sp<MockTracker>> fTracks; 91 }; 92 93 SkMemoryStream stream(json, strlen(json)); 94 auto rp = sk_make_sp<MockResourceProvider>(r); 95 96 auto skottie = skottie::Animation::Builder() 97 .setResourceProvider(rp) 98 .make(&stream); 99 100 const auto& tracks = rp->tracks(); 101 102 REPORTER_ASSERT(r, skottie); 103 REPORTER_ASSERT(r, tracks.size() == 2); 104 105 skottie->seekFrame(0); 106 REPORTER_ASSERT(r, !tracks[0]->isPlaying()); 107 REPORTER_ASSERT(r, !tracks[1]->isPlaying()); 108 109 skottie->seekFrame(20); 110 REPORTER_ASSERT(r, tracks[0]->isPlaying()); 111 REPORTER_ASSERT(r, !tracks[1]->isPlaying()); 112 REPORTER_ASSERT(r, tracks[0]->currentTime() == 0); 113 114 skottie->seekFrame(50); 115 REPORTER_ASSERT(r, tracks[0]->isPlaying()); 116 REPORTER_ASSERT(r, tracks[1]->isPlaying()); 117 REPORTER_ASSERT(r, tracks[0]->currentTime() == 3); 118 REPORTER_ASSERT(r, tracks[1]->currentTime() == 0); 119 120 skottie->seekFrame(70); 121 REPORTER_ASSERT(r, tracks[0]->isPlaying()); 122 REPORTER_ASSERT(r, tracks[1]->isPlaying()); 123 REPORTER_ASSERT(r, tracks[0]->currentTime() == 5); 124 REPORTER_ASSERT(r, tracks[1]->currentTime() == 2); 125 126 skottie->seekFrame(80); 127 REPORTER_ASSERT(r, !tracks[0]->isPlaying()); 128 REPORTER_ASSERT(r, tracks[1]->isPlaying()); 129 REPORTER_ASSERT(r, tracks[1]->currentTime() == 3); 130 131 skottie->seekFrame(100); 132 REPORTER_ASSERT(r, !tracks[0]->isPlaying()); 133 REPORTER_ASSERT(r, !tracks[1]->isPlaying()); 134} 135