Loading packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotExecutor.kt +27 −16 Original line number Diff line number Diff line Loading @@ -150,16 +150,18 @@ constructor( } /** * Returns a [RequestCallback] that calls [RequestCallback.onFinish] only when all callbacks for * id created have finished. * Returns a [RequestCallback] that wraps [originalCallback]. * * If any callback created calls [reportError], then following [onFinish] are not considered. * Each [RequestCallback] created with [createCallbackForId] is expected to be used with either * [reportError] or [onFinish]. Once they are both called: * - If any finished with an error, [reportError] of [originalCallback] is called * - Otherwise, [onFinish] is called. */ private class MultiResultCallbackWrapper( private val originalCallback: RequestCallback, ) { private val idsPending = mutableSetOf<Int>() private var errorReported = false private val idsWithErrors = mutableSetOf<Int>() /** * Creates a callback for [id]. Loading @@ -172,24 +174,33 @@ constructor( idsPending += id return object : RequestCallback { override fun reportError() { Log.d(TAG, "ReportError id=$id") Trace.asyncTraceForTrackEnd(Trace.TRACE_TAG_APP, TAG, id) Trace.instantForTrack(Trace.TRACE_TAG_APP, TAG, "reportError id=$id") originalCallback.reportError() errorReported = true endTrace("reportError id=$id") idsWithErrors += id idsPending -= id reportToOriginalIfNeeded() } override fun onFinish() { Log.d(TAG, "onFinish id=$id") if (errorReported) return endTrace("onFinish id=$id") idsPending -= id Trace.instantForTrack(Trace.TRACE_TAG_APP, TAG, "onFinish id=$id") if (idsPending.isEmpty()) { reportToOriginalIfNeeded() } private fun endTrace(reason: String) { Log.d(TAG, "Finished waiting for id=$id. $reason") Trace.asyncTraceForTrackEnd(Trace.TRACE_TAG_APP, TAG, id) originalCallback.onFinish() Trace.instantForTrack(Trace.TRACE_TAG_APP, TAG, reason) } } } private fun reportToOriginalIfNeeded() { if (idsPending.isNotEmpty()) return if (idsWithErrors.isEmpty()) { originalCallback.onFinish() } else { originalCallback.reportError() } } } Loading packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java +5 −1 Original line number Diff line number Diff line Loading @@ -99,7 +99,11 @@ public class TakeScreenshotService extends Service { /** Informs about coarse grained state of the Controller. */ public interface RequestCallback { /** Respond to the current request indicating the screenshot request failed. */ /** * Respond to the current request indicating the screenshot request failed. * <p> * After this, the service will be disconnected and all visible UI is removed. */ void reportError(); /** The controller has completed handling this request UI has been removed */ Loading packages/SystemUI/tests/src/com/android/systemui/screenshot/TakeScreenshotExecutorTest.kt +5 −4 Original line number Diff line number Diff line Loading @@ -180,7 +180,7 @@ class TakeScreenshotExecutorTest : SysuiTestCase() { } @Test fun executeScreenshots_doesNotReportFinishedIfOneFinishesOtherFails() = fun executeScreenshots_oneFinishesOtherFails_reportFailsOnlyAtTheEnd() = testScope.runTest { setDisplays(display(TYPE_INTERNAL, id = 0), display(TYPE_EXTERNAL, id = 1)) val onSaved = { _: Uri -> } Loading @@ -207,7 +207,7 @@ class TakeScreenshotExecutorTest : SysuiTestCase() { } @Test fun executeScreenshots_doesNotReportFinishedAfterOneFails() = fun executeScreenshots_allDisplaysFail_reportsFail() = testScope.runTest { setDisplays(display(TYPE_INTERNAL, id = 0), display(TYPE_EXTERNAL, id = 1)) val onSaved = { _: Uri -> } Loading @@ -224,11 +224,12 @@ class TakeScreenshotExecutorTest : SysuiTestCase() { capturer0.value.reportError() verify(callback, never()).onFinish() verify(callback).reportError() verify(callback, never()).reportError() capturer1.value.onFinish() capturer1.value.reportError() verify(callback, never()).onFinish() verify(callback).reportError() screenshotExecutor.onDestroy() } Loading Loading
packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotExecutor.kt +27 −16 Original line number Diff line number Diff line Loading @@ -150,16 +150,18 @@ constructor( } /** * Returns a [RequestCallback] that calls [RequestCallback.onFinish] only when all callbacks for * id created have finished. * Returns a [RequestCallback] that wraps [originalCallback]. * * If any callback created calls [reportError], then following [onFinish] are not considered. * Each [RequestCallback] created with [createCallbackForId] is expected to be used with either * [reportError] or [onFinish]. Once they are both called: * - If any finished with an error, [reportError] of [originalCallback] is called * - Otherwise, [onFinish] is called. */ private class MultiResultCallbackWrapper( private val originalCallback: RequestCallback, ) { private val idsPending = mutableSetOf<Int>() private var errorReported = false private val idsWithErrors = mutableSetOf<Int>() /** * Creates a callback for [id]. Loading @@ -172,24 +174,33 @@ constructor( idsPending += id return object : RequestCallback { override fun reportError() { Log.d(TAG, "ReportError id=$id") Trace.asyncTraceForTrackEnd(Trace.TRACE_TAG_APP, TAG, id) Trace.instantForTrack(Trace.TRACE_TAG_APP, TAG, "reportError id=$id") originalCallback.reportError() errorReported = true endTrace("reportError id=$id") idsWithErrors += id idsPending -= id reportToOriginalIfNeeded() } override fun onFinish() { Log.d(TAG, "onFinish id=$id") if (errorReported) return endTrace("onFinish id=$id") idsPending -= id Trace.instantForTrack(Trace.TRACE_TAG_APP, TAG, "onFinish id=$id") if (idsPending.isEmpty()) { reportToOriginalIfNeeded() } private fun endTrace(reason: String) { Log.d(TAG, "Finished waiting for id=$id. $reason") Trace.asyncTraceForTrackEnd(Trace.TRACE_TAG_APP, TAG, id) originalCallback.onFinish() Trace.instantForTrack(Trace.TRACE_TAG_APP, TAG, reason) } } } private fun reportToOriginalIfNeeded() { if (idsPending.isNotEmpty()) return if (idsWithErrors.isEmpty()) { originalCallback.onFinish() } else { originalCallback.reportError() } } } Loading
packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java +5 −1 Original line number Diff line number Diff line Loading @@ -99,7 +99,11 @@ public class TakeScreenshotService extends Service { /** Informs about coarse grained state of the Controller. */ public interface RequestCallback { /** Respond to the current request indicating the screenshot request failed. */ /** * Respond to the current request indicating the screenshot request failed. * <p> * After this, the service will be disconnected and all visible UI is removed. */ void reportError(); /** The controller has completed handling this request UI has been removed */ Loading
packages/SystemUI/tests/src/com/android/systemui/screenshot/TakeScreenshotExecutorTest.kt +5 −4 Original line number Diff line number Diff line Loading @@ -180,7 +180,7 @@ class TakeScreenshotExecutorTest : SysuiTestCase() { } @Test fun executeScreenshots_doesNotReportFinishedIfOneFinishesOtherFails() = fun executeScreenshots_oneFinishesOtherFails_reportFailsOnlyAtTheEnd() = testScope.runTest { setDisplays(display(TYPE_INTERNAL, id = 0), display(TYPE_EXTERNAL, id = 1)) val onSaved = { _: Uri -> } Loading @@ -207,7 +207,7 @@ class TakeScreenshotExecutorTest : SysuiTestCase() { } @Test fun executeScreenshots_doesNotReportFinishedAfterOneFails() = fun executeScreenshots_allDisplaysFail_reportsFail() = testScope.runTest { setDisplays(display(TYPE_INTERNAL, id = 0), display(TYPE_EXTERNAL, id = 1)) val onSaved = { _: Uri -> } Loading @@ -224,11 +224,12 @@ class TakeScreenshotExecutorTest : SysuiTestCase() { capturer0.value.reportError() verify(callback, never()).onFinish() verify(callback).reportError() verify(callback, never()).reportError() capturer1.value.onFinish() capturer1.value.reportError() verify(callback, never()).onFinish() verify(callback).reportError() screenshotExecutor.onDestroy() } Loading