do not merge: Cherry pick change I6529695c from master to partially fix bug 4126624.

Change-Id: If724de60bd6da1becdffc815d5358ffe78629469
diff --git a/drm/common/IDrmManagerService.cpp b/drm/common/IDrmManagerService.cpp
index 696e305..16f1dd0 100644
--- a/drm/common/IDrmManagerService.cpp
+++ b/drm/common/IDrmManagerService.cpp
@@ -37,6 +37,63 @@
 
 using namespace android;
 
+static void writeDecrptHandleToParcelData(
+        const DecryptHandle* handle, Parcel* data) {
+    data->writeInt32(handle->decryptId);
+    data->writeString8(handle->mimeType);
+    data->writeInt32(handle->decryptApiType);
+    data->writeInt32(handle->status);
+
+    int size = handle->copyControlVector.size();
+    data->writeInt32(size);
+    for(int i = 0; i < size; i++) {
+        data->writeInt32(handle->copyControlVector.keyAt(i));
+        data->writeInt32(handle->copyControlVector.valueAt(i));
+    }
+
+    if (NULL != handle->decryptInfo) {
+        data->writeInt32(handle->decryptInfo->decryptBufferLength);
+    } else {
+        data->writeInt32(INVALID_BUFFER_LENGTH);
+    }
+}
+
+static void readDecryptHandleFromParcelData(
+        DecryptHandle* handle, const Parcel& data) {
+    if (0 == data.dataAvail()) {
+        return;
+    }
+
+    handle->decryptId = data.readInt32();
+    handle->mimeType = data.readString8();
+    handle->decryptApiType = data.readInt32();
+    handle->status = data.readInt32();
+
+    int size = data.readInt32();
+    for (int i = 0; i < size; i ++) {
+        handle->copyControlVector.add(
+                (DrmCopyControl)data.readInt32(), data.readInt32());
+    }
+
+    handle->decryptInfo = NULL;
+    const int bufferLen = data.readInt32();
+    if (INVALID_BUFFER_LENGTH != bufferLen) {
+        handle->decryptInfo = new DecryptInfo();
+        handle->decryptInfo->decryptBufferLength = bufferLen;
+    }
+}
+
+static void clearDecryptHandle(DecryptHandle* handle) {
+    if (handle == NULL) {
+        return;
+    }
+    if (handle->decryptInfo) {
+        delete handle->decryptInfo;
+        handle->decryptInfo = NULL;
+    }
+    handle->copyControlVector.clear();
+}
+
 int BpDrmManagerService::addUniqueId(int uniqueId) {
     LOGV("add uniqueid");
     Parcel data, reply;
@@ -344,16 +401,7 @@
     data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor());
     data.writeInt32(uniqueId);
 
-    data.writeInt32(decryptHandle->decryptId);
-    data.writeString8(decryptHandle->mimeType);
-    data.writeInt32(decryptHandle->decryptApiType);
-    data.writeInt32(decryptHandle->status);
-
-    if (NULL != decryptHandle->decryptInfo) {
-        data.writeInt32(decryptHandle->decryptInfo->decryptBufferLength);
-    } else {
-        data.writeInt32(INVALID_BUFFER_LENGTH);
-    }
+    writeDecrptHandleToParcelData(decryptHandle, &data);
 
     data.writeInt32(action);
     data.writeInt32(static_cast< int>(reserve));
@@ -370,16 +418,7 @@
     data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor());
     data.writeInt32(uniqueId);
 
-    data.writeInt32(decryptHandle->decryptId);
-    data.writeString8(decryptHandle->mimeType);
-    data.writeInt32(decryptHandle->decryptApiType);
-    data.writeInt32(decryptHandle->status);
-
-    if (NULL != decryptHandle->decryptInfo) {
-        data.writeInt32(decryptHandle->decryptInfo->decryptBufferLength);
-    } else {
-        data.writeInt32(INVALID_BUFFER_LENGTH);
-    }
+    writeDecrptHandleToParcelData(decryptHandle, &data);
 
     data.writeInt32(playbackStatus);
     data.writeInt64(position);
@@ -560,15 +599,7 @@
     DecryptHandle* handle = NULL;
     if (0 != reply.dataAvail()) {
         handle = new DecryptHandle();
-        handle->decryptId = reply.readInt32();
-        handle->mimeType = reply.readString8();
-        handle->decryptApiType = reply.readInt32();
-        handle->status = reply.readInt32();
-        handle->decryptInfo = NULL;
-        if (0 != reply.dataAvail()) {
-            handle->decryptInfo = new DecryptInfo();
-            handle->decryptInfo->decryptBufferLength = reply.readInt32();
-        }
+        readDecryptHandleFromParcelData(handle, reply);
     }
     return handle;
 }
