From d91a066ceaf017a23a29ea3064d69cb802bb2ea1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Adrien=20B=C3=A9raud?= <adrien.beraud@savoirfairelinux.com>
Date: Wed, 10 Jun 2015 10:47:31 -0400
Subject: [PATCH] android: add signal to retreive cache/data paths

The API to get data/cache paths are Java only.
Currently  we need to access files and cache paths but the design
keeps the possibility to access other paths using the name signal.

Refs #75320

Change-Id: Ic691f0b5073b8d5fa437e3aea64ad1ec9a19ac09
---
 src/client/ring_signal.cpp                 |  1 +
 src/dring/configurationmanager_interface.h |  8 ++
 src/fileutils.cpp                          | 88 +++++++++++++++++-----
 src/fileutils.h                            |  4 +-
 src/manager.cpp                            | 27 +------
 5 files changed, 80 insertions(+), 48 deletions(-)

diff --git a/src/client/ring_signal.cpp b/src/client/ring_signal.cpp
index dd03668cb4..01416ada5c 100644
--- a/src/client/ring_signal.cpp
+++ b/src/client/ring_signal.cpp
@@ -79,6 +79,7 @@ getSignalHandlers()
         exported_callback<DRing::ConfigurationSignal::Error>(),
 #ifdef __ANDROID__
         exported_callback<DRing::ConfigurationSignal::GetHardwareAudioFormat>(),
+        exported_callback<DRing::ConfigurationSignal::GetAppDataPath>(),
 #endif
 
         /* Presence */
diff --git a/src/dring/configurationmanager_interface.h b/src/dring/configurationmanager_interface.h
index 1de64f7bf3..0a77fa3da9 100644
--- a/src/dring/configurationmanager_interface.h
+++ b/src/dring/configurationmanager_interface.h
@@ -210,10 +210,18 @@ struct ConfigurationSignal {
                 using cb_type = void(const std::string& /*account_id*/, const std::string& /*certId*/, const std::string& /*state*/);
         };
 #ifdef __ANDROID__
+        /**
+         * These are special getters for Android so the daemon can retreive
+         * some informations only accessible through Java APIs
+         */
         struct GetHardwareAudioFormat {
                 constexpr static const char* name = "GetHardwareAudioFormat";
                 using cb_type = void(std::vector<int32_t>* /* params_ret */);
         };
+        struct GetAppDataPath {
+                constexpr static const char* name = "GetAppDataPath";
+                using cb_type = void(const std::string& name, std::vector<std::string>* /* path_ret */);
+        };
 #endif
 };
 
diff --git a/src/fileutils.cpp b/src/fileutils.cpp
index d5d7beb369..7b4f7d985b 100644
--- a/src/fileutils.cpp
+++ b/src/fileutils.cpp
@@ -39,6 +39,10 @@
 #include "logger.h"
 #include "intrin.h"
 
+#ifdef __ANDROID__
+#include "client/ring_signal.h"
+#endif
+
 #include <sys/types.h>
 #include <sys/stat.h>
 
@@ -90,22 +94,6 @@ bool check_dir(const char *path)
     return true;
 }
 
-#ifdef __ANDROID__
-static char *program_dir = "/data/data/cx.ring";
-#else
-static char *program_dir = NULL;
-#endif
-
-void set_program_dir(char *program_path)
-{
-    program_dir = dirname(program_path);
-}
-
-const char *get_program_dir()
-{
-    return program_dir;
-}
-
 #ifndef _WIN32
 /* Lock a file region */
 static int
@@ -322,6 +310,18 @@ FileHandle::~FileHandle()
     }
 }
 
