Skip to content
This repository was archived by the owner on Dec 24, 2024. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions XBMC.files
Original file line number Diff line number Diff line change
Expand Up @@ -9889,3 +9889,7 @@ lib/libmpeg2/Makefile.am
lib/libmpeg2/configure.ac
lib/libUPnP/Makefile.in
lib/UnrarXLib/Makefile
xbmc/filesystem/StorageDirectory.h
xbmc/filesystem/StorageDirectory.cpp
xbmc/filesystem/StorageFile.h
xbmc/filesystem/StorageFile.cpp
25 changes: 14 additions & 11 deletions tools/android/packaging/xbmc/AndroidManifest.xml.in
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,11 @@
<uses-feature android:name="android.hardware.type.television" android:required="false" />
<uses-feature android:name="android.hardware.usb.host" android:required="false" />
<uses-feature android:name="android.hardware.wifi" android:required="false" />

<application android:icon="@drawable/ic_launcher"
android:logo="@drawable/banner"
android:label="@string/app_name"
android:hasCode="true">
android:logo="@drawable/banner"
android:label="@string/app_name"
android:hasCode="true">
<activity
android:name=".Splash"
android:configChanges="orientation|keyboard|keyboardHidden|navigation|touchscreen|screenLayout|screenSize"
Expand Down Expand Up @@ -100,6 +100,9 @@
<action android:name="android.bluetooth.a2dp.profile.action.CONNECTION_STATE_CHANGED" />
<action android:name="android.intent.action.MEDIA_BUTTON" />
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.MEDIA_MOUNTED" />
<action android:name="android.intent.action.MEDIA_REMOVED" />
<data android:scheme="file" />
</intent-filter>
</receiver>

Expand All @@ -112,15 +115,15 @@
android:name=".XBMCMediaContentProvider"
android:authorities="@[email protected]"
android:exported="true" />

<activity android:name=".XBMCSearchableActivity" >
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
</intent-filter>
<meta-data android:name="android.app.searchable"
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
</intent-filter>
<meta-data android:name="android.app.searchable"
android:resource="@xml/searchable"/>
</activity>
</activity>

</application>

</manifest> <!-- END_INCLUDE(manifest) -->
Expand Down
99 changes: 99 additions & 0 deletions xbmc/android/activity/XBMCApp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@
#include "android/jni/SystemProperties.h"
#include "android/jni/Display.h"
#include "android/jni/View.h"
#include "android/jni/StorageManager.h"

#include "AndroidKey.h"

#include "CompileInfo.h"
Expand Down Expand Up @@ -114,13 +116,15 @@ bool CXBMCApp::m_hasFocus = false;
bool CXBMCApp::m_isResumed = false;
bool CXBMCApp::m_hasAudioFocus = false;
bool CXBMCApp::m_headsetPlugged = false;
CCriticalSection CXBMCApp::m_apiMutex;
CCriticalSection CXBMCApp::m_applicationsMutex;
std::vector<androidPackage> CXBMCApp::m_applications;
std::vector<CActivityResultEvent*> CXBMCApp::m_activityResultEvents;
uint64_t CXBMCApp::m_vsynctime = 0;
CEvent CXBMCApp::m_vsyncEvent;
std::vector<GLuint> CXBMCApp::m_texturePool;
CJNIAudioDeviceInfos CXBMCApp::m_audiodevices;
VECSOURCES CXBMCApp::m_removableDrives;

void LogAudoDevices(const char* stage, const CJNIAudioDeviceInfos& devices)
{
Expand Down Expand Up @@ -932,6 +936,97 @@ bool CXBMCApp::GetStorageUsage(const std::string &path, std::string &usage)
return true;
}

void CXBMCApp::InvalidateRemovableDrives()
{
CSingleLock lock(m_apiMutex);
m_removableDrives.clear();
}

