• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 //#define LOG_NDEBUG 0
18 #undef LOG_TAG
19 #define LOG_TAG "BufferStateLayer"
20 #define ATRACE_TAG ATRACE_TAG_GRAPHICS
21 
22 #include "BufferStateLayer.h"
23 
24 #include <limits>
25 
26 #include <FrameTimeline/FrameTimeline.h>
27 #include <compositionengine/LayerFECompositionState.h>
28 #include <gui/BufferQueue.h>
29 #include <private/gui/SyncFeatures.h>
30 #include <renderengine/Image.h>
31 #include "TunnelModeEnabledReporter.h"
32 
33 #include "EffectLayer.h"
34 #include "FrameTracer/FrameTracer.h"
35 #include "TimeStats/TimeStats.h"
36 
37 #define EARLY_RELEASE_ENABLED false
38 
39 namespace android {
40 
41 using PresentState = frametimeline::SurfaceFrame::PresentState;
42 namespace {
callReleaseBufferCallback(const sp<ITransactionCompletedListener> & listener,const sp<GraphicBuffer> & buffer,uint64_t framenumber,const sp<Fence> & releaseFence,uint32_t currentMaxAcquiredBufferCount)43 void callReleaseBufferCallback(const sp<ITransactionCompletedListener>& listener,
44                                const sp<GraphicBuffer>& buffer, uint64_t framenumber,
45                                const sp<Fence>& releaseFence,
46                                uint32_t currentMaxAcquiredBufferCount) {
47     if (!listener) {
48         return;
49     }
50     listener->onReleaseBuffer({buffer->getId(), framenumber},
51                               releaseFence ? releaseFence : Fence::NO_FENCE,
52                               currentMaxAcquiredBufferCount);
53 }
54 } // namespace
55 
BufferStateLayer(const LayerCreationArgs & args)56 BufferStateLayer::BufferStateLayer(const LayerCreationArgs& args)
57       : BufferLayer(args), mHwcSlotGenerator(new HwcSlotGenerator()) {
58     mDrawingState.dataspace = ui::Dataspace::V0_SRGB;
59 }
60 
~BufferStateLayer()61 BufferStateLayer::~BufferStateLayer() {
62     // The original layer and the clone layer share the same texture and buffer. Therefore, only
63     // one of the layers, in this case the original layer, needs to handle the deletion. The
64     // original layer and the clone should be removed at the same time so there shouldn't be any
65     // issue with the clone layer trying to use the texture.
66     if (mBufferInfo.mBuffer != nullptr) {
67         callReleaseBufferCallback(mDrawingState.releaseBufferListener,
68                                   mBufferInfo.mBuffer->getBuffer(), mBufferInfo.mFrameNumber,
69                                   mBufferInfo.mFence,
70                                   mFlinger->getMaxAcquiredBufferCountForCurrentRefreshRate(
71                                           mOwnerUid));
72     }
73 }
74 
75 // -----------------------------------------------------------------------
76 // Interface implementation for Layer
77 // -----------------------------------------------------------------------
onLayerDisplayed(ftl::SharedFuture<FenceResult> futureFenceResult)78 void BufferStateLayer::onLayerDisplayed(ftl::SharedFuture<FenceResult> futureFenceResult) {
79     // If we are displayed on multiple displays in a single composition cycle then we would
80     // need to do careful tracking to enable the use of the mLastClientCompositionFence.
81     //  For example we can only use it if all the displays are client comp, and we need
82     //  to merge all the client comp fences. We could do this, but for now we just
83     // disable the optimization when a layer is composed on multiple displays.
84     if (mClearClientCompositionFenceOnLayerDisplayed) {
85         mLastClientCompositionFence = nullptr;
86     } else {
87         mClearClientCompositionFenceOnLayerDisplayed = true;
88     }
89 
90     // The previous release fence notifies the client that SurfaceFlinger is done with the previous
91     // buffer that was presented on this layer. The first transaction that came in this frame that
92     // replaced the previous buffer on this layer needs this release fence, because the fence will
93     // let the client know when that previous buffer is removed from the screen.
94     //
95     // Every other transaction on this layer does not need a release fence because no other
96     // Transactions that were set on this layer this frame are going to have their preceeding buffer
97     // removed from the display this frame.
98     //
99     // For example, if we have 3 transactions this frame. The first transaction doesn't contain a
100     // buffer so it doesn't need a previous release fence because the layer still needs the previous
101     // buffer. The second transaction contains a buffer so it needs a previous release fence because
102     // the previous buffer will be released this frame. The third transaction also contains a
103     // buffer. It replaces the buffer in the second transaction. The buffer in the second
104     // transaction will now no longer be presented so it is released immediately and the third
105     // transaction doesn't need a previous release fence.
106     sp<CallbackHandle> ch;
107     for (auto& handle : mDrawingState.callbackHandles) {
108         if (handle->releasePreviousBuffer &&
109             mDrawingState.releaseBufferEndpoint == handle->listener) {
110             ch = handle;
111             break;
112         }
113     }
114 
115     // Prevent tracing the same release multiple times.
116     if (mPreviousFrameNumber != mPreviousReleasedFrameNumber) {
117         mPreviousReleasedFrameNumber = mPreviousFrameNumber;
118     }
119 
120     if (ch != nullptr) {
121         ch->previousReleaseCallbackId = mPreviousReleaseCallbackId;
122         ch->previousReleaseFences.emplace_back(std::move(futureFenceResult));
123         ch->name = mName;
124     }
125 }
126 
onSurfaceFrameCreated(const std::shared_ptr<frametimeline::SurfaceFrame> & surfaceFrame)127 void BufferStateLayer::onSurfaceFrameCreated(
128         const std::shared_ptr<frametimeline::SurfaceFrame>& surfaceFrame) {
129     while (mPendingJankClassifications.size() >= kPendingClassificationMaxSurfaceFrames) {
130         // Too many SurfaceFrames pending classification. The front of the deque is probably not
131         // tracked by FrameTimeline and will never be presented. This will only result in a memory
132         // leak.
133         ALOGW("Removing the front of pending jank deque from layer - %s to prevent memory leak",
134               mName.c_str());
135         std::string miniDump = mPendingJankClassifications.front()->miniDump();
136         ALOGD("Head SurfaceFrame mini dump\n%s", miniDump.c_str());
137         mPendingJankClassifications.pop_front();
138     }
139     mPendingJankClassifications.emplace_back(surfaceFrame);
140 }
141 
releasePendingBuffer(nsecs_t dequeueReadyTime)142 void BufferStateLayer::releasePendingBuffer(nsecs_t dequeueReadyTime) {
143     for (const auto& handle : mDrawingState.callbackHandles) {
144         handle->transformHint = mTransformHint;
145         handle->dequeueReadyTime = dequeueReadyTime;
146         handle->currentMaxAcquiredBufferCount =
147                 mFlinger->getMaxAcquiredBufferCountForCurrentRefreshRate(mOwnerUid);
148     }
149 
150     for (auto& handle : mDrawingState.callbackHandles) {
151         if (handle->releasePreviousBuffer &&
152             mDrawingState.releaseBufferEndpoint == handle->listener) {
153             handle->previousReleaseCallbackId = mPreviousReleaseCallbackId;
154             break;
155         }
156     }
157 
158     std::vector<JankData> jankData;
159     jankData.reserve(mPendingJankClassifications.size());
160     while (!mPendingJankClassifications.empty()
161             && mPendingJankClassifications.front()->getJankType()) {
162         std::shared_ptr<frametimeline::SurfaceFrame> surfaceFrame =
163                 mPendingJankClassifications.front();
164         mPendingJankClassifications.pop_front();
165         jankData.emplace_back(
166                 JankData(surfaceFrame->getToken(), surfaceFrame->getJankType().value()));
167     }
168 
169     mFlinger->getTransactionCallbackInvoker().addCallbackHandles(
170             mDrawingState.callbackHandles, jankData);
171 
172     sp<Fence> releaseFence = Fence::NO_FENCE;
173     for (auto& handle : mDrawingState.callbackHandles) {
174         if (handle->releasePreviousBuffer &&
175             mDrawingState.releaseBufferEndpoint == handle->listener) {
176             releaseFence =
177                     handle->previousReleaseFence ? handle->previousReleaseFence : Fence::NO_FENCE;
178             break;
179         }
180     }
181 
182     mDrawingState.callbackHandles = {};
183 }
184 
finalizeFrameEventHistory(const std::shared_ptr<FenceTime> & glDoneFence,const CompositorTiming & compositorTiming)185 void BufferStateLayer::finalizeFrameEventHistory(const std::shared_ptr<FenceTime>& glDoneFence,
186                                                  const CompositorTiming& compositorTiming) {
187     for (const auto& handle : mDrawingState.callbackHandles) {
188         handle->gpuCompositionDoneFence = glDoneFence;
189         handle->compositorTiming = compositorTiming;
190     }
191 }
192 
willPresentCurrentTransaction() const193 bool BufferStateLayer::willPresentCurrentTransaction() const {
194     // Returns true if the most recent Transaction applied to CurrentState will be presented.
195     return (getSidebandStreamChanged() || getAutoRefresh() ||
196             (mDrawingState.modified &&
197              (mDrawingState.buffer != nullptr || mDrawingState.bgColorLayer != nullptr)));
198 }
199 
getCrop(const Layer::State & s) const200 Rect BufferStateLayer::getCrop(const Layer::State& s) const {
201     return s.crop;
202 }
203 
setTransform(uint32_t transform)204 bool BufferStateLayer::setTransform(uint32_t transform) {
205     if (mDrawingState.bufferTransform == transform) return false;
206     mDrawingState.bufferTransform = transform;
207     mDrawingState.modified = true;
208     setTransactionFlags(eTransactionNeeded);
209     return true;
210 }
211 
setTransformToDisplayInverse(bool transformToDisplayInverse)212 bool BufferStateLayer::setTransformToDisplayInverse(bool transformToDisplayInverse) {
213     if (mDrawingState.transformToDisplayInverse == transformToDisplayInverse) return false;
214     mDrawingState.sequence++;
215     mDrawingState.transformToDisplayInverse = transformToDisplayInverse;
216     mDrawingState.modified = true;
217     setTransactionFlags(eTransactionNeeded);
218     return true;
219 }
220 
setCrop(const Rect & crop)221 bool BufferStateLayer::setCrop(const Rect& crop) {
222     if (mDrawingState.crop == crop) return false;
223     mDrawingState.sequence++;
224     mDrawingState.crop = crop;
225 
226     mDrawingState.modified = true;
227     setTransactionFlags(eTransactionNeeded);
228     return true;
229 }
230 
setBufferCrop(const Rect & bufferCrop)231 bool BufferStateLayer::setBufferCrop(const Rect& bufferCrop) {
232     if (mDrawingState.bufferCrop == bufferCrop) return false;
233 
234     mDrawingState.sequence++;
235     mDrawingState.bufferCrop = bufferCrop;
236 
237     mDrawingState.modified = true;
238     setTransactionFlags(eTransactionNeeded);
239     return true;
240 }
241 
setDestinationFrame(const Rect & destinationFrame)242 bool BufferStateLayer::setDestinationFrame(const Rect& destinationFrame) {
243     if (mDrawingState.destinationFrame == destinationFrame) return false;
244 
245     mDrawingState.sequence++;
246     mDrawingState.destinationFrame = destinationFrame;
247 
248     mDrawingState.modified = true;
249     setTransactionFlags(eTransactionNeeded);
250     return true;
251 }
252 
assignTransform(ui::Transform * dst,ui::Transform & from)253 static bool assignTransform(ui::Transform* dst, ui::Transform& from) {
254     if (*dst == from) {
255         return false;
256     }
257     *dst = from;
258     return true;
259 }
260 
261 // Translate destination frame into scale and position. If a destination frame is not set, use the
262 // provided scale and position
updateGeometry()263 bool BufferStateLayer::updateGeometry() {
264     if ((mDrawingState.flags & layer_state_t::eIgnoreDestinationFrame) ||
265         mDrawingState.destinationFrame.isEmpty()) {
266         // If destination frame is not set, use the requested transform set via
267         // BufferStateLayer::setPosition and BufferStateLayer::setMatrix.
268         return assignTransform(&mDrawingState.transform, mRequestedTransform);
269     }
270 
271     Rect destRect = mDrawingState.destinationFrame;
272     int32_t destW = destRect.width();
273     int32_t destH = destRect.height();
274     if (destRect.left < 0) {
275         destRect.left = 0;
276         destRect.right = destW;
277     }
278     if (destRect.top < 0) {
279         destRect.top = 0;
280         destRect.bottom = destH;
281     }
282 
283     if (!mDrawingState.buffer) {
284         ui::Transform t;
285         t.set(destRect.left, destRect.top);
286         return assignTransform(&mDrawingState.transform, t);
287     }
288 
289     uint32_t bufferWidth = mDrawingState.buffer->getWidth();
290     uint32_t bufferHeight = mDrawingState.buffer->getHeight();
291     // Undo any transformations on the buffer.
292     if (mDrawingState.bufferTransform & ui::Transform::ROT_90) {
293         std::swap(bufferWidth, bufferHeight);
294     }
295     uint32_t invTransform = DisplayDevice::getPrimaryDisplayRotationFlags();
296     if (mDrawingState.transformToDisplayInverse) {
297         if (invTransform & ui::Transform::ROT_90) {
298             std::swap(bufferWidth, bufferHeight);
299         }
300     }
301 
302     float sx = destW / static_cast<float>(bufferWidth);
303     float sy = destH / static_cast<float>(bufferHeight);
304     ui::Transform t;
305     t.set(sx, 0, 0, sy);
306     t.set(destRect.left, destRect.top);
307     return assignTransform(&mDrawingState.transform, t);
308 }
309 
setMatrix(const layer_state_t::matrix22_t & matrix)310 bool BufferStateLayer::setMatrix(const layer_state_t::matrix22_t& matrix) {
311     if (mRequestedTransform.dsdx() == matrix.dsdx && mRequestedTransform.dtdy() == matrix.dtdy &&
312         mRequestedTransform.dtdx() == matrix.dtdx && mRequestedTransform.dsdy() == matrix.dsdy) {
313         return false;
314     }
315 
316     ui::Transform t;
317     t.set(matrix.dsdx, matrix.dtdy, matrix.dtdx, matrix.dsdy);
318 
319     mRequestedTransform.set(matrix.dsdx, matrix.dtdy, matrix.dtdx, matrix.dsdy);
320 
321     mDrawingState.sequence++;
322     mDrawingState.modified = true;
323     setTransactionFlags(eTransactionNeeded);
324 
325     return true;
326 }
327 
setPosition(float x,float y)328 bool BufferStateLayer::setPosition(float x, float y) {
329     if (mRequestedTransform.tx() == x && mRequestedTransform.ty() == y) {
330         return false;
331     }
332 
333     mRequestedTransform.set(x, y);
334 
335     mDrawingState.sequence++;
336     mDrawingState.modified = true;
337     setTransactionFlags(eTransactionNeeded);
338 
339     return true;
340 }
341 
setBuffer(std::shared_ptr<renderengine::ExternalTexture> & buffer,const BufferData & bufferData,nsecs_t postTime,nsecs_t desiredPresentTime,bool isAutoTimestamp,std::optional<nsecs_t> dequeueTime,const FrameTimelineInfo & info)342 bool BufferStateLayer::setBuffer(std::shared_ptr<renderengine::ExternalTexture>& buffer,
343                                  const BufferData& bufferData, nsecs_t postTime,
344                                  nsecs_t desiredPresentTime, bool isAutoTimestamp,
345                                  std::optional<nsecs_t> dequeueTime,
346                                  const FrameTimelineInfo& info) {
347     ATRACE_CALL();
348 
349     if (!buffer) {
350         return false;
351     }
352 
353     const bool frameNumberChanged =
354             bufferData.flags.test(BufferData::BufferDataChange::frameNumberChanged);
355     const uint64_t frameNumber =
356             frameNumberChanged ? bufferData.frameNumber : mDrawingState.frameNumber + 1;
357 
358     if (mDrawingState.buffer) {
359         mReleasePreviousBuffer = true;
360         if (!mBufferInfo.mBuffer ||
361             (!mDrawingState.buffer->hasSameBuffer(*mBufferInfo.mBuffer) ||
362              mDrawingState.frameNumber != mBufferInfo.mFrameNumber)) {
363             // If mDrawingState has a buffer, and we are about to update again
364             // before swapping to drawing state, then the first buffer will be
365             // dropped and we should decrement the pending buffer count and
366             // call any release buffer callbacks if set.
367             callReleaseBufferCallback(mDrawingState.releaseBufferListener,
368                                       mDrawingState.buffer->getBuffer(), mDrawingState.frameNumber,
369                                       mDrawingState.acquireFence,
370                                       mFlinger->getMaxAcquiredBufferCountForCurrentRefreshRate(
371                                               mOwnerUid));
372             decrementPendingBufferCount();
373             if (mDrawingState.bufferSurfaceFrameTX != nullptr &&
374                 mDrawingState.bufferSurfaceFrameTX->getPresentState() != PresentState::Presented) {
375               addSurfaceFrameDroppedForBuffer(mDrawingState.bufferSurfaceFrameTX);
376               mDrawingState.bufferSurfaceFrameTX.reset();
377             }
378         } else if (EARLY_RELEASE_ENABLED && mLastClientCompositionFence != nullptr) {
379             callReleaseBufferCallback(mDrawingState.releaseBufferListener,
380                                       mDrawingState.buffer->getBuffer(), mDrawingState.frameNumber,
381                                       mLastClientCompositionFence,
382                                       mFlinger->getMaxAcquiredBufferCountForCurrentRefreshRate(
383                                               mOwnerUid));
384             mLastClientCompositionFence = nullptr;
385         }
386     }
387 
388     mDrawingState.frameNumber = frameNumber;
389     mDrawingState.releaseBufferListener = bufferData.releaseBufferListener;
390     mDrawingState.buffer = std::move(buffer);
391     mDrawingState.clientCacheId = bufferData.cachedBuffer;
392 
393     mDrawingState.acquireFence = bufferData.flags.test(BufferData::BufferDataChange::fenceChanged)
394             ? bufferData.acquireFence
395             : Fence::NO_FENCE;
396     mDrawingState.acquireFenceTime = std::make_unique<FenceTime>(mDrawingState.acquireFence);
397     if (mDrawingState.acquireFenceTime->getSignalTime() == Fence::SIGNAL_TIME_PENDING) {
398         // We latched this buffer unsiganled, so we need to pass the acquire fence
399         // on the callback instead of just the acquire time, since it's unknown at
400         // this point.
401         mCallbackHandleAcquireTimeOrFence = mDrawingState.acquireFence;
402     } else {
403         mCallbackHandleAcquireTimeOrFence = mDrawingState.acquireFenceTime->getSignalTime();
404     }
405 
406     mDrawingState.modified = true;
407     setTransactionFlags(eTransactionNeeded);
408 
409     const int32_t layerId = getSequence();
410     mFlinger->mTimeStats->setPostTime(layerId, mDrawingState.frameNumber, getName().c_str(),
411                                       mOwnerUid, postTime, getGameMode());
412     mDrawingState.desiredPresentTime = desiredPresentTime;
413     mDrawingState.isAutoTimestamp = isAutoTimestamp;
414 
415     const nsecs_t presentTime = [&] {
416         if (!isAutoTimestamp) return desiredPresentTime;
417 
418         const auto prediction =
419                 mFlinger->mFrameTimeline->getTokenManager()->getPredictionsForToken(info.vsyncId);
420         if (prediction.has_value()) return prediction->presentTime;
421 
422         return static_cast<nsecs_t>(0);
423     }();
424 
425     using LayerUpdateType = scheduler::LayerHistory::LayerUpdateType;
426     mFlinger->mScheduler->recordLayerHistory(this, presentTime, LayerUpdateType::Buffer);
427 
428     setFrameTimelineVsyncForBufferTransaction(info, postTime);
429 
430     if (dequeueTime && *dequeueTime != 0) {
431         const uint64_t bufferId = mDrawingState.buffer->getId();
432         mFlinger->mFrameTracer->traceNewLayer(layerId, getName().c_str());
433         mFlinger->mFrameTracer->traceTimestamp(layerId, bufferId, frameNumber, *dequeueTime,
434                                                FrameTracer::FrameEvent::DEQUEUE);
435         mFlinger->mFrameTracer->traceTimestamp(layerId, bufferId, frameNumber, postTime,
436                                                FrameTracer::FrameEvent::QUEUE);
437     }
438 
439     mDrawingState.width = mDrawingState.buffer->getWidth();
440     mDrawingState.height = mDrawingState.buffer->getHeight();
441     mDrawingState.releaseBufferEndpoint = bufferData.releaseBufferEndpoint;
442     return true;
443 }
444 
setDataspace(ui::Dataspace dataspace)445 bool BufferStateLayer::setDataspace(ui::Dataspace dataspace) {
446     if (mDrawingState.dataspace == dataspace) return false;
447     mDrawingState.dataspace = dataspace;
448     mDrawingState.modified = true;
449     setTransactionFlags(eTransactionNeeded);
450     return true;
451 }
452 
setHdrMetadata(const HdrMetadata & hdrMetadata)453 bool BufferStateLayer::setHdrMetadata(const HdrMetadata& hdrMetadata) {
454     if (mDrawingState.hdrMetadata == hdrMetadata) return false;
455     mDrawingState.hdrMetadata = hdrMetadata;
456     mDrawingState.modified = true;
457     setTransactionFlags(eTransactionNeeded);
458     return true;
459 }
460 
setSurfaceDamageRegion(const Region & surfaceDamage)461 bool BufferStateLayer::setSurfaceDamageRegion(const Region& surfaceDamage) {
462     mDrawingState.surfaceDamageRegion = surfaceDamage;
463     mDrawingState.modified = true;
464     setTransactionFlags(eTransactionNeeded);
465     return true;
466 }
467 
setApi(int32_t api)468 bool BufferStateLayer::setApi(int32_t api) {
469     if (mDrawingState.api == api) return false;
470     mDrawingState.api = api;
471     mDrawingState.modified = true;
472     setTransactionFlags(eTransactionNeeded);
473     return true;
474 }
475 
setSidebandStream(const sp<NativeHandle> & sidebandStream)476 bool BufferStateLayer::setSidebandStream(const sp<NativeHandle>& sidebandStream) {
477     if (mDrawingState.sidebandStream == sidebandStream) return false;
478 
479     if (mDrawingState.sidebandStream != nullptr && sidebandStream == nullptr) {
480         mFlinger->mTunnelModeEnabledReporter->decrementTunnelModeCount();
481     } else if (sidebandStream != nullptr) {
482         mFlinger->mTunnelModeEnabledReporter->incrementTunnelModeCount();
483     }
484 
485     mDrawingState.sidebandStream = sidebandStream;
486     mDrawingState.modified = true;
487     setTransactionFlags(eTransactionNeeded);
488     if (!mSidebandStreamChanged.exchange(true)) {
489         // mSidebandStreamChanged was false
490         mFlinger->onLayerUpdate();
491     }
492     return true;
493 }
494 
setTransactionCompletedListeners(const std::vector<sp<CallbackHandle>> & handles)495 bool BufferStateLayer::setTransactionCompletedListeners(
496         const std::vector<sp<CallbackHandle>>& handles) {
497     // If there is no handle, we will not send a callback so reset mReleasePreviousBuffer and return
498     if (handles.empty()) {
499         mReleasePreviousBuffer = false;
500         return false;
501     }
502 
503     const bool willPresent = willPresentCurrentTransaction();
504 
505     for (const auto& handle : handles) {
506         // If this transaction set a buffer on this layer, release its previous buffer
507         handle->releasePreviousBuffer = mReleasePreviousBuffer;
508 
509         // If this layer will be presented in this frame
510         if (willPresent) {
511             // If this transaction set an acquire fence on this layer, set its acquire time
512             handle->acquireTimeOrFence = mCallbackHandleAcquireTimeOrFence;
513             handle->frameNumber = mDrawingState.frameNumber;
514 
515             // Store so latched time and release fence can be set
516             mDrawingState.callbackHandles.push_back(handle);
517 
518         } else { // If this layer will NOT need to be relatched and presented this frame
519             // Notify the transaction completed thread this handle is done
520             mFlinger->getTransactionCallbackInvoker().registerUnpresentedCallbackHandle(handle);
521         }
522     }
523 
524     mReleasePreviousBuffer = false;
525     mCallbackHandleAcquireTimeOrFence = -1;
526 
527     return willPresent;
528 }
529 
setTransparentRegionHint(const Region & transparent)530 bool BufferStateLayer::setTransparentRegionHint(const Region& transparent) {
531     mDrawingState.sequence++;
532     mDrawingState.transparentRegionHint = transparent;
533     mDrawingState.modified = true;
534     setTransactionFlags(eTransactionNeeded);
535     return true;
536 }
537 
getBufferSize(const State &) const538 Rect BufferStateLayer::getBufferSize(const State& /*s*/) const {
539     // for buffer state layers we use the display frame size as the buffer size.
540 
541     if (mBufferInfo.mBuffer == nullptr) {
542         return Rect::INVALID_RECT;
543     }
544 
545     uint32_t bufWidth = mBufferInfo.mBuffer->getWidth();
546     uint32_t bufHeight = mBufferInfo.mBuffer->getHeight();
547 
548     // Undo any transformations on the buffer and return the result.
549     if (mBufferInfo.mTransform & ui::Transform::ROT_90) {
550         std::swap(bufWidth, bufHeight);
551     }
552 
553     if (getTransformToDisplayInverse()) {
554         uint32_t invTransform = DisplayDevice::getPrimaryDisplayRotationFlags();
555         if (invTransform & ui::Transform::ROT_90) {
556             std::swap(bufWidth, bufHeight);
557         }
558     }
559 
560     return Rect(0, 0, static_cast<int32_t>(bufWidth), static_cast<int32_t>(bufHeight));
561 }
562 
computeSourceBounds(const FloatRect & parentBounds) const563 FloatRect BufferStateLayer::computeSourceBounds(const FloatRect& parentBounds) const {
564     if (mBufferInfo.mBuffer == nullptr) {
565         return parentBounds;
566     }
567 
568     return getBufferSize(getDrawingState()).toFloatRect();
569 }
570 
571 // -----------------------------------------------------------------------
572 
573 // -----------------------------------------------------------------------
574 // Interface implementation for BufferLayer
575 // -----------------------------------------------------------------------
fenceHasSignaled() const576 bool BufferStateLayer::fenceHasSignaled() const {
577     if (SurfaceFlinger::enableLatchUnsignaledConfig != LatchUnsignaledConfig::Disabled) {
578         return true;
579     }
580 
581     const bool fenceSignaled =
582             getDrawingState().acquireFence->getStatus() == Fence::Status::Signaled;
583     if (!fenceSignaled) {
584         mFlinger->mTimeStats->incrementLatchSkipped(getSequence(),
585                                                     TimeStats::LatchSkipReason::LateAcquire);
586     }
587 
588     return fenceSignaled;
589 }
590 
framePresentTimeIsCurrent(nsecs_t expectedPresentTime) const591 bool BufferStateLayer::framePresentTimeIsCurrent(nsecs_t expectedPresentTime) const {
592     if (!hasFrameUpdate() || isRemovedFromCurrentState()) {
593         return true;
594     }
595 
596     return mDrawingState.isAutoTimestamp || mDrawingState.desiredPresentTime <= expectedPresentTime;
597 }
598 
onPreComposition(nsecs_t refreshStartTime)599 bool BufferStateLayer::onPreComposition(nsecs_t refreshStartTime) {
600     for (const auto& handle : mDrawingState.callbackHandles) {
601         handle->refreshStartTime = refreshStartTime;
602     }
603     return BufferLayer::onPreComposition(refreshStartTime);
604 }
605 
setAutoRefresh(bool autoRefresh)606 void BufferStateLayer::setAutoRefresh(bool autoRefresh) {
607     mDrawingState.autoRefresh = autoRefresh;
608 }
609 
latchSidebandStream(bool & recomputeVisibleRegions)610 bool BufferStateLayer::latchSidebandStream(bool& recomputeVisibleRegions) {
611     // We need to update the sideband stream if the layer has both a buffer and a sideband stream.
612     editCompositionState()->sidebandStreamHasFrame = hasFrameUpdate() && mSidebandStream.get();
613 
614     if (mSidebandStreamChanged.exchange(false)) {
615         const State& s(getDrawingState());
616         // mSidebandStreamChanged was true
617         mSidebandStream = s.sidebandStream;
618         editCompositionState()->sidebandStream = mSidebandStream;
619         if (mSidebandStream != nullptr) {
620             setTransactionFlags(eTransactionNeeded);
621             mFlinger->setTransactionFlags(eTraversalNeeded);
622         }
623         recomputeVisibleRegions = true;
624 
625         return true;
626     }
627     return false;
628 }
629 
hasFrameUpdate() const630 bool BufferStateLayer::hasFrameUpdate() const {
631     const State& c(getDrawingState());
632     return (mDrawingStateModified || mDrawingState.modified) && (c.buffer != nullptr || c.bgColorLayer != nullptr);
633 }
634 
updateTexImage(bool &,nsecs_t latchTime,nsecs_t)635 status_t BufferStateLayer::updateTexImage(bool& /*recomputeVisibleRegions*/, nsecs_t latchTime,
636                                           nsecs_t /*expectedPresentTime*/) {
637     const State& s(getDrawingState());
638 
639     if (!s.buffer) {
640         if (s.bgColorLayer) {
641             for (auto& handle : mDrawingState.callbackHandles) {
642                 handle->latchTime = latchTime;
643             }
644         }
645         return NO_ERROR;
646     }
647 
648     for (auto& handle : mDrawingState.callbackHandles) {
649         if (handle->frameNumber == mDrawingState.frameNumber) {
650             handle->latchTime = latchTime;
651         }
652     }
653 
654     const int32_t layerId = getSequence();
655     const uint64_t bufferId = mDrawingState.buffer->getId();
656     const uint64_t frameNumber = mDrawingState.frameNumber;
657     const auto acquireFence = std::make_shared<FenceTime>(mDrawingState.acquireFence);
658     mFlinger->mTimeStats->setAcquireFence(layerId, frameNumber, acquireFence);
659     mFlinger->mTimeStats->setLatchTime(layerId, frameNumber, latchTime);
660 
661     mFlinger->mFrameTracer->traceFence(layerId, bufferId, frameNumber, acquireFence,
662                                        FrameTracer::FrameEvent::ACQUIRE_FENCE);
663     mFlinger->mFrameTracer->traceTimestamp(layerId, bufferId, frameNumber, latchTime,
664                                            FrameTracer::FrameEvent::LATCH);
665 
666     auto& bufferSurfaceFrame = mDrawingState.bufferSurfaceFrameTX;
667     if (bufferSurfaceFrame != nullptr &&
668         bufferSurfaceFrame->getPresentState() != PresentState::Presented) {
669         // Update only if the bufferSurfaceFrame wasn't already presented. A Presented
670         // bufferSurfaceFrame could be seen here if a pending state was applied successfully and we
671         // are processing the next state.
672         addSurfaceFramePresentedForBuffer(bufferSurfaceFrame,
673                                           mDrawingState.acquireFenceTime->getSignalTime(),
674                                           latchTime);
675         mDrawingState.bufferSurfaceFrameTX.reset();
676     }
677 
678     std::deque<sp<CallbackHandle>> remainingHandles;
679     mFlinger->getTransactionCallbackInvoker()
680             .addOnCommitCallbackHandles(mDrawingState.callbackHandles, remainingHandles);
681     mDrawingState.callbackHandles = remainingHandles;
682 
683     mDrawingStateModified = false;
684 
685     return NO_ERROR;
686 }
687 
updateActiveBuffer()688 status_t BufferStateLayer::updateActiveBuffer() {
689     const State& s(getDrawingState());
690 
691     if (s.buffer == nullptr) {
692         return BAD_VALUE;
693     }
694 
695     if (!mBufferInfo.mBuffer || !s.buffer->hasSameBuffer(*mBufferInfo.mBuffer)) {
696         decrementPendingBufferCount();
697     }
698 
699     mPreviousReleaseCallbackId = {getCurrentBufferId(), mBufferInfo.mFrameNumber};
700     mBufferInfo.mBuffer = s.buffer;
701     mBufferInfo.mFence = s.acquireFence;
702     mBufferInfo.mFrameNumber = s.frameNumber;
703 
704     return NO_ERROR;
705 }
706 
updateFrameNumber()707 status_t BufferStateLayer::updateFrameNumber() {
708     // TODO(marissaw): support frame history events
709     mPreviousFrameNumber = mCurrentFrameNumber;
710     mCurrentFrameNumber = mDrawingState.frameNumber;
711     return NO_ERROR;
712 }
713 
bufferErased(const client_cache_t & clientCacheId)714 void BufferStateLayer::HwcSlotGenerator::bufferErased(const client_cache_t& clientCacheId) {
715     std::lock_guard lock(mMutex);
716     if (!clientCacheId.isValid()) {
717         ALOGE("invalid process, failed to erase buffer");
718         return;
719     }
720     eraseBufferLocked(clientCacheId);
721 }
722 
getHwcCacheSlot(const client_cache_t & clientCacheId)723 int BufferStateLayer::HwcSlotGenerator::getHwcCacheSlot(const client_cache_t& clientCacheId) {
724     std::lock_guard<std::mutex> lock(mMutex);
725     auto itr = mCachedBuffers.find(clientCacheId);
726     if (itr == mCachedBuffers.end()) {
727         return addCachedBuffer(clientCacheId);
728     }
729     auto& [hwcCacheSlot, counter] = itr->second;
730     counter = mCounter++;
731     return hwcCacheSlot;
732 }
733 
addCachedBuffer(const client_cache_t & clientCacheId)734 int BufferStateLayer::HwcSlotGenerator::addCachedBuffer(const client_cache_t& clientCacheId)
735         REQUIRES(mMutex) {
736     if (!clientCacheId.isValid()) {
737         ALOGE("invalid process, returning invalid slot");
738         return BufferQueue::INVALID_BUFFER_SLOT;
739     }
740 
741     ClientCache::getInstance().registerErasedRecipient(clientCacheId, wp<ErasedRecipient>(this));
742 
743     int hwcCacheSlot = getFreeHwcCacheSlot();
744     mCachedBuffers[clientCacheId] = {hwcCacheSlot, mCounter++};
745     return hwcCacheSlot;
746 }
747 
getFreeHwcCacheSlot()748 int BufferStateLayer::HwcSlotGenerator::getFreeHwcCacheSlot() REQUIRES(mMutex) {
749     if (mFreeHwcCacheSlots.empty()) {
750         evictLeastRecentlyUsed();
751     }
752 
753     int hwcCacheSlot = mFreeHwcCacheSlots.top();
754     mFreeHwcCacheSlots.pop();
755     return hwcCacheSlot;
756 }
757 
evictLeastRecentlyUsed()758 void BufferStateLayer::HwcSlotGenerator::evictLeastRecentlyUsed() REQUIRES(mMutex) {
759     uint64_t minCounter = UINT_MAX;
760     client_cache_t minClientCacheId = {};
761     for (const auto& [clientCacheId, slotCounter] : mCachedBuffers) {
762         const auto& [hwcCacheSlot, counter] = slotCounter;
763         if (counter < minCounter) {
764             minCounter = counter;
765             minClientCacheId = clientCacheId;
766         }
767     }
768     eraseBufferLocked(minClientCacheId);
769 
770     ClientCache::getInstance().unregisterErasedRecipient(minClientCacheId, this);
771 }
772 
eraseBufferLocked(const client_cache_t & clientCacheId)773 void BufferStateLayer::HwcSlotGenerator::eraseBufferLocked(const client_cache_t& clientCacheId)
774         REQUIRES(mMutex) {
775     auto itr = mCachedBuffers.find(clientCacheId);
776     if (itr == mCachedBuffers.end()) {
777         return;
778     }
779     auto& [hwcCacheSlot, counter] = itr->second;
780 
781     // TODO send to hwc cache and resources
782 
783     mFreeHwcCacheSlots.push(hwcCacheSlot);
784     mCachedBuffers.erase(clientCacheId);
785 }
786 
gatherBufferInfo()787 void BufferStateLayer::gatherBufferInfo() {
788     BufferLayer::gatherBufferInfo();
789 
790     const State& s(getDrawingState());
791     mBufferInfo.mDesiredPresentTime = s.desiredPresentTime;
792     mBufferInfo.mFenceTime = std::make_shared<FenceTime>(s.acquireFence);
793     mBufferInfo.mFence = s.acquireFence;
794     mBufferInfo.mTransform = s.bufferTransform;
795     auto lastDataspace = mBufferInfo.mDataspace;
796     mBufferInfo.mDataspace = translateDataspace(s.dataspace);
797     if (lastDataspace != mBufferInfo.mDataspace) {
798         mFlinger->mSomeDataspaceChanged = true;
799     }
800     mBufferInfo.mCrop = computeBufferCrop(s);
801     mBufferInfo.mScaleMode = NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW;
802     mBufferInfo.mSurfaceDamage = s.surfaceDamageRegion;
803     mBufferInfo.mHdrMetadata = s.hdrMetadata;
804     mBufferInfo.mApi = s.api;
805     mBufferInfo.mTransformToDisplayInverse = s.transformToDisplayInverse;
806     mBufferInfo.mBufferSlot = mHwcSlotGenerator->getHwcCacheSlot(s.clientCacheId);
807 }
808 
getEffectiveScalingMode() const809 uint32_t BufferStateLayer::getEffectiveScalingMode() const {
810    return NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW;
811 }
812 
computeBufferCrop(const State & s)813 Rect BufferStateLayer::computeBufferCrop(const State& s) {
814     if (s.buffer && !s.bufferCrop.isEmpty()) {
815         Rect bufferCrop;
816         s.buffer->getBounds().intersect(s.bufferCrop, &bufferCrop);
817         return bufferCrop;
818     } else if (s.buffer) {
819         return s.buffer->getBounds();
820     } else {
821         return s.bufferCrop;
822     }
823 }
824 
createClone()825 sp<Layer> BufferStateLayer::createClone() {
826     LayerCreationArgs args(mFlinger.get(), nullptr, mName + " (Mirror)", 0, LayerMetadata());
827     args.textureName = mTextureName;
828     sp<BufferStateLayer> layer = mFlinger->getFactory().createBufferStateLayer(args);
829     layer->mHwcSlotGenerator = mHwcSlotGenerator;
830     layer->setInitialValuesForClone(this);
831     return layer;
832 }
833 
bufferNeedsFiltering() const834 bool BufferStateLayer::bufferNeedsFiltering() const {
835     const State& s(getDrawingState());
836     if (!s.buffer) {
837         return false;
838     }
839 
840     int32_t bufferWidth = static_cast<int32_t>(s.buffer->getWidth());
841     int32_t bufferHeight = static_cast<int32_t>(s.buffer->getHeight());
842 
843     // Undo any transformations on the buffer and return the result.
844     if (s.bufferTransform & ui::Transform::ROT_90) {
845         std::swap(bufferWidth, bufferHeight);
846     }
847 
848     if (s.transformToDisplayInverse) {
849         uint32_t invTransform = DisplayDevice::getPrimaryDisplayRotationFlags();
850         if (invTransform & ui::Transform::ROT_90) {
851             std::swap(bufferWidth, bufferHeight);
852         }
853     }
854 
855     const Rect layerSize{getBounds()};
856     return layerSize.width() != bufferWidth || layerSize.height() != bufferHeight;
857 }
858 
decrementPendingBufferCount()859 void BufferStateLayer::decrementPendingBufferCount() {
860     int32_t pendingBuffers = --mPendingBufferTransactions;
861     tracePendingBufferCount(pendingBuffers);
862 }
863 
tracePendingBufferCount(int32_t pendingBuffers)864 void BufferStateLayer::tracePendingBufferCount(int32_t pendingBuffers) {
865     ATRACE_INT(mBlastTransactionName.c_str(), pendingBuffers);
866 }
867 
868 
869 /*
870  * We don't want to send the layer's transform to input, but rather the
871  * parent's transform. This is because BufferStateLayer's transform is
872  * information about how the buffer is placed on screen. The parent's
873  * transform makes more sense to send since it's information about how the
874  * layer is placed on screen. This transform is used by input to determine
875  * how to go from screen space back to window space.
876  */
getInputTransform() const877 ui::Transform BufferStateLayer::getInputTransform() const {
878     sp<Layer> parent = mDrawingParent.promote();
879     if (parent == nullptr) {
880         return ui::Transform();
881     }
882 
883     return parent->getTransform();
884 }
885 
886 /**
887  * Similar to getInputTransform, we need to update the bounds to include the transform.
888  * This is because bounds for BSL doesn't include buffer transform, where the input assumes
889  * that's already included.
890  */
getInputBounds() const891 Rect BufferStateLayer::getInputBounds() const {
892     Rect bufferBounds = getCroppedBufferSize(getDrawingState());
893     if (mDrawingState.transform.getType() == ui::Transform::IDENTITY || !bufferBounds.isValid()) {
894         return bufferBounds;
895     }
896     return mDrawingState.transform.transform(bufferBounds);
897 }
898 
simpleBufferUpdate(const layer_state_t & s) const899 bool BufferStateLayer::simpleBufferUpdate(const layer_state_t& s) const {
900     const uint64_t requiredFlags = layer_state_t::eBufferChanged;
901 
902     const uint64_t deniedFlags = layer_state_t::eProducerDisconnect | layer_state_t::eLayerChanged |
903             layer_state_t::eRelativeLayerChanged | layer_state_t::eTransparentRegionChanged |
904             layer_state_t::eFlagsChanged | layer_state_t::eBlurRegionsChanged |
905             layer_state_t::eLayerStackChanged | layer_state_t::eAutoRefreshChanged |
906             layer_state_t::eReparent;
907 
908     const uint64_t allowedFlags = layer_state_t::eHasListenerCallbacksChanged |
909             layer_state_t::eFrameRateSelectionPriority | layer_state_t::eFrameRateChanged |
910             layer_state_t::eSurfaceDamageRegionChanged | layer_state_t::eApiChanged |
911             layer_state_t::eMetadataChanged | layer_state_t::eDropInputModeChanged |
912             layer_state_t::eInputInfoChanged;
913 
914     if ((s.what & requiredFlags) != requiredFlags) {
915         ALOGV("%s: false [missing required flags 0x%" PRIx64 "]", __func__,
916               (s.what | requiredFlags) & ~s.what);
917         return false;
918     }
919 
920     if (s.what & deniedFlags) {
921         ALOGV("%s: false [has denied flags 0x%" PRIx64 "]", __func__, s.what & deniedFlags);
922         return false;
923     }
924 
925     if (s.what & allowedFlags) {
926         ALOGV("%s: [has allowed flags 0x%" PRIx64 "]", __func__, s.what & allowedFlags);
927     }
928 
929     if (s.what & layer_state_t::ePositionChanged) {
930         if (mRequestedTransform.tx() != s.x || mRequestedTransform.ty() != s.y) {
931             ALOGV("%s: false [ePositionChanged changed]", __func__);
932             return false;
933         }
934     }
935 
936     if (s.what & layer_state_t::eAlphaChanged) {
937         if (mDrawingState.color.a != s.alpha) {
938             ALOGV("%s: false [eAlphaChanged changed]", __func__);
939             return false;
940         }
941     }
942 
943     if (s.what & layer_state_t::eColorTransformChanged) {
944         if (mDrawingState.colorTransform != s.colorTransform) {
945             ALOGV("%s: false [eColorTransformChanged changed]", __func__);
946             return false;
947         }
948     }
949 
950     if (s.what & layer_state_t::eBackgroundColorChanged) {
951         if (mDrawingState.bgColorLayer || s.bgColorAlpha != 0) {
952             ALOGV("%s: false [eBackgroundColorChanged changed]", __func__);
953             return false;
954         }
955     }
956 
957     if (s.what & layer_state_t::eMatrixChanged) {
958         if (mRequestedTransform.dsdx() != s.matrix.dsdx ||
959             mRequestedTransform.dtdy() != s.matrix.dtdy ||
960             mRequestedTransform.dtdx() != s.matrix.dtdx ||
961             mRequestedTransform.dsdy() != s.matrix.dsdy) {
962             ALOGV("%s: false [eMatrixChanged changed]", __func__);
963             return false;
964         }
965     }
966 
967     if (s.what & layer_state_t::eCornerRadiusChanged) {
968         if (mDrawingState.cornerRadius != s.cornerRadius) {
969             ALOGV("%s: false [eCornerRadiusChanged changed]", __func__);
970             return false;
971         }
972     }
973 
974     if (s.what & layer_state_t::eBackgroundBlurRadiusChanged) {
975         if (mDrawingState.backgroundBlurRadius != static_cast<int>(s.backgroundBlurRadius)) {
976             ALOGV("%s: false [eBackgroundBlurRadiusChanged changed]", __func__);
977             return false;
978         }
979     }
980 
981     if (s.what & layer_state_t::eTransformChanged) {
982         if (mDrawingState.bufferTransform != s.transform) {
983             ALOGV("%s: false [eTransformChanged changed]", __func__);
984             return false;
985         }
986     }
987 
988     if (s.what & layer_state_t::eTransformToDisplayInverseChanged) {
989         if (mDrawingState.transformToDisplayInverse != s.transformToDisplayInverse) {
990             ALOGV("%s: false [eTransformToDisplayInverseChanged changed]", __func__);
991             return false;
992         }
993     }
994 
995     if (s.what & layer_state_t::eCropChanged) {
996         if (mDrawingState.crop != s.crop) {
997             ALOGV("%s: false [eCropChanged changed]", __func__);
998             return false;
999         }
1000     }
1001 
1002     if (s.what & layer_state_t::eDataspaceChanged) {
1003         if (mDrawingState.dataspace != s.dataspace) {
1004             ALOGV("%s: false [eDataspaceChanged changed]", __func__);
1005             return false;
1006         }
1007     }
1008 
1009     if (s.what & layer_state_t::eHdrMetadataChanged) {
1010         if (mDrawingState.hdrMetadata != s.hdrMetadata) {
1011             ALOGV("%s: false [eHdrMetadataChanged changed]", __func__);
1012             return false;
1013         }
1014     }
1015 
1016     if (s.what & layer_state_t::eSidebandStreamChanged) {
1017         if (mDrawingState.sidebandStream != s.sidebandStream) {
1018             ALOGV("%s: false [eSidebandStreamChanged changed]", __func__);
1019             return false;
1020         }
1021     }
1022 
1023     if (s.what & layer_state_t::eColorSpaceAgnosticChanged) {
1024         if (mDrawingState.colorSpaceAgnostic != s.colorSpaceAgnostic) {
1025             ALOGV("%s: false [eColorSpaceAgnosticChanged changed]", __func__);
1026             return false;
1027         }
1028     }
1029 
1030     if (s.what & layer_state_t::eShadowRadiusChanged) {
1031         if (mDrawingState.shadowRadius != s.shadowRadius) {
1032             ALOGV("%s: false [eShadowRadiusChanged changed]", __func__);
1033             return false;
1034         }
1035     }
1036 
1037     if (s.what & layer_state_t::eFixedTransformHintChanged) {
1038         if (mDrawingState.fixedTransformHint != s.fixedTransformHint) {
1039             ALOGV("%s: false [eFixedTransformHintChanged changed]", __func__);
1040             return false;
1041         }
1042     }
1043 
1044     if (s.what & layer_state_t::eTrustedOverlayChanged) {
1045         if (mDrawingState.isTrustedOverlay != s.isTrustedOverlay) {
1046             ALOGV("%s: false [eTrustedOverlayChanged changed]", __func__);
1047             return false;
1048         }
1049     }
1050 
1051     if (s.what & layer_state_t::eStretchChanged) {
1052         StretchEffect temp = s.stretchEffect;
1053         temp.sanitize();
1054         if (mDrawingState.stretchEffect != temp) {
1055             ALOGV("%s: false [eStretchChanged changed]", __func__);
1056             return false;
1057         }
1058     }
1059 
1060     if (s.what & layer_state_t::eBufferCropChanged) {
1061         if (mDrawingState.bufferCrop != s.bufferCrop) {
1062             ALOGV("%s: false [eBufferCropChanged changed]", __func__);
1063             return false;
1064         }
1065     }
1066 
1067     if (s.what & layer_state_t::eDestinationFrameChanged) {
1068         if (mDrawingState.destinationFrame != s.destinationFrame) {
1069             ALOGV("%s: false [eDestinationFrameChanged changed]", __func__);
1070             return false;
1071         }
1072     }
1073 
1074     if (s.what & layer_state_t::eDimmingEnabledChanged) {
1075         if (mDrawingState.dimmingEnabled != s.dimmingEnabled) {
1076             ALOGV("%s: false [eDimmingEnabledChanged changed]", __func__);
1077             return false;
1078         }
1079     }
1080 
1081     ALOGV("%s: true", __func__);
1082     return true;
1083 }
1084 
1085 } // namespace android
1086