mm-video-v4l2: vdec: allocate secure buffer as native_handle

Rather than stashing a file-descriptor directly in pBuffer,
wrap the fd in a native_handle to enable client to pass
fds safely to crypto process.

Bug: 28522683
Change-Id: Ica3beac395a0e63c1e0aeec061ec88bb9055a31f
diff --git a/msm8996/mm-core/inc/OMX_QCOMExtns.h b/msm8996/mm-core/inc/OMX_QCOMExtns.h
index 4ce44f6..00a532e 100644
--- a/msm8996/mm-core/inc/OMX_QCOMExtns.h
+++ b/msm8996/mm-core/inc/OMX_QCOMExtns.h
@@ -550,6 +550,9 @@
 
     /* Force OPB to UnCompressed mode */
     OMX_QTIIndexParamForceUnCompressedForOPB = 0x7F00005A,
+
+    /*"OMX.google.android.index.allocateNativeHandle"*/
+    OMX_GoogleAndroidIndexAllocateNativeHandle = 0x7F00005B,
 };
 
 /**
diff --git a/msm8996/mm-video-v4l2/vidc/vdec/inc/omx_vdec.h b/msm8996/mm-video-v4l2/vidc/vdec/inc/omx_vdec.h
index 2478338..d08d164 100644
--- a/msm8996/mm-video-v4l2/vidc/vdec/inc/omx_vdec.h
+++ b/msm8996/mm-video-v4l2/vidc/vdec/inc/omx_vdec.h
@@ -940,6 +940,7 @@
         omx_time_stamp_reorder time_stamp_dts;
         desc_buffer_hdr *m_desc_buffer_ptr;
         bool secure_mode;
+        bool allocate_native_handle;
         bool external_meta_buffer;
         bool external_meta_buffer_iommu;
         OMX_QCOM_EXTRADATA_FRAMEINFO *m_extradata;
diff --git a/msm8996/mm-video-v4l2/vidc/vdec/src/omx_vdec_v4l2.cpp b/msm8996/mm-video-v4l2/vidc/vdec/src/omx_vdec_v4l2.cpp
index be9b37d..a825b08 100644
--- a/msm8996/mm-video-v4l2/vidc/vdec/src/omx_vdec_v4l2.cpp
+++ b/msm8996/mm-video-v4l2/vidc/vdec/src/omx_vdec_v4l2.cpp
@@ -639,6 +639,7 @@
 #endif
     m_desc_buffer_ptr(NULL),
     secure_mode(false),
+    allocate_native_handle(false),
     m_other_extradata(NULL),
     m_profile(0),
     client_set_fps(false),
@@ -4586,6 +4587,13 @@
                                        eRet = use_android_native_buffer(hComp, paramData);
                                    }
                                    break;
+        case OMX_GoogleAndroidIndexAllocateNativeHandle: {
+                AllocateNativeHandleParams* allocateNativeHandleParams = (AllocateNativeHandleParams *) paramData;
+                if (allocateNativeHandleParams != NULL) {
+                    allocate_native_handle = allocateNativeHandleParams->enable;
+                }
+            }
+            break;
 #endif
         case OMX_QcomIndexParamEnableTimeStampReorder: {
                                        VALIDATE_OMX_PARAM_DATA(paramData, QOMX_INDEXTIMESTAMPREORDER);
@@ -5237,6 +5245,8 @@
         *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer;
     } else if (extn_equals(paramName, "OMX.google.android.index.getAndroidNativeBufferUsage")) {
         *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage;
+    } else if (extn_equals(paramName, "OMX.google.android.index.allocateNativeHandle")) {
+        *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexAllocateNativeHandle;
     }
 #endif
     else if (extn_equals(paramName, "OMX.google.android.index.storeMetaDataInBuffers")) {
@@ -5838,8 +5848,12 @@
                         drv_ctx.ptr_inputbuffer[index].bufferaddr);
                 munmap (drv_ctx.ptr_inputbuffer[index].bufferaddr,
                         drv_ctx.ptr_inputbuffer[index].mmaped_size);
+                close (drv_ctx.ptr_inputbuffer[index].pmem_fd);
+            } else if (allocate_native_handle){
+                native_handle_t *nh = (native_handle_t *)bufferHdr->pBuffer;
+                native_handle_close(nh);
+                native_handle_delete(nh);
             }
-            close (drv_ctx.ptr_inputbuffer[index].pmem_fd);
             drv_ctx.ptr_inputbuffer[index].pmem_fd = -1;
             if (m_desc_buffer_ptr && m_desc_buffer_ptr[index].buf_addr) {
                 free(m_desc_buffer_ptr[index].buf_addr);
@@ -6168,11 +6182,16 @@
         input = *bufferHdr;
         BITMASK_SET(&m_inp_bm_count,i);
         DEBUG_PRINT_LOW("Buffer address %p of pmem",*bufferHdr);
-        if (secure_mode || m_input_pass_buffer_fd)
+        if (allocate_native_handle) {
+            native_handle_t *nh = native_handle_create(1 /*numFds*/, 0 /*numInts*/);
+            nh->data[0] = drv_ctx.ptr_inputbuffer[i].pmem_fd;
+            input->pBuffer = (OMX_U8 *)nh;
+        } else if (secure_mode || m_input_pass_buffer_fd) {
+            /*Legacy method, pass ion fd stashed directly in pBuffer*/
             input->pBuffer = (OMX_U8 *)(intptr_t)drv_ctx.ptr_inputbuffer[i].pmem_fd;
-        else
-            input->pBuffer = (OMX_U8 *)buf_addr;
-
+        } else {
+            input->pBuffer           = (OMX_U8 *)buf_addr;
+        }
         input->nSize             = sizeof(OMX_BUFFERHEADERTYPE);
         input->nVersion.nVersion = OMX_SPEC_VERSION;
         input->nAllocLen         = drv_ctx.ip_buf.buffer_size;
@@ -6979,7 +6998,7 @@
     }
 #endif
 
-log_input_buffers((const char *)temp_buffer->bufferaddr, temp_buffer->buffer_len);
+    log_input_buffers((const char *)temp_buffer->bufferaddr, temp_buffer->buffer_len);
 
 if (buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ) {
         frameinfo.flags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;