From a41ef3827cebe7cba0ab1b4cefa2475cf528ae92 Mon Sep 17 00:00:00 2001 From: vng Date: Thu, 6 Nov 2014 18:56:37 +0300 Subject: [PATCH] [android] Better logic in Platform::GetReader() according to different markets. --- .../com/mapswithme/maps/MWMApplication.cpp | 4 +- .../jni/com/mapswithme/platform/Platform.cpp | 16 ++- .../jni/com/mapswithme/platform/Platform.hpp | 1 + .../com/mapswithme/maps/MWMApplication.java | 3 +- platform/platform.cpp | 6 +- platform/platform.hpp | 13 +- platform/platform_android.cpp | 125 +++++++++++------- platform/platform_ios.mm | 2 +- platform/platform_qt.cpp | 2 +- platform/platform_tizen.cpp | 20 ++- storage/guides.cpp | 4 +- 11 files changed, 120 insertions(+), 76 deletions(-) diff --git a/android/jni/com/mapswithme/maps/MWMApplication.cpp b/android/jni/com/mapswithme/maps/MWMApplication.cpp index 6375449d68..09547ff692 100644 --- a/android/jni/com/mapswithme/maps/MWMApplication.cpp +++ b/android/jni/com/mapswithme/maps/MWMApplication.cpp @@ -24,10 +24,10 @@ extern "C" Java_com_mapswithme_maps_MWMApplication_nativeInit( JNIEnv * env, jobject thiz, jstring apkPath, jstring storagePath, jstring tmpPath, jstring obbGooglePath, - jboolean isPro, jboolean isYota) + jstring flavorName, jboolean isPro, jboolean isYota) { android::Platform::Instance().Initialize( - env, apkPath, storagePath, tmpPath, obbGooglePath, isPro, isYota); + env, apkPath, storagePath, tmpPath, obbGooglePath, flavorName, isPro, isYota); LOG(LDEBUG, ("Creating android::Framework instance ...")); diff --git a/android/jni/com/mapswithme/platform/Platform.cpp b/android/jni/com/mapswithme/platform/Platform.cpp index d25cd3c5f6..8cb96e19f2 100644 --- a/android/jni/com/mapswithme/platform/Platform.cpp +++ b/android/jni/com/mapswithme/platform/Platform.cpp @@ -65,12 +65,22 @@ namespace android void Platform::Initialize(JNIEnv * env, jstring apkPath, jstring storagePath, jstring tmpPath, jstring obbGooglePath, - bool isPro, bool isYota) + jstring flavorName, bool isPro, bool isYota) { + string const flavor = jni::ToNativeString(env, flavorName); + LOG(LINFO, ("Flavor name:", flavor)); + + if (flavor.find("google") == 0) + m_androidDefResScope = "ferw"; + else if (flavor.find("amazon") == 0 || flavor.find("samsung") == 0) + m_androidDefResScope = "frw"; + else + m_androidDefResScope = "fwr"; + m_resourcesDir = jni::ToNativeString(env, apkPath); - // Settings file should always be in one place (default external storage). - // It stores path to current maps storage. + // Settings file should be in a one place always (default external storage). + // It stores path to the current maps storage. m_settingsDir = jni::ToNativeString(env, storagePath); // @TODO it's a bug when user had all his maps on SD but when space is low, diff --git a/android/jni/com/mapswithme/platform/Platform.hpp b/android/jni/com/mapswithme/platform/Platform.hpp index 2597198e1a..22fedc9716 100644 --- a/android/jni/com/mapswithme/platform/Platform.hpp +++ b/android/jni/com/mapswithme/platform/Platform.hpp @@ -13,6 +13,7 @@ namespace android void Initialize(JNIEnv * env, jstring apkPath, jstring storagePath, jstring tmpPath, jstring obbGooglePath, + jstring flavorName, bool isPro, bool isYota); void OnExternalStorageStatusChanged(bool isAvailable); diff --git a/android/src/com/mapswithme/maps/MWMApplication.java b/android/src/com/mapswithme/maps/MWMApplication.java index 91683d1183..b02b65268a 100644 --- a/android/src/com/mapswithme/maps/MWMApplication.java +++ b/android/src/com/mapswithme/maps/MWMApplication.java @@ -121,7 +121,7 @@ public class MWMApplication extends android.app.Application implements ActiveCou // init native framework nativeInit(getApkPath(), extStoragePath, extTmpPath, - getOBBGooglePath(), BuildConfig.IS_PRO, mIsYota); + getOBBGooglePath(), BuildConfig.FLAVOR, BuildConfig.IS_PRO, mIsYota); ActiveCountryTree.addListener(this); @@ -216,6 +216,7 @@ public class MWMApplication extends android.app.Application implements ActiveCou private native void nativeInit(String apkPath, String storagePath, String tmpPath, String obbGooglePath, + String flavorName, boolean isPro, boolean isYota); public native boolean nativeIsBenchmarking(); diff --git a/platform/platform.cpp b/platform/platform.cpp index 74c5401ece..bf2e1adaf7 100644 --- a/platform/platform.cpp +++ b/platform/platform.cpp @@ -6,8 +6,11 @@ #include "../base/logging.hpp" -string Platform::ReadPathForFile(string const & file, string const & searchScope) const +string Platform::ReadPathForFile(string const & file, string searchScope) const { + if (searchScope.empty()) + searchScope = "wrf"; + string fullPath; for (size_t i = 0; i < searchScope.size(); ++i) { @@ -15,6 +18,7 @@ string Platform::ReadPathForFile(string const & file, string const & searchScope { case 'w': fullPath = m_writableDir + file; break; case 'r': fullPath = m_resourcesDir + file; break; + case 's': fullPath = m_settingsDir + file; break; case 'f': fullPath = file; break; default : CHECK(false, ("Unsupported searchScope:", searchScope)); break; } diff --git a/platform/platform.hpp b/platform/platform.hpp index ca246994ec..0fd612f229 100644 --- a/platform/platform.hpp +++ b/platform/platform.hpp @@ -43,10 +43,13 @@ protected: /// Extended resource files. /// Used in Android only (downloaded zip files as a container). vector m_extResFiles; + /// Default search scope for resource files. + /// Used in Android only and initialized according to the market type (Play, Amazon, Samsung). + string m_androidDefResScope; /// Internal function to get full path for input file. - /// Uses m_writeableDir and m_resourcesDir. - string ReadPathForFile(string const & file, string const & searchScope) const; + /// Uses m_writeableDir [w], m_resourcesDir [r], m_settingsDir [s]. + string ReadPathForFile(string const & file, string searchScope = string()) const; /// Hash some unique string into uniform format. static string HashUniqueID(string const & s); @@ -78,9 +81,9 @@ public: /// @return reader for file decriptor. /// @throws FileAbsentException /// @param[in] file name or full path which we want to read, don't forget to free memory or wrap it to ReaderPtr - /// @param[in] searchScope looks for file in dirs in given order: [w]ritable, [r]esources, by [f]ull path - /// @TODO add [e]xternal resource scope for Android (obb support) - ModelReader * GetReader(string const & file, string const & searchScope = "wrf") const; + /// @param[in] searchScope looks for file in dirs in given order: \n + /// [w]ritable, [r]esources, [s]ettings, by [f]ull path, [e]xternal resources, + ModelReader * GetReader(string const & file, string const & searchScope = string()) const; /// @name File operations //@{ diff --git a/platform/platform_android.cpp b/platform/platform_android.cpp index ad458824fd..027ebfc7b2 100644 --- a/platform/platform_android.cpp +++ b/platform/platform_android.cpp @@ -21,40 +21,44 @@ Platform::Platform() namespace { -enum SourceT { EXTERNAL_RESOURCE, RESOURCE, WRITABLE_PATH, FULL_PATH }; +enum SourceT { EXTERNAL_RESOURCE, RESOURCE, WRITABLE_PATH, SETTINGS_PATH, FULL_PATH }; -size_t GetSearchSources(string const & file, SourceT (&arr)[4]) +bool IsResource(string const & file, string const & ext) { - size_t ret = 0; - string const ext = my::GetFileExtension(file); - ASSERT ( !ext.empty(), () ); - if (ext == DATA_FILE_EXTENSION) { - bool const isWorld = - strings::StartsWith(file, WORLD_COASTS_FILE_NAME) || - strings::StartsWith(file, WORLD_FILE_NAME); - - if (isWorld) - arr[ret++] = EXTERNAL_RESOURCE; - arr[ret++] = WRITABLE_PATH; - if (isWorld) - arr[ret++] = RESOURCE; + return (strings::StartsWith(file, WORLD_COASTS_FILE_NAME) || + strings::StartsWith(file, WORLD_FILE_NAME)); } - else if (ext == FONT_FILE_EXTENSION) + else if (ext == BOOKMARKS_FILE_EXTENSION || + ext == ROUTING_FILE_EXTENSION || + file == SETTINGS_FILE_NAME) { - // system fonts have absolute unix path - if (strings::StartsWith(file, "/")) - arr[ret++] = FULL_PATH; - else + return false; + } + + return true; +} + +size_t GetSearchSources(string const & file, string const & searchScope, SourceT (&arr)[4]) +{ + size_t ret = 0; + + for (size_t i = 0; i < searchScope.size(); ++i) + { + switch (searchScope[i]) { - arr[ret++] = EXTERNAL_RESOURCE; - arr[ret++] = WRITABLE_PATH; - arr[ret++] = RESOURCE; + case 'w': arr[ret++] = WRITABLE_PATH; break; + case 'r': arr[ret++] = RESOURCE; break; + case 'e': arr[ret++] = EXTERNAL_RESOURCE; break; + case 's': arr[ret++] = SETTINGS_PATH; break; + case 'f': + if (strings::StartsWith(file, "/")) + arr[ret++] = FULL_PATH; + break; + default : CHECK(false, ("Unsupported searchScope:", searchScope)); break; } } - else - arr[ret++] = RESOURCE; return ret; } @@ -78,24 +82,32 @@ public: ModelReader * Platform::GetReader(string const & file, string const & searchScope) const { - // @TODO now we handle only two specific cases needed to release guides ads - if (searchScope == "w") - { - string const path = m_writableDir + file; - if (IsFileExistsByFullPath(path)) - return new FileReader(path, READER_CHUNK_LOG_SIZE, READER_CHUNK_LOG_COUNT); - MYTHROW(FileAbsentException, ("File not found", file)); - } - else if (searchScope == "r") - { - return new ZipFileReader(m_resourcesDir, "assets/" + file); - } - // @TODO refactor code below and some other parts too, like fonts and maps detection and loading, - // as it can be done much better + string const ext = my::GetFileExtension(file); + ASSERT(!ext.empty(), ()); + uint32_t const logPageSize = (ext == DATA_FILE_EXTENSION) ? READER_CHUNK_LOG_SIZE : 10; + uint32_t const logPageCount = (ext == DATA_FILE_EXTENSION) ? READER_CHUNK_LOG_COUNT : 4; SourceT sources[4]; - size_t const n = GetSearchSources(file, sources); + size_t n = 0; + + if (searchScope.empty()) + { + // Default behaviour - use predefined scope for resource files and writable path for all others. + + if (IsResource(file, ext)) + n = GetSearchSources(file, m_androidDefResScope, sources); + else + { + // Add source for map files and other dynamic stored data. + sources[n++] = WRITABLE_PATH; + } + } + else + { + // Use passed scope as client wishes. + n = GetSearchSources(file, searchScope, sources); + } #ifdef DEBUG DbgLogger logger(file); @@ -110,38 +122,53 @@ ModelReader * Platform::GetReader(string const & file, string const & searchScop switch (sources[i]) { case EXTERNAL_RESOURCE: - { for (size_t j = 0; j < m_extResFiles.size(); ++j) { try { - return new ZipFileReader(m_extResFiles[j], file, - READER_CHUNK_LOG_SIZE, READER_CHUNK_LOG_COUNT); + return new ZipFileReader(m_extResFiles[j], file, logPageSize, logPageCount); } catch (Reader::OpenException const &) { } } break; - } case WRITABLE_PATH: { string const path = m_writableDir + file; if (IsFileExistsByFullPath(path)) - return new FileReader(path, READER_CHUNK_LOG_SIZE, READER_CHUNK_LOG_COUNT); + return new FileReader(path, logPageSize, logPageCount); + break; + } + + case SETTINGS_PATH: + { + string const path = m_settingsDir + file; + if (IsFileExistsByFullPath(path)) + return new FileReader(path, logPageSize, logPageCount); break; } case FULL_PATH: if (IsFileExistsByFullPath(file)) - return new FileReader(file); + return new FileReader(file, logPageSize, logPageCount); + break; + + case RESOURCE: + ASSERT_EQUAL(file.find("assets/"), string::npos, ()); + try + { + return new ZipFileReader(m_resourcesDir, "assets/" + file, logPageSize, logPageCount); + } + catch (Reader::OpenException const &) + { + } break; default: - ASSERT_EQUAL ( sources[i], RESOURCE, () ); - ASSERT_EQUAL ( file.find("assets/"), string::npos, () ); - return new ZipFileReader(m_resourcesDir, "assets/" + file); + CHECK(false, ("Unsupported source:", sources[i])); + break; } } diff --git a/platform/platform_ios.mm b/platform/platform_ios.mm index 386f9e3613..25fdf1f6ab 100644 --- a/platform/platform_ios.mm +++ b/platform/platform_ios.mm @@ -62,7 +62,7 @@ bool Platform::GetFileSizeByName(string const & fileName, uint64_t & size) const { try { - return GetFileSizeByFullPath(ReadPathForFile(fileName, "wr"), size); + return GetFileSizeByFullPath(ReadPathForFile(fileName), size); } catch (RootException const &) { diff --git a/platform/platform_qt.cpp b/platform/platform_qt.cpp index d15fa664e3..980e0fde96 100644 --- a/platform/platform_qt.cpp +++ b/platform/platform_qt.cpp @@ -22,7 +22,7 @@ bool Platform::GetFileSizeByName(string const & fileName, uint64_t & size) const { try { - return GetFileSizeByFullPath(ReadPathForFile(fileName, "wr"), size); + return GetFileSizeByFullPath(ReadPathForFile(fileName), size); } catch (RootException const &) { diff --git a/platform/platform_tizen.cpp b/platform/platform_tizen.cpp index f554700991..56bd4aaa93 100644 --- a/platform/platform_tizen.cpp +++ b/platform/platform_tizen.cpp @@ -1,23 +1,22 @@ - #include "platform.hpp" +#include "constants.hpp" +#include "platform_unix_impl.hpp" +#include "tizen_utils.hpp" +#include "http_thread_tizen.hpp" #include #include #include #include -#include "../base/logging.hpp" #include "../coding/file_reader.hpp" -#include "constants.hpp" -#include "platform_unix_impl.hpp" - -#include "tizen_utils.hpp" -#include "http_thread_tizen.hpp" +#include "../base/logging.hpp" #include #include "../../tizen/inc/FIo.hpp" + Platform::Platform() { Tizen::App::App * pApp = Tizen::App::App::GetInstance(); @@ -57,7 +56,6 @@ string Platform::UniqueClientId() const { Tizen::App::App * pApp = Tizen::App::App::GetInstance(); return FromTizenString(pApp->GetAppId()); - } void Platform::RunOnGuiThread(TFunctor const & fn) @@ -87,7 +85,7 @@ bool Platform::GetFileSizeByName(string const & fileName, uint64_t & size) const { try { - return GetFileSizeByFullPath(ReadPathForFile(fileName, "wr"), size); + return GetFileSizeByFullPath(ReadPathForFile(fileName), size); } catch (RootException const &) { @@ -104,7 +102,7 @@ int Platform::PreCachingDepth() const { return 3; } -//////////////////////////////////////////////////////////////////////// + extern Platform & GetPlatform() { static Platform platform; @@ -115,6 +113,7 @@ class HttpThread; namespace downloader { + class IHttpThreadCallback; HttpThread * CreateNativeHttpThread(string const & url, @@ -124,7 +123,6 @@ HttpThread * CreateNativeHttpThread(string const & url, int64_t size, string const & pb) { - HttpThread * pRes = new HttpThread(url, cb, beg, end, size, pb); return pRes; } diff --git a/storage/guides.cpp b/storage/guides.cpp index 4ec89df0a1..7bbcdd3aa7 100644 --- a/storage/guides.cpp +++ b/storage/guides.cpp @@ -120,7 +120,7 @@ bool GuidesManager::RestoreFromFile() try { string json; - ReaderPtr(pl.GetReader(GetDataFileName(), "w")).ReadAsString(json); + FileReader(GetDataFileFullPath()).ReadAsString(json); downloadedVersion = ParseGuidesData(json, fromDownloaded); } catch (RootException const &) @@ -209,7 +209,7 @@ string GuidesManager::GetDataFileName() string GuidesManager::GetDataFileFullPath() { - return GetPlatform().WritableDir() + GetDataFileName(); + return GetPlatform().SettingsDir() + GetDataFileName(); } void GuidesManager::OnFinish(downloader::HttpRequest & request)