@@ -586,15 +617,7 @@
     DecryptHandle* handle = NULL;
     if (0 != reply.dataAvail()) {
         handle = new DecryptHandle();
-        handle->decryptId = reply.readInt32();
-        handle->mimeType = reply.readString8();
-        handle->decryptApiType = reply.readInt32();
-        handle->status = reply.readInt32();
-        handle->decryptInfo = NULL;
-        if (0 != reply.dataAvail()) {
-            handle->decryptInfo = new DecryptInfo();
-            handle->decryptInfo->decryptBufferLength = reply.readInt32();
-        }
+        readDecryptHandleFromParcelData(handle, reply);
     } else {
         LOGV("no decryptHandle is generated in service side");
     }
@@ -608,16 +631,7 @@
     data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor());
     data.writeInt32(uniqueId);
 
-    data.writeInt32(decryptHandle->decryptId);
-    data.writeString8(decryptHandle->mimeType);
-    data.writeInt32(decryptHandle->decryptApiType);
-    data.writeInt32(decryptHandle->status);
-
-    if (NULL != decryptHandle->decryptInfo) {
-        data.writeInt32(decryptHandle->decryptInfo->decryptBufferLength);
-    } else {
-        data.writeInt32(INVALID_BUFFER_LENGTH);
-    }
+    writeDecrptHandleToParcelData(decryptHandle, &data);
 
     remote()->transact(CLOSE_DECRYPT_SESSION, data, &reply);
 
@@ -638,16 +652,8 @@
     data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor());
     data.writeInt32(uniqueId);
 
-    data.writeInt32(decryptHandle->decryptId);
-    data.writeString8(decryptHandle->mimeType);
-    data.writeInt32(decryptHandle->decryptApiType);
-    data.writeInt32(decryptHandle->status);
+    writeDecrptHandleToParcelData(decryptHandle, &data);
 
-    if (NULL != decryptHandle->decryptInfo) {
-        data.writeInt32(decryptHandle->decryptInfo->decryptBufferLength);
-    } else {
-        data.writeInt32(INVALID_BUFFER_LENGTH);
-    }
     data.writeInt32(decryptUnitId);
 
     data.writeInt32(headerInfo->length);
@@ -666,16 +672,7 @@
     data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor());
     data.writeInt32(uniqueId);
 
-    data.writeInt32(decryptHandle->decryptId);
-    data.writeString8(decryptHandle->mimeType);
-    data.writeInt32(decryptHandle->decryptApiType);
-    data.writeInt32(decryptHandle->status);
-
-    if (NULL != decryptHandle->decryptInfo) {
-        data.writeInt32(decryptHandle->decryptInfo->decryptBufferLength);
-    } else {
-        data.writeInt32(INVALID_BUFFER_LENGTH);
-    }
+    writeDecrptHandleToParcelData(decryptHandle, &data);
 
     data.writeInt32(decryptUnitId);
     data.writeInt32((*decBuffer)->length);
@@ -708,16 +705,7 @@
     data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor());
     data.writeInt32(uniqueId);
 
-    data.writeInt32(decryptHandle->decryptId);
-    data.writeString8(decryptHandle->mimeType);
-    data.writeInt32(decryptHandle->decryptApiType);
-    data.writeInt32(decryptHandle->status);
-
-    if (NULL != decryptHandle->decryptInfo) {
-        data.writeInt32(decryptHandle->decryptInfo->decryptBufferLength);
-    } else {
-        data.writeInt32(INVALID_BUFFER_LENGTH);
-    }
+    writeDecrptHandleToParcelData(decryptHandle, &data);
 
     data.writeInt32(decryptUnitId);
 
@@ -735,16 +723,7 @@
     data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor());
     data.writeInt32(uniqueId);
 
-    data.writeInt32(decryptHandle->decryptId);
-    data.writeString8(decryptHandle->mimeType);
-    data.writeInt32(decryptHandle->decryptApiType);
-    data.writeInt32(decryptHandle->status);
-
-    if (NULL != decryptHandle->decryptInfo) {
-        data.writeInt32(decryptHandle->decryptInfo->decryptBufferLength);
-    } else {
-        data.writeInt32(INVALID_BUFFER_LENGTH);
-    }
+    writeDecrptHandleToParcelData(decryptHandle, &data);
 
     data.writeInt32(numBytes);
     data.writeInt64(offset);
@@ -1069,24 +1048,14 @@
         const int uniqueId = data.readInt32();
 
         DecryptHandle handle;
