FIX: [droid] handle usb storage
authorChris "Koying" Browet <cbro@semperpax.com>
Sat, 28 Dec 2013 12:38:31 +0000 (13:38 +0100)
committerChris "Koying" Browet <cbro@semperpax.com>
Sat, 28 Dec 2013 12:40:57 +0000 (13:40 +0100)
xbmc/storage/android/AndroidStorageProvider.cpp
xbmc/storage/android/AndroidStorageProvider.h

index 3fade50..8fc56f4 100644 (file)
 #include "guilib/LocalizeStrings.h"
 #include "filesystem/File.h"
 
-//#include "utils/RegExp.h"
-//#include "utils/StdString.h"
-//#include "Util.h"
+#include "utils/log.h"
+#include "utils/RegExp.h"
+#include "utils/StringUtils.h"
+#include "utils/URIUtils.h"
+
+CAndroidStorageProvider::CAndroidStorageProvider()
+{
+  m_removableLength = 0;
+  PumpDriveChangeEvents(NULL);
+}
+
+std::string CAndroidStorageProvider::unescape(const std::string& str)
+{
+  std::string retString;
+  for (uint32_t i=0; i < str.length(); ++i)
+  {
+    if (str[i] != '\\')
+      retString += str[i];
+    else
+    {
+      i += 1;
+      if (str[i] == 'u') // unicode
+      {
+        // TODO
+      }
+      else if (str[i] >= '0' && str[i] <= '7') // octal
+      {
+        std::string octString;
+        while (str[i] >= '0' && str[i] <= '7')
+        {
+          octString += str[i];
+          i += 1;
+        }
+        if (octString.length() != 0)
+        {
+          uint8_t val = 0;
+          for (int j=octString.length()-1; j>=0; --j)
+          {
+            val += ((uint8_t)(octString[j] - '0')) * (1 << ((octString.length() - (j+1)) * 3));
+          }
+          retString += (char)val;
+          i -= 1;
+        }
+      }
+    }
+  }
+  return retString;
+}
 
 void CAndroidStorageProvider::GetLocalDrives(VECSOURCES &localDrives)
 {
@@ -49,7 +94,55 @@ void CAndroidStorageProvider::GetLocalDrives(VECSOURCES &localDrives)
 
 void CAndroidStorageProvider::GetRemovableDrives(VECSOURCES &removableDrives)
 {
-  // TODO
+  // mounted usb disks
+  std::vector<CStdString> result;
+  CRegExp reMount;
+  reMount.RegComp("^(.+?)\\s+(.+?)\\s+(.+?)\\s");
+  char line[1024];
+
+  FILE* pipe = fopen("/proc/mounts", "r");
+
+  if (pipe)
+  {
+    while (fgets(line, sizeof(line) - 1, pipe))
+    {
+      if (reMount.RegFind(line) != -1)
+      {
+        bool accepted = false;
+        std::string mountStr = reMount.GetReplaceString("\\2");
+        std::string fsStr    = reMount.GetReplaceString("\\3");
+        const char* mount = mountStr.c_str();
+        const char* fs    = fsStr.c_str();
+
+        // Here we choose which filesystems are approved
+        if (strcmp(fs, "fuseblk") == 0 || strcmp(fs, "vfat") == 0
+            || strcmp(fs, "ext2") == 0 || strcmp(fs, "ext3") == 0 || strcmp(fs, "ext4") == 0
+            || strcmp(fs, "reiserfs") == 0 || strcmp(fs, "xfs") == 0
+            || strcmp(fs, "ntfs-3g") == 0 || strcmp(fs, "iso9660") == 0
+            || strcmp(fs, "exfat") == 0
+            || strcmp(fs, "fusefs") == 0 || strcmp(fs, "hfs") == 0)
+          accepted = true;
+
+        // Ignore everything but usb
+        if (!StringUtils::StartsWith(mountStr, "/mnt/usb"))
+          accepted = false;
+
+        if(accepted)
+          result.push_back(mount);
+      }
+    }
+    fclose(pipe);
+  } else
+    CLog::Log(LOGERROR, "Cannot read mount points");
+
+  for (unsigned int i = 0; i < result.size(); i++)
+  {
+    CMediaSource share;
+    share.strPath = unescape(result[i]);
+    share.strName = URIUtils::GetFileName(share.strPath);
+    share.m_ignore = true;
+    removableDrives.push_back(share);
+  }
 }
 
 std::vector<CStdString> CAndroidStorageProvider::GetDiskUsage()
@@ -73,6 +166,16 @@ std::vector<CStdString> CAndroidStorageProvider::GetDiskUsage()
       CXBMCApp::GetStorageUsage(path, usage) && !usage.empty())
     result.push_back(usage);
 
+  // add removable storage
+  VECSOURCES drives;
+  GetRemovableDrives(drives);
+  for (unsigned int i = 0; i < drives.size(); i++)
+  {
+    usage.clear();
+    if (CXBMCApp::GetStorageUsage(drives[i].strPath, usage) && !usage.empty())
+      result.push_back(usage);
+  }
+
   return result;
 }
 
@@ -83,5 +186,9 @@ bool CAndroidStorageProvider::Eject(CStdString mountpath)
 
 bool CAndroidStorageProvider::PumpDriveChangeEvents(IStorageEventsCallback *callback)
 {
-  return false;
+  VECSOURCES drives;
+  GetRemovableDrives(drives);
+  bool changed = drives.size() != m_removableLength;
+  m_removableLength = drives.size();
+  return changed;
 }
index aa9ce35..0ffe2a5 100644 (file)
@@ -24,7 +24,7 @@
 class CAndroidStorageProvider : public IStorageProvider
 {
 public:
-  CAndroidStorageProvider() { }
+  CAndroidStorageProvider();
   virtual ~CAndroidStorageProvider() { }
 
   virtual void Initialize() { }
@@ -38,4 +38,8 @@ public:
   virtual std::vector<CStdString> GetDiskUsage();
 
   virtual bool PumpDriveChangeEvents(IStorageEventsCallback *callback);
+
+private:
+  std::string unescape(const std::string& str);
+  unsigned int m_removableLength;
 };