bool CXBMCApp::GetRemovableDrives(VECSOURCES& removableDrives)
{
CSingleLock lock(m_apiMutex);

// Uses non-public API: be extra carefull
bool inError = false;

if (m_removableDrives.empty())
{
CJNIStorageManager manager(CJNIContext::getSystemService("storage"));
if (xbmc_jnienv()->ExceptionCheck())
{
xbmc_jnienv()->ExceptionClear();
inError = true;
}

if (!inError)
{
CJNIStorageVolumes vols = manager.getVolumeList();
if (xbmc_jnienv()->ExceptionCheck())
{
xbmc_jnienv()->ExceptionClear();
inError = true;
}

if (!inError)
{
for (auto vol : vols)
{
// CLog::Log(LOGDEBUG, "-- Volume: %s(%s) -- %s", vol.getPath().c_str(), vol.getUserLabel().c_str(), vol.getState().c_str());
bool removable = vol.isRemovable();
if (xbmc_jnienv()->ExceptionCheck())
{
xbmc_jnienv()->ExceptionClear();
inError = true;
break;
}
std::string state = vol.getState();
if (xbmc_jnienv()->ExceptionCheck())
{
xbmc_jnienv()->ExceptionClear();
inError = true;
break;
}

if (removable && state == CJNIEnvironment::MEDIA_MOUNTED)
{
CMediaSource share;
share.strPath = vol.getPath();
if (xbmc_jnienv()->ExceptionCheck())
{
xbmc_jnienv()->ExceptionClear();
inError = true;
break;
}
share.strDiskUniqueId = vol.getUuid();
if (xbmc_jnienv()->ExceptionCheck())
{
xbmc_jnienv()->ExceptionClear();
inError = true;
break;
}
share.strName = vol.getUserLabel();
if (xbmc_jnienv()->ExceptionCheck())
{
xbmc_jnienv()->ExceptionClear();
inError = true;
break;
}
StringUtils::Trim(share.strName);
if (share.strName.empty() || share.strName == "?" || StringUtils::CompareNoCase(share.strName, "null") == 0)
share.strName = URIUtils::GetFileName(share.strPath);
share.m_ignore = true;
m_removableDrives.push_back(share);
}
}
}
}
}
if (!inError)
removableDrives.insert(removableDrives.end(), m_removableDrives.begin(), m_removableDrives.end());

return !inError;
}

// Used in Application.cpp to figure out volume steps
int CXBMCApp::GetMaxSystemVolume()
{
Expand Down Expand Up @@ -1073,6 +1168,10 @@ void CXBMCApp::onNewIntent(CJNIIntent intent)
CApplicationMessenger::GetInstance().PostMsg(TMSG_GUI_ACTIVATE_WINDOW, WINDOW_MUSIC_NAV, 0, nullptr, "", params);
}
}
else if (action == "android.intent.action.MEDIA_MOUNTED" || action == "android.intent.action.MEDIA_REMOVED")
{
InvalidateRemovableDrives();
}
}

void CXBMCApp::onActivityResult(int requestCode, int resultCode, CJNIIntent resultData)
Expand Down
7 changes: 7 additions & 0 deletions xbmc/android/activity/XBMCApp.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@

#include "IActivityHandler.h"
#include "IInputHandler.h"
#include "storage/IStorageProvider.h"

#include "xbmc.h"
#include "android/jni/Activity.h"
Expand Down Expand Up @@ -153,6 +154,9 @@ class CXBMCApp
*/
static bool GetExternalStorage(std::string &path, const std::string &type = "");
static bool GetStorageUsage(const std::string &path, std::string &usage);
static void InvalidateRemovableDrives();
static bool GetRemovableDrives(VECSOURCES& removableDrives);

static int GetMaxSystemVolume();
static float GetSystemVolume();
static void SetSystemVolume(float percent);
Expand Down Expand Up @@ -208,10 +212,13 @@ class CXBMCApp
bool m_firstrun;
bool m_exiting;
pthread_t m_thread;
static CCriticalSection m_apiMutex;
static CCriticalSection m_applicationsMutex;
static std::vector<androidPackage> m_applications;
static std::vector<CActivityResultEvent*> m_activityResultEvents;

static VECSOURCES m_removableDrives;

static ANativeWindow* m_window;
static CEvent m_windowCreated;
static std::vector<GLuint> m_texturePool;
Expand Down
3 changes: 3 additions & 0 deletions xbmc/filesystem/DirectoryFactory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@
#include "HTTPDirectory.h"
#include "DAVDirectory.h"
#include "UDFDirectory.h"
#include "StorageDirectory.h"