-        handle.decryptId = data.readInt32();
-        handle.mimeType = data.readString8();
-        handle.decryptApiType = data.readInt32();
-        handle.status = data.readInt32();
-        handle.decryptInfo = NULL;
-
-        const int bufferLength = data.readInt32();
-        if (INVALID_BUFFER_LENGTH != bufferLength) {
-            handle.decryptInfo = new DecryptInfo();
-            handle.decryptInfo->decryptBufferLength = bufferLength;
-        }
+        readDecryptHandleFromParcelData(&handle, data);
 
         const status_t status
             = consumeRights(uniqueId, &handle, data.readInt32(),
                 static_cast<bool>(data.readInt32()));
         reply->writeInt32(status);
 
-        delete handle.decryptInfo; handle.decryptInfo = NULL;
+        clearDecryptHandle(&handle);
         return DRM_NO_ERROR;
     }
 
@@ -1098,23 +1067,13 @@
         const int uniqueId = data.readInt32();
 
         DecryptHandle handle;
-        handle.decryptId = data.readInt32();
-        handle.mimeType = data.readString8();
-        handle.decryptApiType = data.readInt32();
-        handle.status = data.readInt32();
-        handle.decryptInfo = NULL;
-
-        const int bufferLength = data.readInt32();
-        if (INVALID_BUFFER_LENGTH != bufferLength) {
-            handle.decryptInfo = new DecryptInfo();
-            handle.decryptInfo->decryptBufferLength = bufferLength;
-        }
+        readDecryptHandleFromParcelData(&handle, data);
 
         const status_t status
             = setPlaybackStatus(uniqueId, &handle, data.readInt32(), data.readInt64());
         reply->writeInt32(status);
 
-        delete handle.decryptInfo; handle.decryptInfo = NULL;
+        clearDecryptHandle(&handle);
         return DRM_NO_ERROR;
     }
 
@@ -1275,16 +1234,10 @@
             = openDecryptSession(uniqueId, fd, data.readInt64(), data.readInt64());
 
         if (NULL != handle) {
-            reply->writeInt32(handle->decryptId);
-            reply->writeString8(handle->mimeType);
-            reply->writeInt32(handle->decryptApiType);
-            reply->writeInt32(handle->status);
-            if (NULL != handle->decryptInfo) {
-                reply->writeInt32(handle->decryptInfo->decryptBufferLength);
-                delete handle->decryptInfo; handle->decryptInfo = NULL;
-            }
+            writeDecrptHandleToParcelData(handle, reply);
+            clearDecryptHandle(handle);
+            delete handle; handle = NULL;
         }
-        delete handle; handle = NULL;
         return DRM_NO_ERROR;
     }
 
@@ -1299,18 +1252,13 @@
         DecryptHandle* handle = openDecryptSession(uniqueId, uri.string());
 
         if (NULL != handle) {
-            reply->writeInt32(handle->decryptId);
-            reply->writeString8(handle->mimeType);
-            reply->writeInt32(handle->decryptApiType);
-            reply->writeInt32(handle->status);
-            if (NULL != handle->decryptInfo) {
-                reply->writeInt32(handle->decryptInfo->decryptBufferLength);
-                delete handle->decryptInfo; handle->decryptInfo = NULL;
-            }
+            writeDecrptHandleToParcelData(handle, reply);
+
+            clearDecryptHandle(handle);
+            delete handle; handle = NULL;
         } else {
             LOGV("NULL decryptHandle is returned");
         }
-        delete handle; handle = NULL;
         return DRM_NO_ERROR;
     }
 
@@ -1322,17 +1270,7 @@
         const int uniqueId = data.readInt32();
 
         DecryptHandle* handle = new DecryptHandle();
-        handle->decryptId = data.readInt32();
-        handle->mimeType = data.readString8();
-        handle->decryptApiType = data.readInt32();
-        handle->status = data.readInt32();
-        handle->decryptInfo = NULL;
-
-        const int bufferLength = data.readInt32();
-        if (INVALID_BUFFER_LENGTH != bufferLength) {
-            handle->decryptInfo = new DecryptInfo();
-            handle->decryptInfo->decryptBufferLength = bufferLength;
-        }
+        readDecryptHandleFromParcelData(handle, data);
 
         const status_t status = closeDecryptSession(uniqueId, handle);
         reply->writeInt32(status);
@@ -1347,17 +1285,8 @@
         const int uniqueId = data.readInt32();
 
         DecryptHandle handle;
-        handle.decryptId = data.readInt32();
-        handle.mimeType = data.readString8();
-        handle.decryptApiType = data.readInt32();
-        handle.status = data.readInt32();
-        handle.decryptInfo = NULL;
+        readDecryptHandleFromParcelData(&handle, data);
 
-        const int bufferLength = data.readInt32();
-        if (INVALID_BUFFER_LENGTH != bufferLength) {
-            handle.decryptInfo = new DecryptInfo();
-            handle.decryptInfo->decryptBufferLength = bufferLength;
-        }
         const int decryptUnitId = data.readInt32();
 
         //Filling Header info
@@ -1369,7 +1298,7 @@
             = initializeDecryptUnit(uniqueId, &handle, decryptUnitId, headerInfo);
         reply->writeInt32(status);
 
-        delete handle.decryptInfo; handle.decryptInfo = NULL;
+        clearDecryptHandle(&handle);
         delete headerInfo; headerInfo = NULL;
         return DRM_NO_ERROR;
     }
@@ -1382,17 +1311,8 @@
         const int uniqueId = data.readInt32();
 
         DecryptHandle handle;
-        handle.decryptId = data.readInt32();
-        handle.mimeType = data.readString8();
-        handle.decryptApiType = data.readInt32();
-        handle.status = data.readInt32();
-        handle.decryptInfo = NULL;
+        readDecryptHandleFromParcelData(&handle, data);
 
-        const int bufferLength = data.readInt32();
-        if (INVALID_BUFFER_LENGTH != bufferLength) {
-            handle.decryptInfo = new DecryptInfo();
-            handle.decryptInfo->decryptBufferLength = bufferLength;
-        }
         const int decryptUnitId = data.readInt32();
         const int decBufferSize = data.readInt32();
 
@@ -1419,7 +1339,7 @@
         reply->writeInt32(size);
         reply->write(decBuffer->data, size);
 
-        delete handle.decryptInfo; handle.decryptInfo = NULL;
+        clearDecryptHandle(&handle);
         delete encBuffer; encBuffer = NULL;
         delete decBuffer; decBuffer = NULL;
         delete [] buffer; buffer = NULL;
@@ -1435,22 +1355,12 @@
         const int uniqueId = data.readInt32();
 
         DecryptHandle handle;
-        handle.decryptId = data.readInt32();
-        handle.mimeType = data.readString8();
-        handle.decryptApiType = data.readInt32();
-        handle.status = data.readInt32();
-        handle.decryptInfo = NULL;
-
-        const int bufferLength = data.readInt32();
-        if (INVALID_BUFFER_LENGTH != bufferLength) {
-            handle.decryptInfo = new DecryptInfo();
-            handle.decryptInfo->decryptBufferLength = bufferLength;
-        }
+        readDecryptHandleFromParcelData(&handle, data);
 
         const status_t status = finalizeDecryptUnit(uniqueId, &handle, data.readInt32());
         reply->writeInt32(status);
 
-        delete handle.decryptInfo; handle.decryptInfo = NULL;
+        clearDecryptHandle(&handle);
         return DRM_NO_ERROR;
     }
 
@@ -1462,17 +1372,7 @@
         const int uniqueId = data.readInt32();
 
         DecryptHandle handle;
-        handle.decryptId = data.readInt32();
-        handle.mimeType = data.readString8();
-        handle.decryptApiType = data.readInt32();
-        handle.status = data.readInt32();
-        handle.decryptInfo = NULL;
-
-        const int bufferLength = data.readInt32();
-        if (INVALID_BUFFER_LENGTH != bufferLength) {
-            handle.decryptInfo = new DecryptInfo();
-            handle.decryptInfo->decryptBufferLength = bufferLength;
-        }
+        readDecryptHandleFromParcelData(&handle, data);
 
         const int numBytes = data.readInt32();
         char* buffer = new char[numBytes];
@@ -1485,7 +1385,7 @@
             reply->write(buffer, result);
         }
 
-        delete handle.decryptInfo; handle.decryptInfo = NULL;
+        clearDecryptHandle(&handle);
         delete [] buffer, buffer = NULL;
         return DRM_NO_ERROR;
     }
diff --git a/include/drm/drm_framework_common.h b/include/drm/drm_framework_common.h
index 1758cdd..e8ec953 100644
--- a/include/drm/drm_framework_common.h
+++ b/include/drm/drm_framework_common.h
@@ -43,6 +43,17 @@
 };
 
 /**
+ * copy control settings used in DecryptHandle::copyControlVector
+ */
+enum DrmCopyControl {
+    DRM_COPY_CONTROL_BASE = 1000,
+    // the key used to set the value for HDCP
+    // if the associated value is 1, then HDCP is required
+    // otherwise, HDCP is not required
+    DRM_COPY_CONTROL_HDCP = DRM_COPY_CONTROL_BASE
+};
+
+/**
  * Defines DRM Buffer
  */
 class DrmBuffer {
@@ -279,6 +290,11 @@
      * e.g. size of memory to be allocated to get the decrypted content.
      */
     DecryptInfo* decryptInfo;
+    /**
+     * Defines a vector for the copy control settings sent from the DRM plugin
+     * to the player
+     */
+    KeyedVector<DrmCopyControl, int> copyControlVector;
 
 public:
     DecryptHandle():