forked from organicmaps/organicmaps-tmp
Add free storage space handler to download button in map.
This commit is contained in:
parent
89d6932057
commit
167afe38c5
6 changed files with 106 additions and 55 deletions
|
@ -1,6 +1,4 @@
|
|||
#include <jni.h>
|
||||
// To get free disk space
|
||||
#include <sys/vfs.h>
|
||||
|
||||
#include "../../../../../defines.hpp"
|
||||
|
||||
|
@ -25,15 +23,15 @@
|
|||
#include "Framework.hpp"
|
||||
|
||||
|
||||
// Special error codes to notify GUI about free space
|
||||
/// Special error codes to notify GUI about free space
|
||||
//@{
|
||||
#define ERR_DOWNLOAD_SUCCESS 0
|
||||
#define ERR_NOT_ENOUGH_MEMORY -1
|
||||
#define ERR_NOT_ENOUGH_FREE_SPACE -2
|
||||
#define ERR_STORAGE_DISCONNECTED -3
|
||||
#define ERR_DOWNLOAD_ERROR -4
|
||||
#define ERR_NO_MORE_FILES -5
|
||||
#define ERR_FILE_IN_PROGRESS -6
|
||||
#define ERR_DOWNLOAD_SUCCESS 0
|
||||
#define ERR_NOT_ENOUGH_MEMORY -1
|
||||
#define ERR_NOT_ENOUGH_FREE_SPACE -2
|
||||
#define ERR_STORAGE_DISCONNECTED -3
|
||||
#define ERR_DOWNLOAD_ERROR -4
|
||||
#define ERR_NO_MORE_FILES -5
|
||||
#define ERR_FILE_IN_PROGRESS -6
|
||||
//@}
|
||||
|
||||
struct FileToDownload
|
||||
|
@ -55,15 +53,12 @@ extern "C"
|
|||
{
|
||||
int HasSpaceForFiles(string const & sdcardPath, size_t fileSize)
|
||||
{
|
||||
struct statfs st;
|
||||
|
||||
if (statfs(sdcardPath.c_str(), &st) != 0)
|
||||
return ERR_STORAGE_DISCONNECTED;
|
||||
|
||||
if (st.f_bsize * st.f_bavail <= fileSize)
|
||||
return ERR_NOT_ENOUGH_FREE_SPACE;
|
||||
|
||||
return fileSize;
|
||||
switch (GetPlatform().GetWritableStorageStatus(fileSize))
|
||||
{
|
||||
case Platform::STORAGE_DISCONNECTED: return ERR_STORAGE_DISCONNECTED;
|
||||
case Platform::NOT_ENOUGH_SPACE: return ERR_NOT_ENOUGH_FREE_SPACE;
|
||||
default: return fileSize;
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
|
|
|
@ -355,6 +355,7 @@ public class MWMActivity extends NvEventQueueActivity implements LocationService
|
|||
nativeSetString("country_status_download", getString(R.string.country_status_download));
|
||||
nativeSetString("country_status_download_failed", getString(R.string.country_status_download_failed));
|
||||
nativeSetString("try_again", getString(R.string.try_again));
|
||||
nativeSetString("not_enough_free_space_on_sdcard", getString(R.string.not_enough_free_space_on_sdcard));
|
||||
|
||||
nativeConnectDownloadButton();
|
||||
}
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
|
||||
#include "../yg/overlay_renderer.hpp"
|
||||
|
||||
#include "../platform/platform.hpp"
|
||||
|
||||
#include "../base/string_format.hpp"
|
||||
|
||||
#include "../std/bind.hpp"
|
||||
|
@ -18,17 +20,31 @@ string const CountryStatusDisplay::displayName() const
|
|||
return m_mapName;
|
||||
}
|
||||
|
||||
template <class T1, class T2>
|
||||
void CountryStatusDisplay::SetStatusMessage(string const & msgID, T1 const * t1, T2 const * t2)
|
||||
{
|
||||
m_statusMsg->setIsVisible(true);
|
||||
|
||||
string msg = m_controller->GetStringsBundle()->GetString(msgID);
|
||||
if (t1)
|
||||
{
|
||||
if (t2)
|
||||
msg = strings::Format(msg, *t1, *t2);
|
||||
else
|
||||
msg = strings::Format(msg, *t1);
|
||||
}
|
||||
|
||||
m_statusMsg->setText(msg);
|
||||
}
|
||||
|
||||
void CountryStatusDisplay::cache()
|
||||
{
|
||||
m_downloadButton->setIsVisible(false);
|
||||
|
||||
m_statusMsg->setIsVisible(false);
|
||||
|
||||
string dn = displayName();
|
||||
strings::UniString udn(strings::MakeUniString(dn));
|
||||
|
||||
StringsBundle const * stringsBundle = m_controller->GetStringsBundle();
|
||||
|
||||
string prefixedName;
|
||||
string postfixedName;
|
||||
|
||||
|
@ -55,51 +71,42 @@ void CountryStatusDisplay::cache()
|
|||
switch (m_countryStatus)
|
||||
{
|
||||
case storage::EInQueue:
|
||||
{
|
||||
m_statusMsg->setIsVisible(true);
|
||||
string countryStatusAddedToQueue = stringsBundle->GetString("country_status_added_to_queue");
|
||||
|
||||
m_statusMsg->setText(strings::Format(countryStatusAddedToQueue, postfixedName));
|
||||
}
|
||||
|
||||
SetStatusMessage<string, int>("country_status_added_to_queue", &postfixedName);
|
||||
break;
|
||||
|
||||
case storage::EDownloading:
|
||||
{
|
||||
m_statusMsg->setIsVisible(true);
|
||||
|
||||
int percent = m_countryProgress.first * 100 / m_countryProgress.second;
|
||||
|
||||
string countryStatusDownloading = stringsBundle->GetString("country_status_downloading");
|
||||
m_statusMsg->setText(strings::Format(countryStatusDownloading, prefixedName, percent));
|
||||
}
|
||||
{
|
||||
int percent = m_countryProgress.first * 100 / m_countryProgress.second;
|
||||
SetStatusMessage<string, int>("country_status_downloading", &prefixedName, &percent);
|
||||
break;
|
||||
}
|
||||
|
||||
case storage::ENotDownloaded:
|
||||
if (m_notEnoughSpace)
|
||||
SetStatusMessage<int, int>("not_enough_free_space_on_sdcard");
|
||||
else
|
||||
{
|
||||
m_downloadButton->setIsVisible(true);
|
||||
|
||||
string countryStatusDownload = stringsBundle->GetString("country_status_download");
|
||||
m_downloadButton->setText(strings::Format(countryStatusDownload, prefixedName));
|
||||
string const msg = m_controller->GetStringsBundle()->GetString("country_status_download");
|
||||
m_downloadButton->setText(strings::Format(msg, prefixedName));
|
||||
}
|
||||
break;
|
||||
|
||||
case storage::EDownloadFailed:
|
||||
{
|
||||
m_downloadButton->setIsVisible(true);
|
||||
m_downloadButton->setText(stringsBundle->GetString("try_again"));
|
||||
m_downloadButton->setIsVisible(true);
|
||||
m_downloadButton->setText(m_controller->GetStringsBundle()->GetString("try_again"));
|
||||
|
||||
string countryStatusDownloadFailed = stringsBundle->GetString("country_status_download_failed");
|
||||
m_statusMsg->setText(strings::Format(countryStatusDownloadFailed, prefixedName));
|
||||
SetStatusMessage<string, int>("country_status_download_failed", &prefixedName);
|
||||
|
||||
m_statusMsg->setIsVisible(true);
|
||||
|
||||
setPivot(pivot());
|
||||
}
|
||||
setPivot(pivot());
|
||||
break;
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/// element bound rect is possibly changed
|
||||
// element bound rect is possibly changed
|
||||
setIsDirtyRect(true);
|
||||
}
|
||||
|
||||
|
@ -163,6 +170,7 @@ CountryStatusDisplay::CountryStatusDisplay(Params const & p)
|
|||
|
||||
m_countryIdx = storage::TIndex();
|
||||
m_countryStatus = storage::EUnknown;
|
||||
m_notEnoughSpace = false;
|
||||
}
|
||||
|
||||
CountryStatusDisplay::~CountryStatusDisplay()
|
||||
|
@ -172,7 +180,17 @@ CountryStatusDisplay::~CountryStatusDisplay()
|
|||
|
||||
void CountryStatusDisplay::downloadCountry()
|
||||
{
|
||||
m_storage->DownloadCountry(m_countryIdx);
|
||||
uint64_t const sz = m_storage->CountrySizeInBytes(m_countryIdx).second;
|
||||
|
||||
if (GetPlatform().GetWritableStorageStatus(sz) != Platform::STORAGE_OK)
|
||||
{
|
||||
m_notEnoughSpace = true;
|
||||
|
||||
setIsDirtyDrawing(true);
|
||||
invalidate();
|
||||
}
|
||||
else
|
||||
m_storage->DownloadCountry(m_countryIdx);
|
||||
}
|
||||
|
||||
void CountryStatusDisplay::setDownloadListener(gui::Button::TOnClickListener const & l)
|
||||
|
@ -185,12 +203,14 @@ void CountryStatusDisplay::setCountryName(string const & name)
|
|||
if (m_fullName != name)
|
||||
{
|
||||
storage::CountryInfo::FullName2GroupAndMap(name, m_mapGroupName, m_mapName);
|
||||
LOG(LINFO, (m_mapName, m_mapGroupName));
|
||||
LOG(LDEBUG, (m_mapName, m_mapGroupName));
|
||||
|
||||
m_countryIdx = m_storage->FindIndexByName(m_mapName);
|
||||
m_countryStatus = m_storage->CountryStatus(m_countryIdx);
|
||||
m_countryProgress = m_storage->CountrySizeInBytes(m_countryIdx);
|
||||
m_fullName = name;
|
||||
m_notEnoughSpace = false;
|
||||
|
||||
setIsDirtyDrawing(true);
|
||||
invalidate();
|
||||
}
|
||||
|
@ -204,7 +224,7 @@ void CountryStatusDisplay::draw(yg::gl::OverlayRenderer *r,
|
|||
|
||||
checkDirtyDrawing();
|
||||
|
||||
// r->drawRectangle(roughBoundRect(), yg::Color(0, 0, 255, 64), yg::maxDepth);
|
||||
//r->drawRectangle(roughBoundRect(), yg::Color(0, 0, 255, 64), yg::maxDepth);
|
||||
|
||||
if (m_downloadButton->isVisible())
|
||||
m_downloadButton->draw(r, m);
|
||||
|
@ -234,6 +254,7 @@ void CountryStatusDisplay::setController(gui::Controller *controller)
|
|||
m_statusMsg->setController(controller);
|
||||
m_downloadButton->setController(controller);
|
||||
}
|
||||
|
||||
void CountryStatusDisplay::setPivot(m2::PointD const & pv)
|
||||
{
|
||||
if (m_countryStatus == storage::EDownloadFailed)
|
||||
|
|
|
@ -43,6 +43,8 @@ private:
|
|||
/// downloading progress of the country
|
||||
pair<int64_t, int64_t> m_countryProgress;
|
||||
|
||||
bool m_notEnoughSpace;
|
||||
|
||||
/// bounding rects
|
||||
mutable vector<m2::AnyRectD> m_boundRects;
|
||||
|
||||
|
@ -51,6 +53,9 @@ private:
|
|||
|
||||
string const displayName() const;
|
||||
|
||||
template <class T1, class T2>
|
||||
void SetStatusMessage(string const & msgID, T1 const * t1 = 0, T2 const * t2 = 0);
|
||||
|
||||
public:
|
||||
|
||||
struct Params : public gui::Element::Params
|
||||
|
|
|
@ -84,6 +84,15 @@ public:
|
|||
static bool GetFileSizeByFullPath(string const & filePath, uint64_t & size);
|
||||
//@}
|
||||
|
||||
/// Used to check available free storage space for downloading.
|
||||
enum TStorageStatus
|
||||
{
|
||||
STORAGE_OK = 0,
|
||||
STORAGE_DISCONNECTED,
|
||||
NOT_ENOUGH_SPACE
|
||||
};
|
||||
TStorageStatus GetWritableStorageStatus(uint64_t neededSize);
|
||||
|
||||
/// @name Functions for concurrent tasks.
|
||||
//@{
|
||||
typedef function<void()> TFunctor;
|
||||
|
@ -102,8 +111,6 @@ public:
|
|||
|
||||
void GetFontNames(FilesList & res) const;
|
||||
|
||||
bool IsMultiThreadedRendering() const;
|
||||
|
||||
int VideoMemoryLimit() const;
|
||||
|
||||
int PreCachingDepth() const;
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
#include "platform.hpp"
|
||||
#include "platform_unix_impl.hpp"
|
||||
|
||||
#include "../base/logging.hpp"
|
||||
|
||||
#include <dirent.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/vfs.h>
|
||||
|
||||
|
||||
bool Platform::IsFileExistsByFullPath(string const & filePath)
|
||||
|
@ -22,6 +25,25 @@ bool Platform::GetFileSizeByFullPath(string const & filePath, uint64_t & size)
|
|||
else return false;
|
||||
}
|
||||
|
||||
Platform::TStorageStatus Platform::GetWritableStorageStatus(uint64_t neededSize)
|
||||
{
|
||||
struct statfs st;
|
||||
int const ret = statfs(m_writableDir.c_str(), &st);
|
||||
|
||||
LOG(LDEBUG, ("statfs return = ", ret,
|
||||
"; block size = ", st.f_bsize,
|
||||
"; blocks available = ", st.f_bavail));
|
||||
|
||||
if (ret != 0)
|
||||
return STORAGE_DISCONNECTED;
|
||||
|
||||
/// @todo May be add additional storage space.
|
||||
if (st.f_bsize * st.f_bavail < neededSize)
|
||||
return NOT_ENOUGH_SPACE;
|
||||
|
||||
return STORAGE_OK;
|
||||
}
|
||||
|
||||
namespace pl
|
||||
{
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue