1/* Copyright 2016 The Android Open Source Project
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *      http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16//#define LOG_NDEBUG 0
17#define LOG_TAG "SurfaceReplayer"
18
19#include "Replayer.h"
20
21#include <android/native_window.h>
22
23#include <android-base/file.h>
24
25#include <gui/BufferQueue.h>
26#include <gui/ISurfaceComposer.h>
27#include <gui/LayerState.h>
28#include <gui/Surface.h>
29#include <private/gui/ComposerService.h>
30
31#include <ui/DisplayInfo.h>
32#include <utils/Log.h>
33#include <utils/String8.h>
34#include <utils/Trace.h>
35
36#include <chrono>
37#include <cmath>
38#include <condition_variable>
39#include <cstdlib>
40#include <fstream>
41#include <functional>
42#include <iostream>
43#include <mutex>
44#include <sstream>
45#include <string>
46#include <thread>
47#include <vector>
48
49using namespace android;
50
51std::atomic_bool Replayer::sReplayingManually(false);
52
53Replayer::Replayer(const std::string& filename, bool replayManually, int numThreads, bool wait,
54        nsecs_t stopHere)
55      : mTrace(),
56        mLoaded(false),
57        mIncrementIndex(0),
58        mCurrentTime(0),
59        mNumThreads(numThreads),
60        mWaitForTimeStamps(wait),
61        mStopTimeStamp(stopHere) {
62    srand(RAND_COLOR_SEED);
63
64    std::string input;
65    if (!android::base::ReadFileToString(filename, &input, true)) {
66        std::cerr << "Trace did not load. Does " << filename << " exist?" << std::endl;
67        abort();
68    }
69
70    mLoaded = mTrace.ParseFromString(input);
71    if (!mLoaded) {
72        std::cerr << "Trace did not load." << std::endl;
73        abort();
74    }
75
76    mCurrentTime = mTrace.increment(0).time_stamp();
77
78    sReplayingManually.store(replayManually);
79
80    if (stopHere < 0) {
81        mHasStopped = true;
82    }
83}
84
85Replayer::Replayer(const Trace& t, bool replayManually, int numThreads, bool wait, nsecs_t stopHere)
86      : mTrace(t),
87        mLoaded(true),
88        mIncrementIndex(0),
89        mCurrentTime(0),
90        mNumThreads(numThreads),
91        mWaitForTimeStamps(wait),
92        mStopTimeStamp(stopHere) {
93    srand(RAND_COLOR_SEED);
94    mCurrentTime = mTrace.increment(0).time_stamp();
95
96    sReplayingManually.store(replayManually);
97
98    if (stopHere < 0) {
99        mHasStopped = true;
100    }
101}
102
103status_t Replayer::replay() {
104    signal(SIGINT, Replayer::stopAutoReplayHandler); //for manual control
105
106    ALOGV("There are %d increments.", mTrace.increment_size());
107
108    status_t status = loadSurfaceComposerClient();
109
110    if (status != NO_ERROR) {
111        ALOGE("Couldn't create SurfaceComposerClient (%d)", status);
112        return status;
113    }
114
115    SurfaceComposerClient::enableVSyncInjections(true);
116
117    initReplay();
118
119    ALOGV("Starting actual Replay!");
120    while (!mPendingIncrements.empty()) {
121        mCurrentIncrement = mTrace.increment(mIncrementIndex);
122
123        if (mHasStopped == false && mCurrentIncrement.time_stamp() >= mStopTimeStamp) {
124            mHasStopped = true;
125            sReplayingManually.store(true);
126        }
127
128        waitForConsoleCommmand();
129
130        if (mWaitForTimeStamps) {
131            waitUntilTimestamp(mCurrentIncrement.time_stamp());
132        }
133
134        auto event = mPendingIncrements.front();
135        mPendingIncrements.pop();
136
137        event->complete();
138
139        if (event->getIncrementType() == Increment::kVsyncEvent) {
140            mWaitingForNextVSync = false;
141        }
142
143        if (mIncrementIndex + mNumThreads < mTrace.increment_size()) {
144            status = dispatchEvent(mIncrementIndex + mNumThreads);
145
146            if (status != NO_ERROR) {
147                SurfaceComposerClient::enableVSyncInjections(false);
148                return status;
149            }
150        }
151
152        mIncrementIndex++;
153        mCurrentTime = mCurrentIncrement.time_stamp();
154    }
155
156    SurfaceComposerClient::enableVSyncInjections(false);
157
158    return status;
159}
160
161status_t Replayer::initReplay() {
162    for (int i = 0; i < mNumThreads && i < mTrace.increment_size(); i++) {
163        status_t status = dispatchEvent(i);
164
165        if (status != NO_ERROR) {
166            ALOGE("Unable to dispatch event (%d)", status);
167            return status;
168        }
169    }
170
171    return NO_ERROR;
172}
173
174void Replayer::stopAutoReplayHandler(int /*signal*/) {
175    if (sReplayingManually) {
176        SurfaceComposerClient::enableVSyncInjections(false);
177        exit(0);
178    }
179
180    sReplayingManually.store(true);
181}
182
183std::vector<std::string> split(const std::string& s, const char delim) {
184    std::vector<std::string> elems;
185    std::stringstream ss(s);
186    std::string item;
187    while (getline(ss, item, delim)) {
188        elems.push_back(item);
189    }
190    return elems;
191}
192
193bool isNumber(const std::string& s) {
194    return !s.empty() &&
195           std::find_if(s.begin(), s.end(), [](char c) { return !std::isdigit(c); }) == s.end();
196}
197
198void Replayer::waitForConsoleCommmand() {
199    if (!sReplayingManually || mWaitingForNextVSync) {
200        return;
201    }
202
203    while (true) {
204        std::string input = "";
205        std::cout << "> ";
206        getline(std::cin, input);
207
208        if (input.empty()) {
209            input = mLastInput;
210        } else {
211            mLastInput = input;
212        }
213
214        if (mLastInput.empty()) {
215            continue;
216        }
217
218        std::vector<std::string> inputs = split(input, ' ');
219
220        if (inputs[0] == "n") {  // next vsync
221            mWaitingForNextVSync = true;
222            break;
223
224        } else if (inputs[0] == "ni") {  // next increment
225            break;
226
227        } else if (inputs[0] == "c") {  // continue
228            if (inputs.size() > 1 && isNumber(inputs[1])) {
229                long milliseconds = stoi(inputs[1]);
230                std::thread([&] {
231                    std::cout << "Started!" << std::endl;
232                    std::this_thread::sleep_for(std::chrono::milliseconds(milliseconds));
233                    sReplayingManually.store(true);
234                    std::cout << "Should have stopped!" << std::endl;
235                }).detach();
236            }
237            sReplayingManually.store(false);
238            mWaitingForNextVSync = false;
239            break;
240
241        } else if (inputs[0] == "s") {  // stop at this timestamp
242            if (inputs.size() < 1) {
243                std::cout << "No time stamp given" << std::endl;
244                continue;
245            }
246            sReplayingManually.store(false);
247            mStopTimeStamp = stol(inputs[1]);
248            mHasStopped = false;
249            break;
250        } else if (inputs[0] == "l") {  // list
251            std::cout << "Time stamp: " << mCurrentIncrement.time_stamp() << "\n";
252            continue;
253        } else if (inputs[0] == "q") {  // quit
254            SurfaceComposerClient::enableVSyncInjections(false);
255            exit(0);
256
257        } else if (inputs[0] == "h") {  // help
258                                        // add help menu
259            std::cout << "Manual Replay options:\n";
260            std::cout << " n  - Go to next VSync\n";
261            std::cout << " ni - Go to next increment\n";
262            std::cout << " c  - Continue\n";
263            std::cout << " c [milliseconds] - Continue until specified number of milliseconds\n";
264            std::cout << " s [timestamp]    - Continue and stop at specified timestamp\n";
265            std::cout << " l  - List out timestamp of current increment\n";
266            std::cout << " h  - Display help menu\n";
267            std::cout << std::endl;
268            continue;
269        }
270
271        std::cout << "Invalid Command" << std::endl;
272    }
273}
274
275status_t Replayer::dispatchEvent(int index) {
276    auto increment = mTrace.increment(index);
277    std::shared_ptr<Event> event = std::make_shared<Event>(increment.increment_case());
278    mPendingIncrements.push(event);
279
280    status_t status = NO_ERROR;
281    switch (increment.increment_case()) {
282        case increment.kTransaction: {
283            std::thread(&Replayer::doTransaction, this, increment.transaction(), event).detach();
284        } break;
285        case increment.kSurfaceCreation: {
286            std::thread(&Replayer::createSurfaceControl, this, increment.surface_creation(), event)
287                    .detach();
288        } break;
289        case increment.kSurfaceDeletion: {
290            std::thread(&Replayer::deleteSurfaceControl, this, increment.surface_deletion(), event)
291                    .detach();
292        } break;
293        case increment.kBufferUpdate: {
294            std::lock_guard<std::mutex> lock1(mLayerLock);
295            std::lock_guard<std::mutex> lock2(mBufferQueueSchedulerLock);
296
297            Dimensions dimensions(increment.buffer_update().w(), increment.buffer_update().h());
298            BufferEvent bufferEvent(event, dimensions);
299
300            auto layerId = increment.buffer_update().id();
301            if (mBufferQueueSchedulers.count(layerId) == 0) {
302                mBufferQueueSchedulers[layerId] = std::make_shared<BufferQueueScheduler>(
303                        mLayers[layerId], mColors[layerId], layerId);
304                mBufferQueueSchedulers[layerId]->addEvent(bufferEvent);
305
306                std::thread(&BufferQueueScheduler::startScheduling,
307                        mBufferQueueSchedulers[increment.buffer_update().id()].get())
308                        .detach();
309            } else {
310                auto bqs = mBufferQueueSchedulers[increment.buffer_update().id()];
311                bqs->addEvent(bufferEvent);
312            }
313        } break;
314        case increment.kVsyncEvent: {
315            std::thread(&Replayer::injectVSyncEvent, this, increment.vsync_event(), event).detach();
316        } break;
317        case increment.kDisplayCreation: {
318            std::thread(&Replayer::createDisplay, this, increment.display_creation(), event)
319                    .detach();
320        } break;
321        case increment.kDisplayDeletion: {
322            std::thread(&Replayer::deleteDisplay, this, increment.display_deletion(), event)
323                    .detach();
324        } break;
325        case increment.kPowerModeUpdate: {
326            std::thread(&Replayer::updatePowerMode, this, increment.power_mode_update(), event)
327                    .detach();
328        } break;
329        default:
330            ALOGE("Unknown Increment Type: %d", increment.increment_case());
331            status = BAD_VALUE;
332            break;
333    }
334
335    return status;
336}
337
338status_t Replayer::doTransaction(const Transaction& t, const std::shared_ptr<Event>& event) {
339    ALOGV("Started Transaction");
340
341    SurfaceComposerClient::Transaction liveTransaction;
342
343    status_t status = NO_ERROR;
344
345    status = doSurfaceTransaction(liveTransaction, t.surface_change());
346    doDisplayTransaction(liveTransaction, t.display_change());
347
348    if (t.animation()) {
349        liveTransaction.setAnimationTransaction();
350    }
351
352    event->readyToExecute();
353
354    liveTransaction.apply(t.synchronous());
355
356    ALOGV("Ended Transaction");
357
358    return status;
359}
360
361status_t Replayer::doSurfaceTransaction(
362        SurfaceComposerClient::Transaction& transaction,
363        const SurfaceChanges& surfaceChanges) {
364    status_t status = NO_ERROR;
365
366    for (const SurfaceChange& change : surfaceChanges) {
367        std::unique_lock<std::mutex> lock(mLayerLock);
368        if (mLayers[change.id()] == nullptr) {
369            mLayerCond.wait(lock, [&] { return (mLayers[change.id()] != nullptr); });
370        }
371
372        switch (change.SurfaceChange_case()) {
373            case SurfaceChange::SurfaceChangeCase::kPosition:
374                setPosition(transaction, change.id(), change.position());
375                break;
376            case SurfaceChange::SurfaceChangeCase::kSize:
377                setSize(transaction, change.id(), change.size());
378                break;
379            case SurfaceChange::SurfaceChangeCase::kAlpha:
380                setAlpha(transaction, change.id(), change.alpha());
381                break;
382            case SurfaceChange::SurfaceChangeCase::kLayer:
383                setLayer(transaction, change.id(), change.layer());
384                break;
385            case SurfaceChange::SurfaceChangeCase::kCrop:
386                setCrop(transaction, change.id(), change.crop());
387                break;
388            case SurfaceChange::SurfaceChangeCase::kMatrix:
389                setMatrix(transaction, change.id(), change.matrix());
390                break;
391            case SurfaceChange::SurfaceChangeCase::kFinalCrop:
392                setFinalCrop(transaction, change.id(), change.final_crop());
393                break;
394            case SurfaceChange::SurfaceChangeCase::kOverrideScalingMode:
395                setOverrideScalingMode(transaction, change.id(),
396                        change.override_scaling_mode());
397                break;
398            case SurfaceChange::SurfaceChangeCase::kTransparentRegionHint:
399                setTransparentRegionHint(transaction, change.id(),
400                        change.transparent_region_hint());
401                break;
402            case SurfaceChange::SurfaceChangeCase::kLayerStack:
403                setLayerStack(transaction, change.id(), change.layer_stack());
404                break;
405            case SurfaceChange::SurfaceChangeCase::kHiddenFlag:
406                setHiddenFlag(transaction, change.id(), change.hidden_flag());
407                break;
408            case SurfaceChange::SurfaceChangeCase::kOpaqueFlag:
409                setOpaqueFlag(transaction, change.id(), change.opaque_flag());
410                break;
411            case SurfaceChange::SurfaceChangeCase::kSecureFlag:
412                setSecureFlag(transaction, change.id(), change.secure_flag());
413                break;
414            case SurfaceChange::SurfaceChangeCase::kDeferredTransaction:
415                waitUntilDeferredTransactionLayerExists(change.deferred_transaction(), lock);
416                setDeferredTransaction(transaction, change.id(),
417                        change.deferred_transaction());
418                break;
419            default:
420                status = 1;
421                break;
422        }
423
424        if (status != NO_ERROR) {
425            ALOGE("Unknown Transaction Code");
426            return status;
427        }
428    }
429    return status;
430}
431
432void Replayer::doDisplayTransaction(SurfaceComposerClient::Transaction& t,
433        const DisplayChanges& displayChanges) {
434    for (const DisplayChange& change : displayChanges) {
435        ALOGV("Doing display transaction");
436        std::unique_lock<std::mutex> lock(mDisplayLock);
437        if (mDisplays[change.id()] == nullptr) {
438            mDisplayCond.wait(lock, [&] { return (mDisplays[change.id()] != nullptr); });
439        }
440
441        switch (change.DisplayChange_case()) {
442            case DisplayChange::DisplayChangeCase::kSurface:
443                setDisplaySurface(t, change.id(), change.surface());
444                break;
445            case DisplayChange::DisplayChangeCase::kLayerStack:
446                setDisplayLayerStack(t, change.id(), change.layer_stack());
447                break;
448            case DisplayChange::DisplayChangeCase::kSize:
449                setDisplaySize(t, change.id(), change.size());
450                break;
451            case DisplayChange::DisplayChangeCase::kProjection:
452                setDisplayProjection(t, change.id(), change.projection());
453                break;
454            default:
455                break;
456        }
457    }
458}
459
460void Replayer::setPosition(SurfaceComposerClient::Transaction& t,
461        layer_id id, const PositionChange& pc) {
462    ALOGV("Layer %d: Setting Position -- x=%f, y=%f", id, pc.x(), pc.y());
463    t.setPosition(mLayers[id], pc.x(), pc.y());
464}
465
466void Replayer::setSize(SurfaceComposerClient::Transaction& t,
467        layer_id id, const SizeChange& sc) {
468    ALOGV("Layer %d: Setting Size -- w=%u, h=%u", id, sc.w(), sc.h());
469    t.setSize(mLayers[id], sc.w(), sc.h());
470}
471
472void Replayer::setLayer(SurfaceComposerClient::Transaction& t,
473        layer_id id, const LayerChange& lc) {
474    ALOGV("Layer %d: Setting Layer -- layer=%d", id, lc.layer());
475    t.setLayer(mLayers[id], lc.layer());
476}
477
478void Replayer::setAlpha(SurfaceComposerClient::Transaction& t,
479        layer_id id, const AlphaChange& ac) {
480    ALOGV("Layer %d: Setting Alpha -- alpha=%f", id, ac.alpha());
481    t.setAlpha(mLayers[id], ac.alpha());
482}
483
484void Replayer::setCrop(SurfaceComposerClient::Transaction& t,
485        layer_id id, const CropChange& cc) {
486    ALOGV("Layer %d: Setting Crop -- left=%d, top=%d, right=%d, bottom=%d", id,
487            cc.rectangle().left(), cc.rectangle().top(), cc.rectangle().right(),
488            cc.rectangle().bottom());
489
490    Rect r = Rect(cc.rectangle().left(), cc.rectangle().top(), cc.rectangle().right(),
491            cc.rectangle().bottom());
492    t.setCrop(mLayers[id], r);
493}
494
495void Replayer::setFinalCrop(SurfaceComposerClient::Transaction& t,
496        layer_id id, const FinalCropChange& fcc) {
497    ALOGV("Layer %d: Setting Final Crop -- left=%d, top=%d, right=%d, bottom=%d", id,
498            fcc.rectangle().left(), fcc.rectangle().top(), fcc.rectangle().right(),
499            fcc.rectangle().bottom());
500    Rect r = Rect(fcc.rectangle().left(), fcc.rectangle().top(), fcc.rectangle().right(),
501            fcc.rectangle().bottom());
502    t.setFinalCrop(mLayers[id], r);
503}
504
505void Replayer::setMatrix(SurfaceComposerClient::Transaction& t,
506        layer_id id, const MatrixChange& mc) {
507    ALOGV("Layer %d: Setting Matrix -- dsdx=%f, dtdx=%f, dsdy=%f, dtdy=%f", id, mc.dsdx(),
508            mc.dtdx(), mc.dsdy(), mc.dtdy());
509    t.setMatrix(mLayers[id], mc.dsdx(), mc.dtdx(), mc.dsdy(), mc.dtdy());
510}
511
512void Replayer::setOverrideScalingMode(SurfaceComposerClient::Transaction& t,
513        layer_id id, const OverrideScalingModeChange& osmc) {
514    ALOGV("Layer %d: Setting Override Scaling Mode -- mode=%d", id, osmc.override_scaling_mode());
515    t.setOverrideScalingMode(mLayers[id], osmc.override_scaling_mode());
516}
517
518void Replayer::setTransparentRegionHint(SurfaceComposerClient::Transaction& t,
519        layer_id id, const TransparentRegionHintChange& trhc) {
520    ALOGV("Setting Transparent Region Hint");
521    Region re = Region();
522
523    for (const auto& r : trhc.region()) {
524        Rect rect = Rect(r.left(), r.top(), r.right(), r.bottom());
525        re.merge(rect);
526    }
527
528    t.setTransparentRegionHint(mLayers[id], re);
529}
530
531void Replayer::setLayerStack(SurfaceComposerClient::Transaction& t,
532        layer_id id, const LayerStackChange& lsc) {
533    ALOGV("Layer %d: Setting LayerStack -- layer_stack=%d", id, lsc.layer_stack());
534    t.setLayerStack(mLayers[id], lsc.layer_stack());
535}
536
537void Replayer::setHiddenFlag(SurfaceComposerClient::Transaction& t,
538        layer_id id, const HiddenFlagChange& hfc) {
539    ALOGV("Layer %d: Setting Hidden Flag -- hidden_flag=%d", id, hfc.hidden_flag());
540    layer_id flag = hfc.hidden_flag() ? layer_state_t::eLayerHidden : 0;
541
542    t.setFlags(mLayers[id], flag, layer_state_t::eLayerHidden);
543}
544
545void Replayer::setOpaqueFlag(SurfaceComposerClient::Transaction& t,
546        layer_id id, const OpaqueFlagChange& ofc) {
547    ALOGV("Layer %d: Setting Opaque Flag -- opaque_flag=%d", id, ofc.opaque_flag());
548    layer_id flag = ofc.opaque_flag() ? layer_state_t::eLayerOpaque : 0;
549
550    t.setFlags(mLayers[id], flag, layer_state_t::eLayerOpaque);
551}
552
553void Replayer::setSecureFlag(SurfaceComposerClient::Transaction& t,
554        layer_id id, const SecureFlagChange& sfc) {
555    ALOGV("Layer %d: Setting Secure Flag -- secure_flag=%d", id, sfc.secure_flag());
556    layer_id flag = sfc.secure_flag() ? layer_state_t::eLayerSecure : 0;
557
558    t.setFlags(mLayers[id], flag, layer_state_t::eLayerSecure);
559}
560
561void Replayer::setDeferredTransaction(SurfaceComposerClient::Transaction& t,
562        layer_id id, const DeferredTransactionChange& dtc) {
563    ALOGV("Layer %d: Setting Deferred Transaction -- layer_id=%d, "
564          "frame_number=%llu",
565            id, dtc.layer_id(), dtc.frame_number());
566    if (mLayers.count(dtc.layer_id()) == 0 || mLayers[dtc.layer_id()] == nullptr) {
567        ALOGE("Layer %d not found in Deferred Transaction", dtc.layer_id());
568        return;
569    }
570
571    auto handle = mLayers[dtc.layer_id()]->getHandle();
572
573    t.deferTransactionUntil(mLayers[id], handle, dtc.frame_number());
574}
575
576void Replayer::setDisplaySurface(SurfaceComposerClient::Transaction& t,
577        display_id id, const DispSurfaceChange& /*dsc*/) {
578    sp<IGraphicBufferProducer> outProducer;
579    sp<IGraphicBufferConsumer> outConsumer;
580    BufferQueue::createBufferQueue(&outProducer, &outConsumer);
581
582    t.setDisplaySurface(mDisplays[id], outProducer);
583}
584
585void Replayer::setDisplayLayerStack(SurfaceComposerClient::Transaction& t,
586        display_id id, const LayerStackChange& lsc) {
587    t.setDisplayLayerStack(mDisplays[id], lsc.layer_stack());
588}
589
590void Replayer::setDisplaySize(SurfaceComposerClient::Transaction& t,
591        display_id id, const SizeChange& sc) {
592    t.setDisplaySize(mDisplays[id], sc.w(), sc.h());
593}
594
595void Replayer::setDisplayProjection(SurfaceComposerClient::Transaction& t,
596        display_id id, const ProjectionChange& pc) {
597    Rect viewport = Rect(pc.viewport().left(), pc.viewport().top(), pc.viewport().right(),
598            pc.viewport().bottom());
599    Rect frame = Rect(pc.frame().left(), pc.frame().top(), pc.frame().right(), pc.frame().bottom());
600
601    t.setDisplayProjection(mDisplays[id], pc.orientation(), viewport, frame);
602}
603
604status_t Replayer::createSurfaceControl(
605        const SurfaceCreation& create, const std::shared_ptr<Event>& event) {
606    event->readyToExecute();
607
608    ALOGV("Creating Surface Control: ID: %d", create.id());
609    sp<SurfaceControl> surfaceControl = mComposerClient->createSurface(
610            String8(create.name().c_str()), create.w(), create.h(), PIXEL_FORMAT_RGBA_8888, 0);
611
612    if (surfaceControl == nullptr) {
613        ALOGE("CreateSurfaceControl: unable to create surface control");
614        return BAD_VALUE;
615    }
616
617    std::lock_guard<std::mutex> lock1(mLayerLock);
618    auto& layer = mLayers[create.id()];
619    layer = surfaceControl;
620
621    mColors[create.id()] = HSV(rand() % 360, 1, 1);
622
623    mLayerCond.notify_all();
624
625    std::lock_guard<std::mutex> lock2(mBufferQueueSchedulerLock);
626    if (mBufferQueueSchedulers.count(create.id()) != 0) {
627        mBufferQueueSchedulers[create.id()]->setSurfaceControl(
628                mLayers[create.id()], mColors[create.id()]);
629    }
630
631    return NO_ERROR;
632}
633
634status_t Replayer::deleteSurfaceControl(
635        const SurfaceDeletion& delete_, const std::shared_ptr<Event>& event) {
636    ALOGV("Deleting %d Surface Control", delete_.id());
637    event->readyToExecute();
638
639    std::lock_guard<std::mutex> lock1(mPendingLayersLock);
640
641    mLayersPendingRemoval.push_back(delete_.id());
642
643    const auto& iterator = mBufferQueueSchedulers.find(delete_.id());
644    if (iterator != mBufferQueueSchedulers.end()) {
645        (*iterator).second->stopScheduling();
646    }
647
648    std::lock_guard<std::mutex> lock2(mLayerLock);
649    if (mLayers[delete_.id()] != nullptr) {
650        mComposerClient->destroySurface(mLayers[delete_.id()]->getHandle());
651    }
652
653    return NO_ERROR;
654}
655
656void Replayer::doDeleteSurfaceControls() {
657    std::lock_guard<std::mutex> lock1(mPendingLayersLock);
658    std::lock_guard<std::mutex> lock2(mLayerLock);
659    if (!mLayersPendingRemoval.empty()) {
660        for (int id : mLayersPendingRemoval) {
661            mLayers.erase(id);
662            mColors.erase(id);
663            mBufferQueueSchedulers.erase(id);
664        }
665        mLayersPendingRemoval.clear();
666    }
667}
668
669status_t Replayer::injectVSyncEvent(
670        const VSyncEvent& vSyncEvent, const std::shared_ptr<Event>& event) {
671    ALOGV("Injecting VSync Event");
672
673    doDeleteSurfaceControls();
674
675    event->readyToExecute();
676
677    SurfaceComposerClient::injectVSync(vSyncEvent.when());
678
679    return NO_ERROR;
680}
681
682void Replayer::createDisplay(const DisplayCreation& create, const std::shared_ptr<Event>& event) {
683    ALOGV("Creating display");
684    event->readyToExecute();
685
686    std::lock_guard<std::mutex> lock(mDisplayLock);
687    sp<IBinder> display = SurfaceComposerClient::createDisplay(
688            String8(create.name().c_str()), create.is_secure());
689    mDisplays[create.id()] = display;
690
691    mDisplayCond.notify_all();
692
693    ALOGV("Done creating display");
694}
695
696void Replayer::deleteDisplay(const DisplayDeletion& delete_, const std::shared_ptr<Event>& event) {
697    ALOGV("Delete display");
698    event->readyToExecute();
699
700    std::lock_guard<std::mutex> lock(mDisplayLock);
701    SurfaceComposerClient::destroyDisplay(mDisplays[delete_.id()]);
702    mDisplays.erase(delete_.id());
703}
704
705void Replayer::updatePowerMode(const PowerModeUpdate& pmu, const std::shared_ptr<Event>& event) {
706    ALOGV("Updating power mode");
707    event->readyToExecute();
708    SurfaceComposerClient::setDisplayPowerMode(mDisplays[pmu.id()], pmu.mode());
709}
710
711void Replayer::waitUntilTimestamp(int64_t timestamp) {
712    ALOGV("Waiting for %lld nanoseconds...", static_cast<int64_t>(timestamp - mCurrentTime));
713    std::this_thread::sleep_for(std::chrono::nanoseconds(timestamp - mCurrentTime));
714}
715
716void Replayer::waitUntilDeferredTransactionLayerExists(
717        const DeferredTransactionChange& dtc, std::unique_lock<std::mutex>& lock) {
718    if (mLayers.count(dtc.layer_id()) == 0 || mLayers[dtc.layer_id()] == nullptr) {
719        mLayerCond.wait(lock, [&] { return (mLayers[dtc.layer_id()] != nullptr); });
720    }
721}
722
723status_t Replayer::loadSurfaceComposerClient() {
724    mComposerClient = new SurfaceComposerClient;
725    return mComposerClient->initCheck();
726}
727