Bläddra i källkod

android: Added SDL_AndroidGetCachePath().

Fixes #8408.
Ryan C. Gordon 9 månader sedan
förälder
incheckning
8779c95905

+ 1 - 0
docs/README-android.md

@@ -172,6 +172,7 @@ useful paths for saving and loading data:
 * SDL_AndroidGetInternalStoragePath()
 * SDL_AndroidGetExternalStorageState()
 * SDL_AndroidGetExternalStoragePath()
+* SDL_AndroidGetCachePath()
 
 See SDL_system.h for more details on these functions.
 

+ 33 - 3
include/SDL3/SDL_system.h

@@ -395,7 +395,7 @@ extern SDL_DECLSPEC void SDLCALL SDL_AndroidBackButton(void);
 #define SDL_ANDROID_EXTERNAL_STORAGE_WRITE  0x02
 
 /**
- * Get the path used for internal storage for this application.
+ * Get the path used for internal storage for this Android application.
  *
  * This path is unique to your application and cannot be written to by other
  * applications.
@@ -403,6 +403,10 @@ extern SDL_DECLSPEC void SDLCALL SDL_AndroidBackButton(void);
  * Your internal storage path is typically:
  * `/data/data/your.app.package/files`.
  *
+ * This is a C wrapper over `android.content.Context.getFilesDir()`:
+ *
+ * https://developer.android.com/reference/android/content/Context#getFilesDir()
+ *
  * The returned string follows the SDL_GetStringRule.
  *
  * \returns the path used for internal storage or NULL on failure; call
@@ -415,7 +419,7 @@ extern SDL_DECLSPEC void SDLCALL SDL_AndroidBackButton(void);
 extern SDL_DECLSPEC const char *SDLCALL SDL_AndroidGetInternalStoragePath(void);
 
 /**
- * Get the current state of external storage.
+ * Get the current state of external storage for this Android application.
  *
  * The current state of external storage, a bitmask of these values:
  * `SDL_ANDROID_EXTERNAL_STORAGE_READ`, `SDL_ANDROID_EXTERNAL_STORAGE_WRITE`.
@@ -434,7 +438,7 @@ extern SDL_DECLSPEC const char *SDLCALL SDL_AndroidGetInternalStoragePath(void);
 extern SDL_DECLSPEC int SDLCALL SDL_AndroidGetExternalStorageState(Uint32 *state);
 
 /**
- * Get the path used for external storage for this application.
+ * Get the path used for external storage for this Android application.
  *
  * This path is unique to your application, but is public and can be written
  * to by other applications.
@@ -442,6 +446,10 @@ extern SDL_DECLSPEC int SDLCALL SDL_AndroidGetExternalStorageState(Uint32 *state
  * Your external storage path is typically:
  * `/storage/sdcard0/Android/data/your.app.package/files`.
  *
+ * This is a C wrapper over `android.content.Context.getExternalFilesDir()`:
+ *
+ * https://developer.android.com/reference/android/content/Context#getExternalFilesDir()
+ *
  * The returned string follows the SDL_GetStringRule.
  *
  * \returns the path used for external storage for this application on success
@@ -453,6 +461,28 @@ extern SDL_DECLSPEC int SDLCALL SDL_AndroidGetExternalStorageState(Uint32 *state
  */
 extern SDL_DECLSPEC const char * SDLCALL SDL_AndroidGetExternalStoragePath(void);
 
+/**
+ * Get the path used for caching data for this Android application.
+ *
+ * This path is unique to your application, but is public and can be written
+ * to by other applications.
+ *
+ * Your cache path is typically:
+ * `/data/data/your.app.package/cache/`.
+ *
+ * This is a C wrapper over `android.content.Context.getCacheDir()`:
+ *
+ * https://developer.android.com/reference/android/content/Context#getCacheDir()
+ *
+ * The returned string follows the SDL_GetStringRule.
+ *
+ * \returns the path used for caches for this application on success
+ *          or NULL on failure; call SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 3.0.0.
+ */
+extern SDL_DECLSPEC const char * SDLCALL SDL_AndroidGetCachePath(void);
+
 
 typedef void (SDLCALL *SDL_AndroidRequestPermissionCallback)(void *userdata, const char *permission, SDL_bool granted);
 

+ 8 - 0
src/core/SDL_core_unsupported.c

@@ -127,6 +127,14 @@ void *SDL_AndroidGetActivity()
     return NULL;
 }
 
+SDL_DECLSPEC const char *SDLCALL SDL_AndroidGetCachePath(void);
+const char* SDL_AndroidGetCachePath()
+{
+    SDL_Unsupported();
+    return NULL;
+}
+
+
 SDL_DECLSPEC const char *SDLCALL SDL_AndroidGetExternalStoragePath(void);
 const char* SDL_AndroidGetExternalStoragePath()
 {

+ 47 - 0
src/core/android/SDL_android.c

@@ -2598,6 +2598,53 @@ const char *SDL_AndroidGetExternalStoragePath(void)
     return s_AndroidExternalFilesPath;
 }
 