#include "Application.h"
#include "utils/log.h"
#include "network/WakeOnAccess.h"
Expand Down Expand Up @@ -130,6 +132,7 @@ IDirectory* CDirectoryFactory::Create(const CURL& url)
#error Local directory access is not implemented for this platform
#endif
if (url.IsProtocol("special")) return new CSpecialProtocolDirectory();
if (url.IsProtocol("storage")) return new CStorageDirectory();
if (url.IsProtocol("sources")) return new CSourcesDirectory();
if (url.IsProtocol("addons")) return new CAddonsDirectory();
#if defined(HAS_FILESYSTEM_CDDA) && defined(HAS_DVD_DRIVE)
Expand Down
5 changes: 4 additions & 1 deletion xbmc/filesystem/FileFactory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@
#include "UDFFile.h"
#include "ImageFile.h"
#include "ResourceFile.h"
#include "StorageFile.h"

#include "Application.h"
#include "URL.h"
#include "utils/log.h"
Expand Down Expand Up @@ -127,13 +129,14 @@ IFile* CFileFactory::CreateLoader(const CURL& url)
else if (url.IsProtocol("musicdb")) return new CMusicDatabaseFile();
else if (url.IsProtocol("videodb")) return new CVideoDatabaseFile();
else if (url.IsProtocol("special")) return new CSpecialProtocolFile();
else if (url.IsProtocol("storage")) return new CStorageFile();
else if (url.IsProtocol("multipath")) return new CMultiPathFile();
else if (url.IsProtocol("image")) return new CImageFile();
#ifdef TARGET_POSIX
else if (url.IsProtocol("file") || url.GetProtocol().empty()) return new CPosixFile();
#elif defined(TARGET_WINDOWS)
else if (url.IsProtocol("file") || url.GetProtocol().empty()) return new CWin32File();
#endif // TARGET_WINDOWS
#endif // TARGET_WINDOWS
else if (url.IsProtocol("filereader")) return new CFileReaderFile();
#if defined(HAS_FILESYSTEM_CDDA) && defined(HAS_DVD_DRIVE)
else if (url.IsProtocol("cdda")) return new CFileCDDA();
Expand Down
2 changes: 2 additions & 0 deletions xbmc/filesystem/Makefile.in
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ SRCS += ZeroconfDirectory.cpp
SRCS += ZipDirectory.cpp
SRCS += ZipFile.cpp
SRCS += ZipManager.cpp
SRCS += StorageDirectory.cpp
SRCS += StorageFile.cpp

ifeq (@USE_ANDROID@,1)
SRCS += APKDirectory.cpp
Expand Down
90 changes: 90 additions & 0 deletions xbmc/filesystem/StorageDirectory.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/*
* Copyright (C) 2016 Christian Browet
* http://xbmc.org
*
* This Program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This Program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with XBMC; see the file COPYING. If not, see
* <http://www.gnu.org/licenses/>.
*
*/

#include "StorageDirectory.h"

#include "Directory.h"
#include "FileItem.h"
#include "URL.h"

#include "utils/URIUtils.h"
#include "utils/StringUtils.h"
#include "utils/log.h"

#ifdef TARGET_ANDROID
#include "android/activity/XBMCApp.h"
#endif

using namespace XFILE;

CStorageDirectory::CStorageDirectory()
{
}

CStorageDirectory::~CStorageDirectory()
{
}

bool CStorageDirectory::GetDirectory(const CURL& url, CFileItemList &items)
{
const std::string pathToUrl(url.Get());
std::string translatedPath = TranslatePath(url);
if (CDirectory::GetDirectory(translatedPath, items, m_strFileMask, m_flags | DIR_FLAG_GET_HIDDEN))
{ // replace our paths as necessary
items.SetURL(url);
for (int i = 0; i < items.Size(); i++)
{
CFileItemPtr item = items[i];
if (StringUtils::StartsWith(item->GetPath(), translatedPath))
item->SetPath(URIUtils::AddFileToFolder(pathToUrl, item->GetPath().substr(translatedPath.size())));
}
return true;
}
return false;
}

std::string CStorageDirectory::TranslatePath(const CURL &url)
{
return TranslatePathImpl(url);
}

std::string CStorageDirectory::TranslatePathImpl(const CURL& url)
{
std::string returl;
std::string uuid = url.GetHostName();

#ifdef TARGET_ANDROID
VECSOURCES drives;
if (CXBMCApp::GetRemovableDrives(drives))
{
for (auto d : drives)
{
if (d.strDiskUniqueId == uuid)
{
returl = URIUtils::AddFileToFolder(d.strPath, url.GetFileName());
// CLog::Log(LOGDEBUG, "CStorageDirectory: translated %s to %s", url.Get().c_str(), returl.c_str());
}
}
}
#endif

return returl;
}

Loading