Fix for not ending up in an eternal loop in DrmManager.

In the original code a random number is used to get try
to find an empty slot in the list of free DRM id's.
When you reached the limit of 0xfff id's you ended up
in an eternal loop causing ANRs.

Updated by James Dong <jdong@google.com>.

Change-Id: I70176cc3f770223c4a8060f9739fe2bc03a703d9
diff --git a/drm/drmserver/DrmManager.cpp b/drm/drmserver/DrmManager.cpp
index e7b0e90..bfaf4bc 100644
--- a/drm/drmserver/DrmManager.cpp
+++ b/drm/drmserver/DrmManager.cpp
@@ -42,7 +42,8 @@
 DrmManager::DrmManager() :
     mDecryptSessionId(0),
     mConvertId(0) {
-
+    srand(time(NULL));
+    memset(mUniqueIdArray, 0, sizeof(bool) * kMaxNumUniqueIds);
 }
 
 DrmManager::~DrmManager() {
@@ -52,48 +53,37 @@
 int DrmManager::addUniqueId(bool isNative) {
     Mutex::Autolock _l(mLock);
 
-    int temp = 0;
-    bool foundUniqueId = false;
-    const int size = mUniqueIdVector.size();
-    const int uniqueIdRange = 0xfff;
-    int maxLoopTimes = (uniqueIdRange - 1) / 2;
-    srand(time(NULL));
+    int uniqueId = -1;
+    int random = rand();
 
-    while (!foundUniqueId) {
-        temp = rand() & uniqueIdRange;
+    for (size_t index = 0; index < kMaxNumUniqueIds; ++index) {
+        int temp = (random + index) % kMaxNumUniqueIds;
+        if (!mUniqueIdArray[temp]) {
+            uniqueId = temp;
+            mUniqueIdArray[uniqueId] = true;
 
-        if (isNative) {
-            // set a flag to differentiate DrmManagerClient
-            // created from native side and java side
-            temp |= 0x1000;
-        }
-
-        int index = 0;
-        for (; index < size; ++index) {
-            if (mUniqueIdVector.itemAt(index) == temp) {
-                foundUniqueId = false;
-                break;
+            if (isNative) {
+                // set a flag to differentiate DrmManagerClient
+                // created from native side and java side
+                uniqueId |= 0x1000;
             }
+            break;
         }
-        if (index == size) {
-            foundUniqueId = true;
-        }
-
-        maxLoopTimes --;
-        LOG_FATAL_IF(maxLoopTimes <= 0, "cannot find an unique ID for this session");
     }
 
-    mUniqueIdVector.push(temp);
-    return temp;
+    // -1 indicates that no unique id can be allocated.
+    return uniqueId;
 }
 
 void DrmManager::removeUniqueId(int uniqueId) {
     Mutex::Autolock _l(mLock);
-    for (unsigned int i = 0; i < mUniqueIdVector.size(); i++) {
-        if (uniqueId == mUniqueIdVector.itemAt(i)) {
-            mUniqueIdVector.removeAt(i);
-            break;
-        }
+    if (uniqueId & 0x1000) {
+        // clear the flag for the native side.
+        uniqueId &= ~(0x1000);
+    }
+
+    if (uniqueId >= 0 && uniqueId < kMaxNumUniqueIds) {
+        mUniqueIdArray[uniqueId] = false;
     }
 }
 
diff --git a/drm/libdrmframework/include/DrmManager.h b/drm/libdrmframework/include/DrmManager.h
index 491e8f7..8ab693f 100644
--- a/drm/libdrmframework/include/DrmManager.h
+++ b/drm/libdrmframework/include/DrmManager.h
@@ -144,7 +144,11 @@
     bool canHandle(int uniqueId, const String8& path);
 
 private:
-    Vector<int> mUniqueIdVector;
+    enum {
+        kMaxNumUniqueIds = 0x1000,
+    };
+
+    bool mUniqueIdArray[kMaxNumUniqueIds];
     static const String8 EMPTY_STRING;
 
     int mDecryptSessionId;