Changes for supporting UICC feature

To have UICC support with multiple sysfs entries with
the same volume label, one boolean flag is added to validate
the correct sysfs entry in fstab.qcom

Change-Id: Ic254e514db95fca82552fea3f9b09310ac09b33b
diff --git a/DirectVolume.cpp b/DirectVolume.cpp
index 3076d5a..93ea6e9 100644
--- a/DirectVolume.cpp
+++ b/DirectVolume.cpp
@@ -80,6 +80,7 @@
     mDiskMinor = -1;
     mDiskNumParts = 0;
     mIsDecrypted = 0;
+    mIsValid = true;
 
     if (strcmp(rec->mount_point, "auto") != 0) {
         ALOGE("Vold managed volumes must have auto mount point; ignoring %s",
@@ -129,12 +130,38 @@
     setState(Volume::State_Idle);
 }
 
+int DirectVolume::getUICCVolumeNum(const char *dp) {
+    int mVolNum = -1;
+    if (strstr(dp, ":0:0:0"))
+        mVolNum = 0;
+    else if (strstr(dp, ":0:0:1"))
+        mVolNum = 1;
+
+    return mVolNum;
+}
+
 int DirectVolume::handleBlockEvent(NetlinkEvent *evt) {
     const char *dp = evt->findParam("DEVPATH");
 
     PathCollection::iterator  it;
     for (it = mPaths->begin(); it != mPaths->end(); ++it) {
         if ((*it)->match(dp)) {
+
+            /* Check for UICC prefix in label */
+            if (strstr(getLabel(), "uicc")) {
+                char mLabel[15];
+                int mNum = getUICCVolumeNum(dp);
+                if (mNum < 0) {
+                    SLOGE("Invalid uicc volume number");
+                    continue;
+                }
+
+                snprintf(mLabel, sizeof(mLabel), "uicc%d", mNum);
+                if (strncmp(getLabel(), mLabel, strlen(mLabel)) != 0)
+                    continue;
+            }
+            setValidSysfs(true);
+
             /* We can handle this disk */
             int action = evt->getAction();
             const char *devtype = evt->findParam("DEVTYPE");
diff --git a/DirectVolume.h b/DirectVolume.h
index 5e0df74..421e1d9 100644
--- a/DirectVolume.h
+++ b/DirectVolume.h
@@ -52,6 +52,7 @@
     int            mDiskNumParts;
     int            mPendingPartCount;
     int            mIsDecrypted;
+    bool           mIsValid;
 
 public:
     DirectVolume(VolumeManager *vm, const fstab_rec* rec, int flags);
@@ -61,6 +62,8 @@
 
     const char *getMountpoint() { return mMountpoint; }
     const char *getFuseMountpoint() { return mFuseMountpoint; }
+    bool isValidSysfs() { return mIsValid; }
+    void setValidSysfs(bool val) { mIsValid = val; }
 
     int handleBlockEvent(NetlinkEvent *evt);
     dev_t getDiskDevice();
@@ -84,6 +87,7 @@
     void handlePartitionChanged(const char *devpath, NetlinkEvent *evt);
 
     int doMountVfat(const char *deviceNode, const char *mountPoint);
+    int getUICCVolumeNum(const char *dp);
 
 };
 
diff --git a/Volume.h b/Volume.h
index 1444ed3..c80eca9 100644
--- a/Volume.h
+++ b/Volume.h
@@ -81,6 +81,10 @@
     virtual const char *getMountpoint() = 0;
     virtual const char *getFuseMountpoint() = 0;
 
+    /* validity of the mount points */
+    virtual void setValidSysfs(bool val) = 0;
+    virtual bool isValidSysfs() = 0;
+
     virtual int handleBlockEvent(NetlinkEvent *evt);
     virtual dev_t getDiskDevice();
     virtual dev_t getShareDevice();
diff --git a/VolumeManager.cpp b/VolumeManager.cpp
index 14f1509..f89d0ff 100644
--- a/VolumeManager.cpp
+++ b/VolumeManager.cpp
@@ -54,6 +54,7 @@
 #include "cryptfs.h"
 
 #define MASS_STORAGE_FILE_PATH  "/sys/class/android_usb/android0/f_mass_storage/lun/file"
+#define UICC0_MASS_STORAGE_PATH  "/sys/class/android_usb/android0/f_mass_storage/uicc0/file"
 
 #define ROUND_UP_POWER_OF_2(number, po2) (((!!(number & ((1U << po2) - 1))) << po2)\
                                          + (number & (~((1U << po2) - 1))))
@@ -233,6 +234,16 @@
 }
 
 int VolumeManager::addVolume(Volume *v) {
+    // If entry is duplicated then mark isValid to false for both of them.
+    // Mark the valid entry on the first insertion of the card on handleBlockEvent()
+    VolumeCollection::iterator it;
+    for (it = mVolumes->begin(); it != mVolumes->end(); ++it) {
+        if(!strncmp((*it)->getLabel(), v->getLabel(), strlen((*it)->getLabel()))) {
+            (*it)->setValidSysfs(false);
+            v->setValidSysfs(false);
+        }
+    }
+
     mVolumes->push_back(v);
     return 0;
 }
@@ -265,12 +276,15 @@
     char msg[256];
 
     for (i = mVolumes->begin(); i != mVolumes->end(); ++i) {
-        char *buffer;
-        asprintf(&buffer, "%s %s %d",
-                 (*i)->getLabel(), (*i)->getFuseMountpoint(),
-                 (*i)->getState());
-        cli->sendMsg(ResponseCode::VolumeListResult, buffer, false);
-        free(buffer);
+        if ((*i)->isValidSysfs()) {
+            char *buffer;
+            asprintf(&buffer, "%s %s %d",
+                     (*i)->getLabel(), (*i)->getFuseMountpoint(),
+                     (*i)->getState());
+            cli->sendMsg(ResponseCode::VolumeListResult, buffer, false);
+            free(buffer);
+        }
+
         if (broadcast) {
             if((*i)->getUuid()) {
                 snprintf(msg, sizeof(msg), "%s %s \"%s\"", (*i)->getLabel(),
@@ -1364,9 +1378,11 @@
     VolumeCollection::iterator i;
 
     for (i = mVolumes->begin(); i != mVolumes->end(); ++i) {
-        const char* mountPoint = (*i)->getFuseMountpoint();
-        if (!strncmp(fileName, mountPoint, strlen(mountPoint))) {
-            return *i;
+        if ((*i)->isValidSysfs()) {
+            const char* mountPoint = (*i)->getFuseMountpoint();
+            if (!strncmp(fileName, mountPoint, strlen(mountPoint))) {
+                return *i;
+            }
         }
     }
 
@@ -1583,6 +1599,18 @@
         return -1;
     }
 
+    if (!strncmp(v->getLabel(), "uicc0", strlen("uicc0"))) {
+        if ((fd = open(UICC0_MASS_STORAGE_PATH, O_WRONLY)) < 0) {
+            SLOGE("Unable to open ums lunfile (%s)", strerror(errno));
+            return -1;
+        }
+    } else {
+        if ((fd = open(MASS_STORAGE_FILE_PATH, O_WRONLY)) < 0) {
+            SLOGE("Unable to open ums lunfile (%s)", strerror(errno));
+            return -1;
+        }
+    }
+
     if ((fd = open(MASS_STORAGE_FILE_PATH, O_WRONLY)) < 0) {
         SLOGE("Unable to open ums lunfile (%s)", strerror(errno));
         return -1;
@@ -1677,8 +1705,10 @@
     int n=0;
 
     for (i = mVolumes->begin(); i != mVolumes->end(); ++i) {
-        if ((*i)->getShareDevice() != (dev_t)0) {
-            n++;
+        if ((*i)->isValidSysfs()) {
+            if ((*i)->getShareDevice() != (dev_t)0) {
+                n++;
+            }
         }
     }
     return n;
@@ -1695,11 +1725,13 @@
     dev_t d;
 
     for (i = mVolumes->begin(); i != mVolumes->end(); ++i) {
-        if ((d=(*i)->getShareDevice()) != (dev_t)0) {
-            (*i)->getVolInfo(&vol_list[n]);
-            snprintf(vol_list[n].blk_dev, sizeof(vol_list[n].blk_dev),
-                     "/dev/block/vold/%d:%d", major(d), minor(d));
-            n++;
+        if ((*i)->isValidSysfs()) {
+            if ((d=(*i)->getShareDevice()) != (dev_t)0) {
+                (*i)->getVolInfo(&vol_list[n]);
+                snprintf(vol_list[n].blk_dev, sizeof(vol_list[n].blk_dev),
+                         "/dev/block/vold/%d:%d", major(d), minor(d));
+                n++;
+            }
         }
     }
 
@@ -1794,12 +1826,14 @@
     VolumeCollection::iterator i;
 
     for (i = mVolumes->begin(); i != mVolumes->end(); ++i) {
-        if (label[0] == '/') {
-            if (!strcmp(label, (*i)->getFuseMountpoint()))
-                return (*i);
-        } else {
-            if (!strcmp(label, (*i)->getLabel()))
-                return (*i);
+        if ((*i)->isValidSysfs()) {
+            if (label[0] == '/') {
+                if (!strcmp(label, (*i)->getFuseMountpoint()))
+                    return (*i);
+            } else {
+                if (!strcmp(label, (*i)->getLabel()))
+                    return (*i);
+            }
         }
     }
     return NULL;