+#ifdef __ANDROID__
+static std::string files_path;
+static std::string cache_path;
+static std::string config_path;
+#else
+static char *program_dir = NULL;
+void set_program_dir(char *program_path)
+{
+    program_dir = dirname(program_path);
+}
+#endif
+
 std::string
 get_cache_dir()
 {
@@ -331,7 +331,11 @@ get_cache_dir()
         return cache_home;
     } else {
 #ifdef __ANDROID__
-        return get_home_dir() + DIR_SEPARATOR_STR + PACKAGE;
+        std::vector<std::string> paths;
+        emitSignal<DRing::ConfigurationSignal::GetAppDataPath>("cache", &paths);
+        if (not paths.empty())
+            cache_path = paths[0];
+        return cache_path;
 #elif defined(__APPLE__)
         return get_home_dir() + DIR_SEPARATOR_STR
             + "Library" + DIR_SEPARATOR_STR + "Caches"
@@ -347,7 +351,11 @@ std::string
 get_home_dir()
 {
 #if defined __ANDROID__
-    return get_program_dir();
+    std::vector<std::string> paths;
+    emitSignal<DRing::ConfigurationSignal::GetAppDataPath>("files", &paths);
+    if (not paths.empty())
+        files_path = paths[0];
+    return files_path;
 #elif defined _WIN32
     WCHAR path[MAX_PATH];
     if (SUCCEEDED(SHGetFolderPathW(nullptr, CSIDL_PROFILE, nullptr, 0, path))) {
@@ -356,7 +364,7 @@ get_home_dir()
         WideCharToMultiByte(CP_ACP, 0, path, -1, tmp, MAX_PATH, &DefChar, nullptr);
         return std::string(tmp);
     }
-    return get_program_dir();
+    return program_dir;
 #else
 
     // 1) try getting user's home directory from the environment
@@ -381,7 +389,11 @@ std::string
 get_data_dir()
 {
 #ifdef __ANDROID__
-    return get_program_dir();
+    std::vector<std::string> paths;
+    emitSignal<DRing::ConfigurationSignal::GetAppDataPath>("files", &paths);
+    if (not paths.empty())
+        files_path = paths[0];
+    return files_path;
 #elif defined(__APPLE__)
     return get_home_dir() + DIR_SEPARATOR_STR
             + "Library" + DIR_SEPARATOR_STR + "Application Support"
@@ -397,6 +409,42 @@ get_data_dir()
 #endif
 }
 
+std::string
+get_config_dir()
+{
+#ifdef __ANDROID__
+    std::vector<std::string> paths;
+    emitSignal<DRing::ConfigurationSignal::GetAppDataPath>("config", &paths);
+    if (not paths.empty())
+        config_path = paths[0];
+    return config_path;
+#else
+#ifdef __APPLE__
+    std::string configdir = fileutils::get_home_dir() + DIR_SEPARATOR_STR
+        + "Library" + DIR_SEPARATOR_STR + "Application Support"
+        + DIR_SEPARATOR_STR + PACKAGE;
+#else
+    std::string configdir = fileutils::get_home_dir() + DIR_SEPARATOR_STR +
+                            ".config" + DIR_SEPARATOR_STR + PACKAGE;
+#endif
+
+    const std::string xdg_env(XDG_CONFIG_HOME);
+    if (not xdg_env.empty())
+        configdir = xdg_env + DIR_SEPARATOR_STR + PACKAGE;
+
+#ifndef _WIN32
+    if (mkdir(configdir.data(), 0700) != 0) {
+#else
+    if (fileutils::recursive_mkdir(configdir.data()) != true) {
+#endif
+        // If directory creation failed
+        if (errno != EEXIST)
+            RING_DBG("Cannot create directory: %s!", configdir.c_str());
+    }
+    return configdir;
+#endif
+}
+
 #ifdef _WIN32
 bool
 recursive_mkdir(const std::string& path)
diff --git a/src/fileutils.h b/src/fileutils.h
index d784e7b3c8..bd8fc64f0e 100644
--- a/src/fileutils.h
+++ b/src/fileutils.h
@@ -54,12 +54,12 @@
 
 namespace ring { namespace fileutils {
 
-    std::string get_data_dir();
     std::string get_home_dir();
+    std::string get_config_dir();
+    std::string get_data_dir();
     std::string get_cache_dir();
     bool check_dir(const char *path);
     void set_program_dir(char *program_path);
-    const char *get_program_dir();
     std::string expand_path(const std::string &path);
     bool isDirectoryWritable(const std::string &directory);
 
diff --git a/src/manager.cpp b/src/manager.cpp
index e19296e908..47f2114ad2 100644
--- a/src/manager.cpp
+++ b/src/manager.cpp
@@ -2017,33 +2017,8 @@ Manager::getTelephoneFile()
 std::string
 Manager::retrieveConfigPath() const
 {
-#ifdef __ANDROID__
-    std::string configdir = "/data/data/cx.ring";
-#elif __APPLE__
-    std::string configdir = fileutils::get_home_dir() + DIR_SEPARATOR_STR
-        + "Library" + DIR_SEPARATOR_STR + "Application Support"
-        + DIR_SEPARATOR_STR + PACKAGE;
-#else
-    std::string configdir = fileutils::get_home_dir() + DIR_SEPARATOR_STR +
-                            ".config" + DIR_SEPARATOR_STR + PACKAGE;
-#endif
-
-    const std::string xdg_env(XDG_CONFIG_HOME);
-    if (not xdg_env.empty())
-        configdir = xdg_env + DIR_SEPARATOR_STR + PACKAGE;
-
-#ifndef _WIN32
-    if (mkdir(configdir.data(), 0700) != 0) {
-#else
-    if (fileutils::recursive_mkdir(configdir.data()) != true) {
-#endif
-        // If directory creation failed
-        if (errno != EEXIST)
-            RING_DBG("Cannot create directory: %s!", configdir.c_str());
-    }
-
     static const char * const PROGNAME = "dring";
-    return configdir + DIR_SEPARATOR_STR + PROGNAME + ".yml";
+    return fileutils::get_config_dir() + DIR_SEPARATOR_STR + PROGNAME + ".yml";
 }
 
 /**
-- 
GitLab