From 4822f1a39b4ff2081e93243868522dfcd6ec7428 Mon Sep 17 00:00:00 2001 From: Roman Tsisyk Date: Sat, 20 Mar 2021 21:44:01 +0300 Subject: [PATCH] [android]: Use scoped storage Signed-off-by: Roman Tsisyk --- .../jni/com/mapswithme/maps/MapManager.cpp | 2 +- .../com/mapswithme/maps/MwmApplication.cpp | 8 +- .../jni/com/mapswithme/platform/Platform.cpp | 19 +-- .../jni/com/mapswithme/platform/Platform.hpp | 9 +- .../com/mapswithme/maps/MwmApplication.java | 55 ++++--- .../mapswithme/maps/settings/StorageItem.java | 9 +- .../maps/settings/StoragePathManager.java | 134 ++++++++++++------ .../maps/settings/StorageUtils.java | 78 ---------- .../src/com/mapswithme/util/Constants.java | 7 - .../src/com/mapswithme/util/StorageUtils.java | 47 ++---- 10 files changed, 161 insertions(+), 207 deletions(-) diff --git a/android/jni/com/mapswithme/maps/MapManager.cpp b/android/jni/com/mapswithme/maps/MapManager.cpp index 1738e78982..e2e5fd22ec 100644 --- a/android/jni/com/mapswithme/maps/MapManager.cpp +++ b/android/jni/com/mapswithme/maps/MapManager.cpp @@ -94,7 +94,7 @@ Java_com_mapswithme_maps_downloader_MapManager_nativeGetRoot(JNIEnv * env, jclas JNIEXPORT jboolean JNICALL Java_com_mapswithme_maps_downloader_MapManager_nativeMoveFile(JNIEnv * env, jclass clazz, jstring oldFile, jstring newFile) { - return base::RenameFileX(jni::ToNativeString(env, oldFile), jni::ToNativeString(env, newFile)); + return base::MoveFileX(jni::ToNativeString(env, oldFile), jni::ToNativeString(env, newFile)); } // static boolean nativeHasSpaceToDownloadAmount(long bytes); diff --git a/android/jni/com/mapswithme/maps/MwmApplication.cpp b/android/jni/com/mapswithme/maps/MwmApplication.cpp index f06d8bb65d..aa7619e4c3 100644 --- a/android/jni/com/mapswithme/maps/MwmApplication.cpp +++ b/android/jni/com/mapswithme/maps/MwmApplication.cpp @@ -7,9 +7,9 @@ extern "C" { - // static void nativePreparePlatform(String settingsPath); + // static void nativeSetSettingsDir(String settingsPath); JNIEXPORT void JNICALL - Java_com_mapswithme_maps_MwmApplication_nativePreparePlatform(JNIEnv * env, jclass clazz, jstring settingsPath) + Java_com_mapswithme_maps_MwmApplication_nativeSetSettingsDir(JNIEnv * env, jclass clazz, jstring settingsPath) { android::Platform::Instance().SetSettingsDir(jni::ToNativeString(env, settingsPath)); } @@ -18,12 +18,12 @@ extern "C" // String obbGooglePath, String flavorName, String buildType, boolean isTablet); JNIEXPORT void JNICALL Java_com_mapswithme_maps_MwmApplication_nativeInitPlatform(JNIEnv * env, jobject thiz, - jstring apkPath, jstring storagePath, + jstring apkPath, jstring writablePath, jstring privatePath, jstring tmpPath, jstring flavorName, jstring buildType, jboolean isTablet) { - android::Platform::Instance().Initialize(env, thiz, apkPath, storagePath, privatePath, tmpPath, + android::Platform::Instance().Initialize(env, thiz, apkPath, writablePath, privatePath, tmpPath, flavorName, buildType, isTablet); } diff --git a/android/jni/com/mapswithme/platform/Platform.cpp b/android/jni/com/mapswithme/platform/Platform.cpp index 9f6eeac40a..f7539f9108 100644 --- a/android/jni/com/mapswithme/platform/Platform.cpp +++ b/android/jni/com/mapswithme/platform/Platform.cpp @@ -137,7 +137,7 @@ platform::NetworkPolicy GetCurrentNetworkPolicy() namespace android { void Platform::Initialize(JNIEnv * env, jobject functorProcessObject, jstring apkPath, - jstring storagePath, jstring privatePath, jstring tmpPath, + jstring writablePath, jstring privatePath, jstring tmpPath, jstring flavorName, jstring buildType, bool isTablet) { m_functorProcessObject = env->NewGlobalRef(functorProcessObject); @@ -160,8 +160,7 @@ void Platform::Initialize(JNIEnv * env, jobject functorProcessObject, jstring ap m_resourcesDir = jni::ToNativeString(env, apkPath); m_privateDir = jni::ToNativeString(env, privatePath); m_tmpDir = jni::ToNativeString(env, tmpPath); - m_writableDir = jni::ToNativeString(env, storagePath); - + m_writableDir = jni::ToNativeString(env, writablePath); LOG(LINFO, ("Apk path = ", m_resourcesDir)); LOG(LINFO, ("Writable path = ", m_writableDir)); LOG(LINFO, ("Temporary path = ", m_tmpDir)); @@ -182,17 +181,6 @@ void Platform::OnExternalStorageStatusChanged(bool isAvailable) { } -std::string Platform::GetStoragePathPrefix() const -{ - size_t const count = m_writableDir.size(); - ASSERT_GREATER ( count, 2, () ); - - size_t const i = m_writableDir.find_last_of('/', count-2); - ASSERT_GREATER ( i, 0, () ); - - return m_writableDir.substr(0, i); -} - void Platform::SetWritableDir(std::string const & dir) { m_writableDir = dir; @@ -203,7 +191,8 @@ void Platform::SetWritableDir(std::string const & dir) void Platform::SetSettingsDir(std::string const & dir) { m_settingsDir = dir; - LOG(LINFO, ("Settings path = ", m_settingsDir)); + // Logger is not fully initialized here. + //LOG(LINFO, ("Settings path = ", m_settingsDir)); } bool Platform::HasAvailableSpaceForWriting(uint64_t size) const diff --git a/android/jni/com/mapswithme/platform/Platform.hpp b/android/jni/com/mapswithme/platform/Platform.hpp index bc3c419934..9693484ca7 100644 --- a/android/jni/com/mapswithme/platform/Platform.hpp +++ b/android/jni/com/mapswithme/platform/Platform.hpp @@ -17,17 +17,14 @@ namespace android class Platform : public ::Platform { public: - void Initialize(JNIEnv * env, jobject functorProcessObject, jstring apkPath, jstring storagePath, - jstring privatePath, jstring tmpPath, jstring flavorName, jstring buildType, - bool isTablet); + void Initialize(JNIEnv * env, jobject functorProcessObject, jstring apkPath, jstring writablePath, + jstring privatePath, jstring tmpPath, jstring flavorName, + jstring buildType, bool isTablet); ~Platform() override; void OnExternalStorageStatusChanged(bool isAvailable); - /// get storage path without ending "/OMapsData/" - std::string GetStoragePathPrefix() const; - /// assign storage path (should contain ending "/OMapsData/") void SetWritableDir(std::string const & dir); void SetSettingsDir(std::string const & dir); diff --git a/android/src/com/mapswithme/maps/MwmApplication.java b/android/src/com/mapswithme/maps/MwmApplication.java index 686921d3bc..fafa3044a6 100644 --- a/android/src/com/mapswithme/maps/MwmApplication.java +++ b/android/src/com/mapswithme/maps/MwmApplication.java @@ -28,6 +28,7 @@ import com.mapswithme.maps.routing.RoutingController; import com.mapswithme.maps.scheduling.ConnectivityJobScheduler; import com.mapswithme.maps.scheduling.ConnectivityListener; import com.mapswithme.maps.search.SearchEngine; +import com.mapswithme.maps.settings.StoragePathManager; import com.mapswithme.maps.sound.TtsPlayer; import com.mapswithme.util.Config; import com.mapswithme.util.ConnectionState; @@ -132,6 +133,9 @@ public class MwmApplication extends Application implements AppBackgroundTracker. LoggerFactory.INSTANCE.initialize(this); mLogger = LoggerFactory.INSTANCE.getLogger(LoggerFactory.Type.MISC); getLogger().d(TAG, "Application is created"); + // Set configuration directory as early as possible. + // Other methods may explicitly use Config, which requires settingsDir to be set. + setSettingsDir(); mMainLoopHandler = new Handler(getMainLooper()); ConnectionState.INSTANCE.initialize(this); CrashlyticsUtils.INSTANCE.initialize(this); @@ -156,6 +160,20 @@ public class MwmApplication extends Application implements AppBackgroundTracker. channelProvider.setDownloadingChannel(); } + /** + * Initialize configuration directory. + */ + public void setSettingsDir() + { + final String settingsPath = StorageUtils.getSettingsPath(this); + if (!StorageUtils.createDirectory(this, settingsPath)) + { + throw new AssertionError("Can't create settingsDir " + settingsPath); + } + getLogger().d(TAG, "Settings path = " + settingsPath); + nativeSetSettingsDir(settingsPath); + } + /** * Initialize native core of application: platform and framework. Caller must handle returned value * and do nothing with native code if initialization is failed. @@ -177,24 +195,27 @@ public class MwmApplication extends Application implements AppBackgroundTracker. if (mPlatformInitialized) return; - final String settingsPath = StorageUtils.getSettingsPath(); - getLogger().d(TAG, "onCreate(), setting path = " + settingsPath); - final String filesPath = StorageUtils.getFilesPath(this); - getLogger().d(TAG, "onCreate(), files path = " + filesPath); + final Logger log = getLogger(); + final String apkPath = StorageUtils.getApkPath(this); + log.d(TAG, "Apk path = " + apkPath); + // Note: StoragePathManager uses Config, which requires initConfig() to be called. + final String writablePath = new StoragePathManager().findMapsStorage(this); + log.d(TAG, "Writable path = " + writablePath); + final String privatePath = StorageUtils.getPrivatePath(this); + log.d(TAG, "Private path = " + privatePath); final String tempPath = StorageUtils.getTempPath(this); - getLogger().d(TAG, "onCreate(), temp path = " + tempPath); + log.d(TAG, "Temp path = " + tempPath); // If platform directories are not created it means that native part of app will not be able // to work at all. So, we just ignore native part initialization in this case, e.g. when the // external storage is damaged or not available (read-only). - if (!createPlatformDirectories(settingsPath, filesPath, tempPath)) + if (!createPlatformDirectories(writablePath, privatePath, tempPath)) return; - // First we need initialize paths and platform to have access to settings and other components. - nativePreparePlatform(settingsPath); - nativeInitPlatform(StorageUtils.getApkPath(this), - StorageUtils.getStoragePath(settingsPath), - filesPath, tempPath, + nativeInitPlatform(apkPath, + writablePath, + privatePath, + tempPath, BuildConfig.FLAVOR, BuildConfig.BUILD_TYPE, UiUtils.isTablet(this)); @@ -204,15 +225,15 @@ public class MwmApplication extends Application implements AppBackgroundTracker. mPlatformInitialized = true; } - private boolean createPlatformDirectories(@NonNull String settingsPath, - @NonNull String filesPath, + private boolean createPlatformDirectories(@NonNull String writablePath, + @NonNull String privatePath, @NonNull String tempPath) { if (SharedPropertiesUtils.shouldEmulateBadExternalStorage(this)) return false; - return StorageUtils.createDirectory(this, settingsPath) && - StorageUtils.createDirectory(this, filesPath) && + return StorageUtils.createDirectory(this, writablePath) && + StorageUtils.createDirectory(this, privatePath) && StorageUtils.createDirectory(this, tempPath); } @@ -308,8 +329,8 @@ public class MwmApplication extends Application implements AppBackgroundTracker. return mPlayer; } - private static native void nativePreparePlatform(String settingsPath); - private native void nativeInitPlatform(String apkPath, String storagePath, String privatePath, + private static native void nativeSetSettingsDir(String settingsPath); + private native void nativeInitPlatform(String apkPath, String writablePath, String privatePath, String tmpPath, String flavorName, String buildType, boolean isTablet); private static native void nativeInitFramework(); diff --git a/android/src/com/mapswithme/maps/settings/StorageItem.java b/android/src/com/mapswithme/maps/settings/StorageItem.java index 208ad17710..c9b7d24a16 100644 --- a/android/src/com/mapswithme/maps/settings/StorageItem.java +++ b/android/src/com/mapswithme/maps/settings/StorageItem.java @@ -1,7 +1,5 @@ package com.mapswithme.maps.settings; -import com.mapswithme.util.Constants; - /** * Represents storage option. */ @@ -47,6 +45,11 @@ public class StorageItem public String getFullPath() { - return mPath + Constants.MWM_DIR_POSTFIX; + return mPath; + } + + public long getFreeSize() + { + return mFreeSize; } } diff --git a/android/src/com/mapswithme/maps/settings/StoragePathManager.java b/android/src/com/mapswithme/maps/settings/StoragePathManager.java index ef05b9f2f0..4cad04d960 100644 --- a/android/src/com/mapswithme/maps/settings/StoragePathManager.java +++ b/android/src/com/mapswithme/maps/settings/StoragePathManager.java @@ -1,6 +1,7 @@ package com.mapswithme.maps.settings; import android.app.Activity; +import android.app.Application; import android.app.ProgressDialog; import android.content.BroadcastReceiver; import android.content.ContentResolver; @@ -8,8 +9,9 @@ import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.IntentFilter; -import android.os.Build; import android.os.Environment; +import android.text.TextUtils; + import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.app.AlertDialog; @@ -28,9 +30,11 @@ import com.mapswithme.util.log.LoggerFactory; import java.io.File; import java.io.FileFilter; import java.io.FilenameFilter; +import java.io.IOError; import java.io.IOException; import java.util.ArrayList; import java.util.HashSet; +import java.util.LinkedHashSet; import java.util.List; import java.util.Set; @@ -90,7 +94,7 @@ public class StoragePathManager @Override public void onReceive(Context context, Intent intent) { - updateExternalStorages(); + updateExternalStorages(mActivity.getApplication()); if (mStoragesChangedListener != null) mStoragesChangedListener.onStorageListChanged(mItems, mCurrentStorageIndex); @@ -98,7 +102,7 @@ public class StoragePathManager }; mActivity.registerReceiver(mInternalReceiver, getMediaChangesIntentFilter()); - updateExternalStorages(); + updateExternalStorages(mActivity.getApplication()); } private static IntentFilter getMediaChangesIntentFilter() @@ -143,57 +147,94 @@ public class StoragePathManager return mCurrentStorageIndex; } - private void updateExternalStorages() + private void updateExternalStorages(Application application) { - updateExternalStorages(StorageUtils.getWritableDirRoot()); - } + List candidates = new ArrayList<>(); - private void updateExternalStorages(String writableDir) - { - Set pathsFromConfig = new HashSet<>(); - - StorageUtils.parseStorages(pathsFromConfig); - - mItems.clear(); - - final StorageItem currentStorage = buildStorageItem(writableDir); - addStorageItem(currentStorage); - addStorageItem(buildStorageItem(Environment.getExternalStorageDirectory().getAbsolutePath())); - for (String path : pathsFromConfig) - addStorageItem(buildStorageItem(path)); - - mCurrentStorageIndex = mItems.indexOf(currentStorage); - - if (mCurrentStorageIndex == -1) + // External storages (SD cards and other). + for (File dir : application.getExternalFilesDirs(null)) { - LOGGER.w(TAG, "Unrecognized current path : " + currentStorage); - LOGGER.w(TAG, "Parsed paths : "); + // + // If the contents of emulated storage devices are backed by a private user data partition, + // then there is little benefit to apps storing data here instead of the private directories + // returned by Context#getFilesDir(), etc. + // + if (!Environment.isExternalStorageEmulated(dir)) + candidates.add(dir); + } + + // Internal storage (always exists). + candidates.add(application.getFilesDir()); + + // Configured path. + String configDir = Config.getStoragePath(); + if (!TextUtils.isEmpty(configDir)) + candidates.add(new File(configDir)); + + // Current path. + String currentDir = Framework.nativeGetWritableDir(); + if (!TextUtils.isEmpty(currentDir)) + candidates.add(new File(configDir));; + + if (candidates.isEmpty()) + throw new AssertionError("Can't find available storage"); + + // + // Update internal state. + // + mItems.clear(); + mCurrentStorageIndex = -1; + Set unique = new HashSet<>(); + for (File dir : candidates) + { + StorageItem item = buildStorageItem(dir); + if (item != null) + { + String path = item.getFullPath(); + if (!unique.add(path)) + { + // A duplicate + LOGGER.d(TAG, "Skip a duplicate : " + path); + continue; + } + LOGGER.i(TAG, "Storage found : " + path + ", size : " + item.getFreeSize()); + if (!TextUtils.isEmpty(configDir) && configDir.equals(path)) + { + mCurrentStorageIndex = mItems.size(); + } + mItems.add(item); + } + } + + if (!TextUtils.isEmpty(configDir) && mCurrentStorageIndex == -1) + { + LOGGER.w(TAG, "Unrecognized current path : " + configDir); for (StorageItem item : mItems) LOGGER.w(TAG, item.toString()); } } - private void addStorageItem(StorageItem item) - { - if (item != null && !mItems.contains(item)) - mItems.add(item); - } - - private static StorageItem buildStorageItem(String path) + private static StorageItem buildStorageItem(File dir) { + String path = dir.getAbsolutePath(); + LOGGER.d(TAG, "Check storage : " + path); try { - final File f = new File(path + "/"); - if (f.exists() && f.isDirectory() && f.canWrite() && StorageUtils.isDirWritable(path)) + path = dir.getCanonicalPath(); + // Add the trailing separator because the native code assumes that all paths have it. + if (!path.endsWith(File.separator)) + path = path + File.separator; + + if (dir.exists() && dir.isDirectory() && dir.canWrite() && StorageUtils.isDirWritable(path)) { final long freeSize = StorageUtils.getFreeBytesAtPath(path); if (freeSize > 0) { - LOGGER.i(TAG, "Storage found : " + path + ", size : " + freeSize); return new StorageItem(path, freeSize); } } - } catch (final IllegalArgumentException ex) + } + catch (IllegalArgumentException | IOException ex) { LOGGER.e(TAG, "Can't build storage for path : " + path, ex); } @@ -227,7 +268,7 @@ public class StoragePathManager @Override public void moveFilesFinished(String newPath) { - updateExternalStorages(); + updateExternalStorages(mActivity.getApplication()); if (mMoveFilesListener != null) mMoveFilesListener.moveFilesFinished(newPath); } @@ -235,7 +276,7 @@ public class StoragePathManager @Override public void moveFilesFailed(int errorCode) { - updateExternalStorages(); + updateExternalStorages(mActivity.getApplication()); if (mMoveFilesListener != null) mMoveFilesListener.moveFilesFailed(errorCode); } @@ -291,18 +332,27 @@ public class StoragePathManager candidates[0].list().length > 0); } - public String findMapsMeStorage(String settingsPath) + public String findMapsStorage(@NonNull Application application) { - updateExternalStorages(settingsPath); + updateExternalStorages(application); + List items = getStorageItems(); for (StorageItem item : items) { + LOGGER.d(TAG, "Scanning: " + item.mPath); if (containsMapData(item.mPath)) + { + LOGGER.i(TAG, "Found map at: " + item.mPath); return item.mPath; + } } - return settingsPath; + // Use the first item by default. + final String defaultDir = items.get(0).mPath; + LOGGER.i(TAG, "Using default directory: " + defaultDir); + Config.setStoragePath(defaultDir); + return defaultDir; } private void setStoragePath(@NonNull final Activity context, @@ -333,7 +383,7 @@ public class StoragePathManager else listener.moveFilesFailed(result); - updateExternalStorages(); + updateExternalStorages(mActivity.getApplication()); } }); } diff --git a/android/src/com/mapswithme/maps/settings/StorageUtils.java b/android/src/com/mapswithme/maps/settings/StorageUtils.java index 2b74438f73..fc36f0c0d8 100644 --- a/android/src/com/mapswithme/maps/settings/StorageUtils.java +++ b/android/src/com/mapswithme/maps/settings/StorageUtils.java @@ -30,8 +30,6 @@ final class StorageUtils private static final Logger LOGGER = LoggerFactory.INSTANCE.getLogger(LoggerFactory.Type.STORAGE); private static final String TAG = StorageUtils.class.getSimpleName(); - private static final int VOLD_MODE = 1; - private static final int MOUNTS_MODE = 2; /** * Check if directory is writable. On some devices with KitKat (eg, Samsung S4) simple File.canWrite() returns @@ -53,20 +51,6 @@ final class StorageUtils return true; } - /** - * Returns path, where maps and other files are stored. - * @return pat (or empty string, if framework wasn't created yet) - */ - static String getWritableDirRoot() - { - String writableDir = Framework.nativeGetWritableDir(); - int index = writableDir.lastIndexOf(Constants.MWM_DIR_POSTFIX); - if (index != -1) - writableDir = writableDir.substring(0, index); - - return writableDir; - } - static long getFreeBytesAtPath(String path) { long size = 0; @@ -81,68 +65,6 @@ final class StorageUtils return size; } - // http://stackoverflow.com/questions/8151779/find-sd-card-volume-label-on-android - // http://stackoverflow.com/questions/5694933/find-an-external-sd-card-location - // http://stackoverflow.com/questions/14212969/file-canwrite-returns-false-on-some-devices-although-write-external-storage-pe - private static void parseMountFile(String file, int mode, Set paths) - { - LOGGER.i(StoragePathManager.TAG, "Parsing " + file); - - BufferedReader reader = null; - try - { - reader = new BufferedReader(new FileReader(file)); - - while (true) - { - String line = reader.readLine(); - if (line == null) - return; - - line = line.trim(); - if (TextUtils.isEmpty(line) || line.startsWith("#")) - continue; - - // standard regexp for all possible whitespaces (space, tab, etc) - String[] parts = line.split("\\s+"); - - if (parts.length <= 3) - continue; - - if (mode == VOLD_MODE) - { - if (parts[0].startsWith("dev_mount")) - paths.add(parts[2]); - - continue; - } - - for (String s : new String[] { "/dev/block/vold", "/dev/fuse", "/mnt/media_rw" }) - { - if (parts[0].startsWith(s)) - { - paths.add(parts[1]); - break; - } - } - } - } catch (final IOException e) - { - LOGGER.w(TAG, "Can't read file: " + file, e); - } finally - { - Utils.closeSafely(reader); - } - } - - static void parseStorages(Set paths) - { - parseMountFile("/etc/vold.conf", VOLD_MODE, paths); - parseMountFile("/etc/vold.fstab", VOLD_MODE, paths); - parseMountFile("/system/etc/vold.fstab", VOLD_MODE, paths); - parseMountFile("/proc/mounts", MOUNTS_MODE, paths); - } - static void copyFile(File source, File dest) throws IOException { int maxChunkSize = 10 * Constants.MB; // move file by smaller chunks to avoid OOM. diff --git a/android/src/com/mapswithme/util/Constants.java b/android/src/com/mapswithme/util/Constants.java index df6fe86ba1..898808da9a 100644 --- a/android/src/com/mapswithme/util/Constants.java +++ b/android/src/com/mapswithme/util/Constants.java @@ -4,8 +4,6 @@ import com.mapswithme.maps.BuildConfig; public final class Constants { - public static final String STORAGE_PATH = "/Android/data/%s/%s/"; - public static final int KB = 1024; public static final int MB = 1024 * 1024; public static final int GB = 1024 * 1024 * 1024; @@ -68,10 +66,5 @@ public final class Constants private Rating() {} } - - public static final String MWM_DIR_POSTFIX = "/OMapsData/"; - public static final String CACHE_DIR = "cache"; - public static final String FILES_DIR = "files"; - private Constants() {} } diff --git a/android/src/com/mapswithme/util/StorageUtils.java b/android/src/com/mapswithme/util/StorageUtils.java index fbf75ea53e..bc9e7dfd9d 100644 --- a/android/src/com/mapswithme/util/StorageUtils.java +++ b/android/src/com/mapswithme/util/StorageUtils.java @@ -109,49 +109,33 @@ public class StorageUtils } @NonNull - public static String getSettingsPath() + private static String addTrailingSeparator(@NonNull String dir) { - return Environment.getExternalStorageDirectory().getAbsolutePath() + Constants.MWM_DIR_POSTFIX; + if (!dir.endsWith("/")) + return dir + File.separator; + return dir; } @NonNull - public static String getStoragePath(@NonNull String settingsPath) + public static String getSettingsPath(@NonNull Application application) { - String path = Config.getStoragePath(); - if (!TextUtils.isEmpty(path)) - { - File f = new File(path); - if (f.exists() && f.isDirectory()) - return path; - - path = new StoragePathManager().findMapsMeStorage(settingsPath); - Config.setStoragePath(path); - return path; - } - - return settingsPath; + return addTrailingSeparator(application.getFilesDir().getAbsolutePath()); } @NonNull - public static String getFilesPath(@NonNull Application application) + public static String getPrivatePath(@NonNull Application application) { - final File filesDir = application.getExternalFilesDir(null); - if (filesDir != null) - return filesDir.getAbsolutePath(); - - return Environment.getExternalStorageDirectory().getAbsolutePath() + - String.format(Constants.STORAGE_PATH, BuildConfig.APPLICATION_ID, Constants.FILES_DIR); + return addTrailingSeparator(application.getFilesDir().getAbsolutePath()); } @NonNull public static String getTempPath(@NonNull Application application) { - final File cacheDir = application.getExternalCacheDir(); + final File cacheDir = application.getExternalCacheDir(); if (cacheDir != null) - return cacheDir.getAbsolutePath(); + return addTrailingSeparator(cacheDir.getAbsolutePath()); - return Environment.getExternalStorageDirectory().getAbsolutePath() + - String.format(Constants.STORAGE_PATH, BuildConfig.APPLICATION_ID, Constants.CACHE_DIR); + return addTrailingSeparator(application.getCacheDir().getAbsolutePath()); } public static boolean createDirectory(@NonNull Context context, @NonNull String path) @@ -159,13 +143,8 @@ public class StorageUtils File directory = new File(path); if (!directory.exists() && !directory.mkdirs()) { - boolean isPermissionGranted = PermissionsUtils.isExternalStorageGranted(context); - Throwable error = new IllegalStateException("Can't create directories for: " + path - + " state = " + Environment.getExternalStorageState() - + " isPermissionGranted = " + isPermissionGranted); - LOGGER.e(TAG, "Can't create directories for: " + path - + " state = " + Environment.getExternalStorageState() - + " isPermissionGranted = " + isPermissionGranted); + Throwable error = new IllegalStateException("Can't create directories for: " + path); + LOGGER.e(TAG, "Can't create directories for: " + path); CrashlyticsUtils.INSTANCE.logException(error); return false; }