+// this caches a string until the process ends, so there's no need to use SDL_FreeLater.
+const char *SDL_AndroidGetCachePath(void)
+{
+    // !!! FIXME: lots of duplication with SDL_AndroidGetExternalStoragePath and SDL_AndroidGetInternalStoragePath; consolidate these functions!
+    static char *s_AndroidCachePath = NULL;
+
+    if (!s_AndroidCachePath) {
+        struct LocalReferenceHolder refs = LocalReferenceHolder_Setup(__FUNCTION__);
+        jmethodID mid;
+        jobject context;
+        jobject fileObject;
+        jstring pathString;
+        const char *path;
+
+        JNIEnv *env = Android_JNI_GetEnv();
+        if (!LocalReferenceHolder_Init(&refs, env)) {
+            LocalReferenceHolder_Cleanup(&refs);
+            return NULL;
+        }
+
+        /* context = SDLActivity.getContext(); */
+        context = (*env)->CallStaticObjectMethod(env, mActivityClass, midGetContext);
+
+        /* fileObj = context.getExternalFilesDir(); */
+        mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, context),
+                                  "getCacheDir", "(Ljava/lang/String;)Ljava/io/File;");
+        fileObject = (*env)->CallObjectMethod(env, context, mid, NULL);
+        if (!fileObject) {
+            SDL_SetError("Couldn't get cache directory");
+            LocalReferenceHolder_Cleanup(&refs);
+            return NULL;
+        }
+
+        /* path = fileObject.getAbsolutePath(); */
+        mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, fileObject),
+                                  "getAbsolutePath", "()Ljava/lang/String;");
+        pathString = (jstring)(*env)->CallObjectMethod(env, fileObject, mid);
+
+        path = (*env)->GetStringUTFChars(env, pathString, NULL);
+        s_AndroidCachePath = SDL_strdup(path);
+        (*env)->ReleaseStringUTFChars(env, pathString, path);
+
+        LocalReferenceHolder_Cleanup(&refs);
+    }
+    return s_AndroidCachePath;
+}
+
 int SDL_AndroidShowToast(const char *message, int duration, int gravity, int xOffset, int yOffset)
 {
     return Android_JNI_ShowToast(message, duration, gravity, xOffset, yOffset);

+ 1 - 0
src/dynapi/SDL_dynapi.sym

@@ -14,6 +14,7 @@ SDL3_0.0.0 {
     SDL_AllocateEventMemory;
     SDL_AndroidBackButton;
     SDL_AndroidGetActivity;
+    SDL_AndroidGetCachePath;
     SDL_AndroidGetExternalStoragePath;
     SDL_AndroidGetExternalStorageState;
     SDL_AndroidGetInternalStoragePath;

+ 1 - 0
src/dynapi/SDL_dynapi_overrides.h

@@ -39,6 +39,7 @@
 #define SDL_AllocateEventMemory SDL_AllocateEventMemory_REAL
 #define SDL_AndroidBackButton SDL_AndroidBackButton_REAL
 #define SDL_AndroidGetActivity SDL_AndroidGetActivity_REAL
+#define SDL_AndroidGetCachePath SDL_AndroidGetCachePath_REAL
 #define SDL_AndroidGetExternalStoragePath SDL_AndroidGetExternalStoragePath_REAL
 #define SDL_AndroidGetExternalStorageState SDL_AndroidGetExternalStorageState_REAL
 #define SDL_AndroidGetInternalStoragePath SDL_AndroidGetInternalStoragePath_REAL

+ 1 - 0
src/dynapi/SDL_dynapi_procs.h

@@ -59,6 +59,7 @@ SDL_DYNAPI_PROC(int,SDL_AddVulkanRenderSemaphores,(SDL_Renderer *a, Uint32 b, Si
 SDL_DYNAPI_PROC(void*,SDL_AllocateEventMemory,(size_t a),(a),return)
 SDL_DYNAPI_PROC(void,SDL_AndroidBackButton,(void),(),)
 SDL_DYNAPI_PROC(void*,SDL_AndroidGetActivity,(void),(),return)
+SDL_DYNAPI_PROC(const char*,SDL_AndroidGetCachePath,(void),(),return)
 SDL_DYNAPI_PROC(const char*,SDL_AndroidGetExternalStoragePath,(void),(),return)
 SDL_DYNAPI_PROC(int,SDL_AndroidGetExternalStorageState,(Uint32 *a),(a),return)
 SDL_DYNAPI_PROC(const char*,SDL_AndroidGetInternalStoragePath,(void),(),return)