Convert c2_status_t to status_t properly

Test: m cts && cts-tradefed run cts \
-m CtsMediaTestCases -t android.media.cts.MediaCodecCapabilitiesTest#\
testGetMaxSupportedInstances

Bug: 110704390
Change-Id: Ia66bd535a068f61c06564926b32005f2f40a2a97
diff --git a/media/sfplugin/CCodec.cpp b/media/sfplugin/CCodec.cpp
index 54c32bf..4dac6e7 100644
--- a/media/sfplugin/CCodec.cpp
+++ b/media/sfplugin/CCodec.cpp
@@ -143,8 +143,8 @@
         if (mConnection != nullptr) {
             return ALREADY_EXISTS;
         }
-        return static_cast<status_t>(
-                mSurface->connectToComponent(comp, &mConnection));
+        return toStatusT(mSurface->connectToComponent(comp, &mConnection),
+                         C2_OPERATION_InputSurface_connectToComponent);
     }
 
     void disconnect() override {
@@ -870,7 +870,8 @@
     if (property_get_bool("debug.stagefright.c2inputsurface", false)) {
         std::shared_ptr<Codec2Client::InputSurface> surface;
 
-        err = static_cast<status_t>(mClient->createInputSurface(&surface));
+        err = toStatusT(mClient->createInputSurface(&surface),
+                        C2_OPERATION_ComponentStore_createInputSurface);
         if (err != OK) {
             ALOGE("Failed to create input surface: %d", static_cast<int>(err));
             mCallback->onInputSurfaceCreationFailed(err);
@@ -998,8 +999,8 @@
 
     c2_status_t err = comp->start();
     if (err != C2_OK) {
-        // TODO: convert err into status_t
-        mCallback->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL);
+        mCallback->onError(toStatusT(err, C2_OPERATION_Component_start),
+                           ACTION_CODE_FATAL);
         return;
     }
     sp<AMessage> inputFormat;
diff --git a/media/sfplugin/CCodecBufferChannel.cpp b/media/sfplugin/CCodecBufferChannel.cpp
index 0da6b41..052ea8c 100644
--- a/media/sfplugin/CCodecBufferChannel.cpp
+++ b/media/sfplugin/CCodecBufferChannel.cpp
@@ -2232,4 +2232,54 @@
     mMetaMode = mode;
 }
 
+status_t toStatusT(c2_status_t c2s, c2_operation_t c2op) {
+    // C2_OK is always translated to OK.
+    if (c2s == C2_OK) {
+        return OK;
+    }
+
+    // Operation-dependent translation
+    // TODO: Add as necessary
+    switch (c2op) {
+    case C2_OPERATION_Component_start:
+        switch (c2s) {
+        case C2_NO_MEMORY:
+            return NO_MEMORY;
+        default:
+            return UNKNOWN_ERROR;
+        }
+    default:
+        break;
+    }
+
+    // Backup operation-agnostic translation
+    switch (c2s) {
+    case C2_BAD_INDEX:
+        return BAD_INDEX;
+    case C2_BAD_VALUE:
+        return BAD_VALUE;
+    case C2_BLOCKING:
+        return WOULD_BLOCK;
+    case C2_DUPLICATE:
+        return ALREADY_EXISTS;
+    case C2_NO_INIT:
+        return NO_INIT;
+    case C2_NO_MEMORY:
+        return NO_MEMORY;
+    case C2_NOT_FOUND:
+        return NAME_NOT_FOUND;
+    case C2_TIMED_OUT:
+        return TIMED_OUT;
+    case C2_BAD_STATE:
+    case C2_CANCELED:
+    case C2_CANNOT_DO:
+    case C2_CORRUPTED:
+    case C2_OMITTED:
+    case C2_REFUSED:
+        return UNKNOWN_ERROR;
+    default:
+        return -static_cast<status_t>(c2s);
+    }
+}
+
 }  // namespace android
diff --git a/media/sfplugin/CCodecBufferChannel.h b/media/sfplugin/CCodecBufferChannel.h
index 52106b9..033d364 100644
--- a/media/sfplugin/CCodecBufferChannel.h
+++ b/media/sfplugin/CCodecBufferChannel.h
@@ -246,6 +246,36 @@
     }
 };
 
+// Conversion of a c2_status_t value to a status_t value may depend on the
+// operation that returns the c2_status_t value.
+enum c2_operation_t {
+    C2_OPERATION_NONE,
+    C2_OPERATION_Component_connectToOmxInputSurface,
+    C2_OPERATION_Component_createBlockPool,
+    C2_OPERATION_Component_destroyBlockPool,
+    C2_OPERATION_Component_disconnectFromInputSurface,
+    C2_OPERATION_Component_drain,
+    C2_OPERATION_Component_flush,
+    C2_OPERATION_Component_queue,
+    C2_OPERATION_Component_release,
+    C2_OPERATION_Component_reset,
+    C2_OPERATION_Component_setOutputSurface,
+    C2_OPERATION_Component_start,
+    C2_OPERATION_Component_stop,
+    C2_OPERATION_ComponentStore_copyBuffer,
+    C2_OPERATION_ComponentStore_createComponent,
+    C2_OPERATION_ComponentStore_createInputSurface,
+    C2_OPERATION_ComponentStore_createInterface,
+    C2_OPERATION_Configurable_config,
+    C2_OPERATION_Configurable_query,
+    C2_OPERATION_Configurable_querySupportedParams,
+    C2_OPERATION_Configurable_querySupportedValues,
+    C2_OPERATION_InputSurface_connectToComponent,
+    C2_OPERATION_InputSurfaceConnection_disconnect,
+};
+
+status_t toStatusT(c2_status_t c2s, c2_operation_t c2op = C2_OPERATION_NONE);
+
 }  // namespace android
 
 #endif  // CCODEC_BUFFER_CHANNEL_H_