FTL: Import std::future utilities from SF

Now including docs and expanded tests.

Bug: 160012986
Test: ftl_test
Change-Id: If9eb25646bb33ebc417ea87e6718b46fe0b87cf3
diff --git a/services/surfaceflinger/DisplayHardware/HWC2.cpp b/services/surfaceflinger/DisplayHardware/HWC2.cpp
index e6bff04..426092d 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWC2.cpp
@@ -26,18 +26,17 @@
 
 #include "HWC2.h"
 
+#include <android/configuration.h>
+#include <ftl/future.h>
 #include <ui/Fence.h>
 #include <ui/FloatRect.h>
 #include <ui/GraphicBuffer.h>
 
-#include <android/configuration.h>
-
-#include <inttypes.h>
 #include <algorithm>
+#include <cinttypes>
 #include <iterator>
 #include <set>
 
-#include "../Promise.h"
 #include "ComposerHal.h"
 
 namespace android {
@@ -647,7 +646,7 @@
 }
 
 std::future<Error> Display::setDisplayBrightness(float brightness) {
-    return promise::defer([composer = &mComposer, id = mId, brightness] {
+    return ftl::defer([composer = &mComposer, id = mId, brightness] {
         const auto intError = composer->setDisplayBrightness(id, brightness);
         return static_cast<Error>(intError);
     });
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 1548d18..5fa72b8 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -30,6 +30,7 @@
 #include <compositionengine/Output.h>
 #include <compositionengine/OutputLayer.h>
 #include <compositionengine/impl/OutputLayerCompositionState.h>
+#include <ftl/future.h>
 #include <log/log.h>
 #include <ui/DebugUtils.h>
 #include <ui/GraphicBuffer.h>
@@ -37,7 +38,6 @@
 #include <utils/Trace.h>
 
 #include "../Layer.h" // needed only for debugging
-#include "../Promise.h"
 #include "../SurfaceFlinger.h"
 #include "../SurfaceFlingerProperties.h"
 #include "ComposerHal.h"
@@ -792,10 +792,10 @@
 
 std::future<status_t> HWComposer::setDisplayBrightness(PhysicalDisplayId displayId,
                                                        float brightness) {
-    RETURN_IF_INVALID_DISPLAY(displayId, promise::yield<status_t>(BAD_INDEX));
+    RETURN_IF_INVALID_DISPLAY(displayId, ftl::yield<status_t>(BAD_INDEX));
     auto& display = mDisplayData[displayId].hwcDisplay;
 
-    return promise::chain(display->setDisplayBrightness(brightness))
+    return ftl::chain(display->setDisplayBrightness(brightness))
             .then([displayId](hal::Error error) -> status_t {
                 if (error == hal::Error::UNSUPPORTED) {
                     RETURN_IF_HWC_ERROR(error, displayId, INVALID_OPERATION);
diff --git a/services/surfaceflinger/Promise.h b/services/surfaceflinger/Promise.h
deleted file mode 100644
index a80d441..0000000
--- a/services/surfaceflinger/Promise.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <future>
-#include <type_traits>
-#include <utility>
-
-namespace android::promise {
-namespace impl {
-
-template <typename T>
-struct FutureResult {
-    using Type = T;
-};
-
-template <typename T>
-struct FutureResult<std::future<T>> {
-    using Type = T;
-};
-
-} // namespace impl
-
-template <typename T>
-using FutureResult = typename impl::FutureResult<T>::Type;
-
-template <typename... Args>
-inline auto defer(Args... args) {
-    return std::async(std::launch::deferred, std::forward<Args>(args)...);
-}
-
-template <typename T>
-inline std::future<T> yield(T&& v) {
-    return defer([](T&& v) { return std::forward<T>(v); }, std::forward<T>(v));
-}
-
-template <typename T>
-struct Chain {
-    Chain(std::future<T>&& f) : future(std::move(f)) {}
-    operator std::future<T>&&() && { return std::move(future); }
-
-    T get() && { return future.get(); }
-
-    template <typename F, typename R = std::invoke_result_t<F, T>>
-    auto then(F&& op) && -> Chain<FutureResult<R>> {
-        return defer(
-                [](auto&& f, F&& op) {
-                    R r = op(f.get());
-                    if constexpr (std::is_same_v<R, FutureResult<R>>) {
-                        return r;
-                    } else {
-                        return r.get();
-                    }
-                },
-                std::move(future), std::forward<F>(op));
-    }
-
-    std::future<T> future;
-};
-
-template <typename T>
-inline Chain<T> chain(std::future<T>&& f) {
-    return std::move(f);
-}
-
-} // namespace android::promise
diff --git a/services/surfaceflinger/RegionSamplingThread.cpp b/services/surfaceflinger/RegionSamplingThread.cpp
index 2511eb3..ad4877b 100644
--- a/services/surfaceflinger/RegionSamplingThread.cpp
+++ b/services/surfaceflinger/RegionSamplingThread.cpp
@@ -28,6 +28,7 @@
 #include <compositionengine/Display.h>
 #include <compositionengine/impl/OutputCompositionState.h>
 #include <cutils/properties.h>
+#include <ftl/future.h>
 #include <gui/IRegionSamplingListener.h>
 #include <gui/SyncScreenCaptureListener.h>
 #include <ui/DisplayStatInfo.h>
@@ -38,7 +39,6 @@
 #include "DisplayDevice.h"
 #include "DisplayRenderArea.h"
 #include "Layer.h"
-#include "Promise.h"
 #include "Scheduler/VsyncController.h"
 #include "SurfaceFlinger.h"
 
@@ -389,7 +389,7 @@
 
     const Rect sampledBounds = sampleRegion.bounds();
 
-    SurfaceFlinger::RenderAreaFuture renderAreaFuture = promise::defer([=] {
+    SurfaceFlinger::RenderAreaFuture renderAreaFuture = ftl::defer([=] {
         return DisplayRenderArea::create(displayWeak, screencapRegion.bounds(),
                                          sampledBounds.getSize(), ui::Dataspace::V0_SRGB,
                                          orientation);
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 2fb3626..f067922 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -47,8 +47,7 @@
 #include <configstore/Utils.h>
 #include <cutils/compiler.h>
 #include <cutils/properties.h>
-#include <dlfcn.h>
-#include <errno.h>
+#include <ftl/future.h>
 #include <gui/BufferQueue.h>
 #include <gui/DebugEGLImageTracker.h>
 #include <gui/IDisplayEventConnection.h>
@@ -81,6 +80,7 @@
 #include <utils/misc.h>
 
 #include <algorithm>
+#include <cerrno>
 #include <cinttypes>
 #include <cmath>
 #include <cstdint>
@@ -112,7 +112,6 @@
 #include "LayerVector.h"
 #include "MonitoredProducer.h"
 #include "NativeWindowSurface.h"
-#include "Promise.h"
 #include "RefreshRateOverlay.h"
 #include "RegionSamplingThread.h"
 #include "Scheduler/DispSyncSource.h"
@@ -1502,12 +1501,12 @@
         return BAD_VALUE;
     }
 
-    return promise::chain(schedule([=]() MAIN_THREAD {
+    return ftl::chain(schedule([=]() MAIN_THREAD {
                if (const auto displayId = getPhysicalDisplayIdLocked(displayToken)) {
                    return getHwComposer().setDisplayBrightness(*displayId, brightness);
                } else {
                    ALOGE("%s: Invalid display token %p", __FUNCTION__, displayToken.get());
-                   return promise::yield<status_t>(NAME_NOT_FOUND);
+                   return ftl::yield<status_t>(NAME_NOT_FOUND);
                }
            }))
             .then([](std::future<status_t> task) { return task; })
@@ -5484,7 +5483,7 @@
         }
     }
 
-    RenderAreaFuture renderAreaFuture = promise::defer([=] {
+    RenderAreaFuture renderAreaFuture = ftl::defer([=] {
         return DisplayRenderArea::create(displayWeak, args.sourceCrop, reqSize, dataspace,
                                          args.useIdentityTransform, args.captureSecureLayers);
     });
@@ -5518,7 +5517,7 @@
                 pickDataspaceFromColorMode(display->getCompositionDisplay()->getState().colorMode);
     }
 
-    RenderAreaFuture renderAreaFuture = promise::defer([=] {
+    RenderAreaFuture renderAreaFuture = ftl::defer([=] {
         return DisplayRenderArea::create(displayWeak, Rect(), size, dataspace,
                                          false /* useIdentityTransform */,
                                          false /* captureSecureLayers */);
@@ -5622,7 +5621,7 @@
     }
 
     bool childrenOnly = args.childrenOnly;
-    RenderAreaFuture renderAreaFuture = promise::defer([=]() -> std::unique_ptr<RenderArea> {
+    RenderAreaFuture renderAreaFuture = ftl::defer([=]() -> std::unique_ptr<RenderArea> {
         return std::make_unique<LayerRenderArea>(*this, parent, crop, reqSize, dataspace,
                                                  childrenOnly, layerStackSpaceRect,
                                                  captureSecureLayers);
diff --git a/services/surfaceflinger/tests/unittests/Android.bp b/services/surfaceflinger/tests/unittests/Android.bp
index 871222c..20f8f42 100644
--- a/services/surfaceflinger/tests/unittests/Android.bp
+++ b/services/surfaceflinger/tests/unittests/Android.bp
@@ -50,7 +50,6 @@
         "LayerHistoryTest.cpp",
         "LayerMetadataTest.cpp",
         "MessageQueueTest.cpp",
-        "PromiseTest.cpp",
         "SurfaceFlinger_CreateDisplayTest.cpp",
         "SurfaceFlinger_DestroyDisplayTest.cpp",
         "SurfaceFlinger_GetDisplayNativePrimariesTest.cpp",
diff --git a/services/surfaceflinger/tests/unittests/PromiseTest.cpp b/services/surfaceflinger/tests/unittests/PromiseTest.cpp
deleted file mode 100644
index e4dc1fe..0000000
--- a/services/surfaceflinger/tests/unittests/PromiseTest.cpp
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <algorithm>
-#include <future>
-#include <string>
-#include <thread>
-#include <vector>
-
-#include <gtest/gtest.h>
-
-#include "Promise.h"
-
-namespace android {
-namespace {
-
-using Bytes = std::vector<uint8_t>;
-
-Bytes decrement(Bytes bytes) {
-    std::transform(bytes.begin(), bytes.end(), bytes.begin(), [](auto b) { return b - 1; });
-    return bytes;
-}
-
-} // namespace
-
-TEST(PromiseTest, yield) {
-    EXPECT_EQ(42, promise::yield(42).get());
-
-    auto ptr = std::make_unique<char>('!');
-    auto future = promise::yield(std::move(ptr));
-    EXPECT_EQ('!', *future.get());
-}
-
-TEST(PromiseTest, chain) {
-    std::packaged_task<const char*()> fetchString([] { return "ifmmp-"; });
-
-    std::packaged_task<Bytes(std::string)> appendString([](std::string str) {
-        str += "!xpsme";
-        return Bytes{str.begin(), str.end()};
-    });
-
-    std::packaged_task<std::future<Bytes>(Bytes)> decrementBytes(
-            [](Bytes bytes) { return promise::defer(decrement, std::move(bytes)); });
-
-    auto fetch = fetchString.get_future();
-    std::thread fetchThread(std::move(fetchString));
-
-    std::thread appendThread, decrementThread;
-
-    EXPECT_EQ("hello, world",
-              promise::chain(std::move(fetch))
-                      .then([](const char* str) { return std::string(str); })
-                      .then([&](std::string str) {
-                          auto append = appendString.get_future();
-                          appendThread = std::thread(std::move(appendString), std::move(str));
-                          return append;
-                      })
-                      .then([&](Bytes bytes) {
-                          auto decrement = decrementBytes.get_future();
-                          decrementThread = std::thread(std::move(decrementBytes),
-                                                        std::move(bytes));
-                          return decrement;
-                      })
-                      .then([](std::future<Bytes> bytes) { return bytes; })
-                      .then([](const Bytes& bytes) {
-                          return std::string(bytes.begin(), bytes.end());
-                      })
-                      .get());
-
-    fetchThread.join();
-    appendThread.join();
-    decrementThread.join();
-}
-
-} // namespace android