From 167afe38c596069051855a05c47d11152f7bb1a2 Mon Sep 17 00:00:00 2001 From: vng Date: Sat, 30 Jun 2012 03:06:50 -0700 Subject: [PATCH] Add free storage space handler to download button in map. --- .../maps/DownloadResourcesActivity.cpp | 33 +++---- .../src/com/mapswithme/maps/MWMActivity.java | 1 + map/country_status_display.cpp | 89 ++++++++++++------- map/country_status_display.hpp | 5 ++ platform/platform.hpp | 11 ++- platform/platform_unix_impl.cpp | 22 +++++ 6 files changed, 106 insertions(+), 55 deletions(-) diff --git a/android/jni/com/mapswithme/maps/DownloadResourcesActivity.cpp b/android/jni/com/mapswithme/maps/DownloadResourcesActivity.cpp index 3e3543e55e..712f588010 100644 --- a/android/jni/com/mapswithme/maps/DownloadResourcesActivity.cpp +++ b/android/jni/com/mapswithme/maps/DownloadResourcesActivity.cpp @@ -1,6 +1,4 @@ #include -// To get free disk space -#include #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 diff --git a/android/src/com/mapswithme/maps/MWMActivity.java b/android/src/com/mapswithme/maps/MWMActivity.java index d6f73ed265..56aa0c2e36 100644 --- a/android/src/com/mapswithme/maps/MWMActivity.java +++ b/android/src/com/mapswithme/maps/MWMActivity.java @@ -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(); } diff --git a/map/country_status_display.cpp b/map/country_status_display.cpp index 95ac2d9b08..09f6319633 100644 --- a/map/country_status_display.cpp +++ b/map/country_status_display.cpp @@ -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 +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("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("country_status_downloading", &prefixedName, &percent); break; + } + case storage::ENotDownloaded: + if (m_notEnoughSpace) + SetStatusMessage("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("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) diff --git a/map/country_status_display.hpp b/map/country_status_display.hpp index 4fec7730d6..a6e7a20088 100644 --- a/map/country_status_display.hpp +++ b/map/country_status_display.hpp @@ -43,6 +43,8 @@ private: /// downloading progress of the country pair m_countryProgress; + bool m_notEnoughSpace; + /// bounding rects mutable vector m_boundRects; @@ -51,6 +53,9 @@ private: string const displayName() const; + template + void SetStatusMessage(string const & msgID, T1 const * t1 = 0, T2 const * t2 = 0); + public: struct Params : public gui::Element::Params diff --git a/platform/platform.hpp b/platform/platform.hpp index 8cb0c2a3a8..c3b20abfbe 100644 --- a/platform/platform.hpp +++ b/platform/platform.hpp @@ -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 TFunctor; @@ -102,8 +111,6 @@ public: void GetFontNames(FilesList & res) const; - bool IsMultiThreadedRendering() const; - int VideoMemoryLimit() const; int PreCachingDepth() const; diff --git a/platform/platform_unix_impl.cpp b/platform/platform_unix_impl.cpp index 80bf718de2..88d4e5257e 100644 --- a/platform/platform_unix_impl.cpp +++ b/platform/platform_unix_impl.cpp @@ -1,8 +1,11 @@ #include "platform.hpp" #include "platform_unix_impl.hpp" +#include "../base/logging.hpp" + #include #include +#include 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 {