Merge "Avoid a couple string copies"
diff --git a/drm/libmediadrm/Android.bp b/drm/libmediadrm/Android.bp
index 6e1e10b..bf0cdd5 100644
--- a/drm/libmediadrm/Android.bp
+++ b/drm/libmediadrm/Android.bp
@@ -168,10 +168,6 @@
         "DrmMetricsConsumer.cpp",
     ],
 
-    include_dirs: [
-        "frameworks/av/media/libmedia/include"
-    ],
-
     shared_libs: [
         "android.hardware.drm@1.0",
         "android.hardware.drm@1.1",
@@ -187,5 +183,6 @@
     header_libs: [
         "libmediametrics_headers",
         "libstagefright_foundation_headers",
+        "libmedia_headers",
     ],
 }
diff --git a/media/libaudioclient/Android.bp b/media/libaudioclient/Android.bp
index 33e2848..e890e97 100644
--- a/media/libaudioclient/Android.bp
+++ b/media/libaudioclient/Android.bp
@@ -203,9 +203,11 @@
     ],
     header_libs: [
         "libbase_headers",
+        "liberror_headers",
     ],
     export_header_lib_headers: [
         "libbase_headers",
+        "liberror_headers",
     ],
     apex_available: [
         "//apex_available:platform",
diff --git a/media/libaudioclient/include/media/AidlConversionUtil.h b/media/libaudioclient/include/media/AidlConversionUtil.h
index 227d823..4d16792 100644
--- a/media/libaudioclient/include/media/AidlConversionUtil.h
+++ b/media/libaudioclient/include/media/AidlConversionUtil.h
@@ -20,45 +20,13 @@
 #include <type_traits>
 #include <utility>
 
-#include <android-base/expected.h>
 #include <binder/Status.h>
+#include <error/Result.h>
 
 namespace android {
 
 template <typename T>
-using ConversionResult = base::expected<T, status_t>;
-
-// Convenience macros for working with ConversionResult, useful for writing converted for aggregate
-// types.
-
-#define VALUE_OR_RETURN(result)                                \
-    ({                                                         \
-        auto _tmp = (result);                                  \
-        if (!_tmp.ok()) return base::unexpected(_tmp.error()); \
-        std::move(_tmp.value());                               \
-    })
-
-#define RETURN_IF_ERROR(result) \
-    if (status_t _tmp = (result); _tmp != OK) return base::unexpected(_tmp);
-
-#define RETURN_STATUS_IF_ERROR(result) \
-    if (status_t _tmp = (result); _tmp != OK) return _tmp;
-
-#define VALUE_OR_RETURN_STATUS(x)           \
-    ({                                      \
-       auto _tmp = (x);                     \
-       if (!_tmp.ok()) return _tmp.error(); \
-       std::move(_tmp.value());             \
-     })
-
-#define VALUE_OR_FATAL(result)                                        \
-    ({                                                                \
-       auto _tmp = (result);                                          \
-       LOG_ALWAYS_FATAL_IF(!_tmp.ok(),                                \
-                           "Function: %s Line: %d Failed result (%d)",\
-                           __FUNCTION__, __LINE__, _tmp.error());     \
-       std::move(_tmp.value());                                       \
-     })
+using ConversionResult = error::Result<T>;
 
 /**
  * A generic template to safely cast between integral types, respecting limits of the destination
diff --git a/media/liberror/Android.bp b/media/liberror/Android.bp
new file mode 100644
index 0000000..f54d354
--- /dev/null
+++ b/media/liberror/Android.bp
@@ -0,0 +1,67 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_av_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_av_license"],
+}
+
+cc_library_headers {
+    name: "libexpectedutils_headers",
+    host_supported: true,
+    vendor_available: true,
+    min_sdk_version: "29",
+    export_include_dirs: [
+        "include",
+    ],
+    header_libs: [
+        "libbase_headers",
+        "libutils_headers",
+    ],
+    export_header_lib_headers: [
+        "libbase_headers",
+        "libutils_headers",
+    ],
+    apex_available: [
+        "//apex_available:platform",
+        "com.android.bluetooth",
+        "com.android.media",
+        "com.android.media.swcodec",
+    ],
+}
+
+cc_test_host {
+    name: "libexpectedutils_test",
+    srcs: [
+        "expected_utils_test.cpp",
+    ],
+    shared_libs: [
+        "liblog",
+    ],
+    header_libs: [
+        "libexpectedutils_headers",
+    ],
+}
+
+cc_library_headers {
+    name: "liberror_headers",
+    host_supported: true,
+    vendor_available: true,
+    min_sdk_version: "29",
+    apex_available: [
+        "//apex_available:platform",
+        "com.android.bluetooth",
+        "com.android.media",
+        "com.android.media.swcodec",
+    ],
+    export_include_dirs: [
+        "include",
+    ],
+    header_libs: [
+        "libexpectedutils_headers",
+    ],
+    export_header_lib_headers: [
+        "libexpectedutils_headers",
+    ],
+}
diff --git a/media/liberror/expected_utils_test.cpp b/media/liberror/expected_utils_test.cpp
new file mode 100644
index 0000000..252210a
--- /dev/null
+++ b/media/liberror/expected_utils_test.cpp
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2021 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 <error/expected_utils.h>
+#include <gtest/gtest.h>
+
+#define LOG_TAG "Result-test"
+
+namespace android {
+namespace foo {
+
+class Value {
+  public:
+    explicit Value(int i) : mInt(i) {}
+    Value(const Value&) = delete;
+    Value(Value&&) = default;
+
+    operator int() const { return mInt; }
+
+  private:
+    const int mInt;
+};
+
+class Status {
+  public:
+    explicit Status(int i) : mInt(i) {}
+    Status(const Status&) = delete;
+    Status(Status&&) = default;
+
+    operator int() const { return mInt; }
+
+  private:
+    const int mInt;
+};
+
+bool errorIsOk(const Status& e) {
+    return e == 0;
+}
+
+std::string errorToString(const Status& e) {
+    std::ostringstream str;
+    str << e;
+    return str.str();
+}
+
+using Result = base::expected<Value, Status>;
+
+}  // namespace foo
+
+namespace {
+
+using foo::Result;
+using foo::Status;
+using foo::Value;
+
+TEST(Result, ValueOrReturnSuccess) {
+    Result result = []() -> Result {
+        Value intermediate = VALUE_OR_RETURN(Result(Value(3)));
+        return Value(intermediate + 1);
+    }();
+    ASSERT_TRUE(result.ok());
+    EXPECT_EQ(4, result.value());
+}
+
+TEST(Result, ValueOrReturnFailure) {
+    Result result = []() -> Result {
+        Value intermediate = VALUE_OR_RETURN(Result(base::unexpected(Status(2))));
+        return Value(intermediate + 1);
+    }();
+    ASSERT_FALSE(result.ok());
+    EXPECT_EQ(2, result.error());
+}
+
+TEST(Result, ValueOrReturnStatusSuccess) {
+    Status status = []() -> Status {
+        Value intermediate = VALUE_OR_RETURN_STATUS(Result(Value(3)));
+        (void) intermediate;
+        return Status(0);
+    }();
+    EXPECT_EQ(0, status);
+}
+
+TEST(Result, ValueOrReturnStatusFailure) {
+    Status status = []() -> Status {
+        Value intermediate = VALUE_OR_RETURN_STATUS(Result(base::unexpected(Status(1))));
+        (void) intermediate;
+        return Status(0);
+    }();
+    EXPECT_EQ(1, status);
+}
+
+TEST(Result, ReturnIfErrorSuccess) {
+    Result result = []() -> Result {
+        RETURN_IF_ERROR(Status(0));
+        return Value(5);
+    }();
+    ASSERT_TRUE(result.ok());
+    EXPECT_EQ(5, result.value());
+}
+
+TEST(Result, ReturnIfErrorFailure) {
+    Result result = []() -> Result {
+        RETURN_IF_ERROR(Status(4));
+        return Value(5);
+    }();
+    ASSERT_FALSE(result.ok());
+    EXPECT_EQ(4, result.error());
+}
+
+TEST(Result, ReturnStatusIfErrorSuccess) {
+    Status status = []() -> Status {
+        RETURN_STATUS_IF_ERROR(Status(0));
+        return Status(7);
+    }();
+    EXPECT_EQ(7, status);
+}
+
+TEST(Result, ReturnStatusIfErrorFailure) {
+    Status status = []() -> Status {
+        RETURN_STATUS_IF_ERROR(Status(3));
+        return Status(0);
+    }();
+    EXPECT_EQ(3, status);
+}
+
+TEST(Result, ValueOrFatalSuccess) {
+    Value value = VALUE_OR_FATAL(Result(Value(7)));
+    EXPECT_EQ(7, value);
+}
+
+TEST(Result, ValueOrFatalFailure) {
+    EXPECT_DEATH(VALUE_OR_FATAL(Result(base::unexpected(Status(3)))), "");
+}
+
+TEST(Result, FatalIfErrorSuccess) {
+    FATAL_IF_ERROR(Status(0));
+}
+
+TEST(Result, FatalIfErrorFailure) {
+    EXPECT_DEATH(FATAL_IF_ERROR(Status(3)), "");
+}
+
+}  // namespace
+}  // namespace android
diff --git a/media/liberror/include/error/Result.h b/media/liberror/include/error/Result.h
new file mode 100644
index 0000000..620e6d0
--- /dev/null
+++ b/media/liberror/include/error/Result.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2021 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 <error/expected_utils.h>
+#include <utils/Errors.h>
+
+namespace android {
+namespace error {
+
+/**
+ * A convenience short-hand for base::expected, where the error type is a status_t.
+ */
+template <typename T>
+using Result = base::expected<T, status_t>;
+
+}  // namespace error
+}  // namespace android
+
+// Below are the implementations of errorIsOk and errorToString for status_t .
+// This allows status_t to be used in conjunction with the expected_utils.h macros.
+// Unfortuantely, since status_t is merely a typedef for int rather than a unique type, we have to
+// overload these methods for any int, and do so in the global namespace for ADL to work.
+
+inline bool errorIsOk(int status) {
+    return status == android::OK;
+}
+
+inline std::string errorToString(int status) {
+    return android::statusToString(status);
+}
diff --git a/media/liberror/include/error/expected_utils.h b/media/liberror/include/error/expected_utils.h
new file mode 100644
index 0000000..ddc8517
--- /dev/null
+++ b/media/liberror/include/error/expected_utils.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2021 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 <sstream>
+
+#include <android-base/expected.h>
+#include <log/log_main.h>
+
+/**
+ * Useful macros for working with status codes and base::expected.
+ *
+ * These macros facilitate various kinds of strategies for reduction of error-handling-related
+ * boilerplate. They can be can be classified by the following criteria:
+ * - Whether the argument is a standalone status code vs. base::expected (status or value). In the
+ *   latter case, the macro will evaluate to the contained value in the case of success.
+ * - Whether to FATAL or return in response to an error.
+ *   - In the latter case, whether the enclosing function returns a status code or a base::expected.
+ *
+ * The table below summarizes which macro serves which case, based on those criteria:
+ * +--------------------+------------------+------------------------------------------------------+
+ * |     Error response | FATAL            | Early return                                         |
+ * |                    |                  +---------------------------+--------------------------+
+ * | Expression type    |                  | Function returns expected | Function returns status  |
+ * +--------------------+------------------+---------------------------+--------------------------+
+ * | status code        | FATAL_IF_ERROR() | RETURN_IF_ERROR()         | RETURN_STATUS_IF_ERROR() |
+ * +--------------------+------------------+---------------------------+--------------------------+
+ * | expected           | VALUE_OR_FATAL() | VALUE_OR_RETURN()         | VALUE_OR_RETURN_STATUS() |
+ * +--------------------+------------------+---------------------------+--------------------------+
+ *
+ * All macros expect that:
+ * - The error type and value value type are movable.
+ * - The macro argument can be assigned to a variable using `auto x = (exp)`.
+ * - The expression errorIsOk(e) for the error type evaluatea to a bool which is true iff the
+ *   status is considered success.
+ * - The expression errorToString(e) for a given error type evaluated to a std::string containing a
+ *   human-readable version of the status.
+ */
+
+#define VALUE_OR_RETURN(exp)                                                         \
+    ({                                                                               \
+        auto _tmp = (exp);                                                           \
+        if (!_tmp.ok()) return ::android::base::unexpected(std::move(_tmp.error())); \
+        std::move(_tmp.value());                                                     \
+    })
+
+#define VALUE_OR_RETURN_STATUS(exp)                     \
+    ({                                                  \
+        auto _tmp = (exp);                              \
+        if (!_tmp.ok()) return std::move(_tmp.error()); \
+        std::move(_tmp.value());                        \
+    })
+
+#define VALUE_OR_FATAL(exp)                                                                       \
+    ({                                                                                            \
+        auto _tmp = (exp);                                                                        \
+        LOG_ALWAYS_FATAL_IF(!_tmp.ok(), "Function: %s Line: %d Failed result (%s)", __FUNCTION__, \
+                            __LINE__, errorToString(_tmp.error()).c_str());                       \
+        std::move(_tmp.value());                                                                  \
+    })
+
+#define RETURN_IF_ERROR(exp) \
+    if (auto _tmp = (exp); !errorIsOk(_tmp)) return ::android::base::unexpected(std::move(_tmp));
+
+#define RETURN_STATUS_IF_ERROR(exp) \
+    if (auto _tmp = (exp); !errorIsOk(_tmp)) return _tmp;
+
+#define FATAL_IF_ERROR(exp)                                                                \
+    {                                                                                      \
+        auto _tmp = (exp);                                                                 \
+        LOG_ALWAYS_FATAL_IF(!errorIsOk(_tmp), "Function: %s Line: %d Failed result: (%s)", \
+                            __FUNCTION__, __LINE__, errorToString(_tmp).c_str());         \
+    }
diff --git a/media/libstagefright/rtsp/Android.bp b/media/libstagefright/rtsp/Android.bp
index 97d4abe..5b63cc2 100644
--- a/media/libstagefright/rtsp/Android.bp
+++ b/media/libstagefright/rtsp/Android.bp
@@ -101,6 +101,10 @@
 
 //###############################################################################
 
+// 2022-01-13: this is stale; it's been disabled for 5 years.
+// test references UDPPusher and ARTPSession, neither of which is built into
+// libstagefright_rtsp
+//
 cc_test {
     name: "rtp_test",
     gtest: false,
@@ -119,10 +123,9 @@
 
     static_libs: ["libstagefright_rtsp"],
 
-    include_dirs: [
-        "frameworks/av/media/libstagefright",
-        "frameworks/av/cmds/stagefright",
-        "frameworks/native/include/media/openmax",
+    header_libs: [
+        "libstagefright_headers",
+        "libstagefright_rtsp_headers",
     ],
 
     cflags: [
diff --git a/media/libstagefright/rtsp/rtp_test.cpp b/media/libstagefright/rtsp/rtp_test.cpp
index 1ae4a09..a8cd7e4 100644
--- a/media/libstagefright/rtsp/rtp_test.cpp
+++ b/media/libstagefright/rtsp/rtp_test.cpp
@@ -182,7 +182,7 @@
     CHECK_EQ(decoder->start(), (status_t)OK);
 
     for (;;) {
-        MediaBuffer *buffer;
+        MediaBufferBase *buffer;
         status_t err = decoder->read(&buffer);
 
         if (err != OK) {
@@ -201,7 +201,7 @@
 #if 1
         if (buffer->range_length() != 0) {
             int64_t timeUs;
-            CHECK(buffer->meta_data()->findInt64(kKeyTime, &timeUs));
+            CHECK(buffer->meta_data().findInt64(kKeyTime, &timeUs));
 
             printf("decoder returned frame of size %zu at time %.2f secs\n",
                    buffer->range_length(), timeUs / 1E6);