|
57 | 57 |
|
58 | 58 | #ifdef ANDROID |
59 | 59 | #include <sys/system_properties.h> |
| 60 | +#ifdef HAVE_SAF |
| 61 | +#include <vfs/vfs_implementation_saf.h> |
| 62 | +#include "../../menu/menu_cbs.h" |
| 63 | +#endif |
60 | 64 | #endif |
61 | 65 |
|
62 | 66 | #if defined(DINGUX) |
@@ -608,6 +612,64 @@ static void frontend_android_shutdown(bool unused) |
608 | 612 | exit(0); |
609 | 613 | } |
610 | 614 |
|
| 615 | +#ifdef HAVE_SAF |
| 616 | +void android_show_saf_tree_picker(void) |
| 617 | +{ |
| 618 | + JNIEnv *env; |
| 619 | + |
| 620 | + if (!g_android || !g_android->have_saf) |
| 621 | + return; |
| 622 | + |
| 623 | + env = jni_thread_getenv(); |
| 624 | + if (!env) |
| 625 | + return; |
| 626 | + |
| 627 | + CALL_VOID_METHOD(env, g_android->activity->clazz, g_android->requestOpenDocumentTree); |
| 628 | +} |
| 629 | +#endif |
| 630 | + |
| 631 | +/* |
| 632 | + * Class: com_retroarch_browser_retroactivity_RetroActivityCommon |
| 633 | + * Method: safTreeAdded |
| 634 | + * Signature: (Ljava/lang/String;)V |
| 635 | + */ |
| 636 | +JNIEXPORT void JNICALL Java_com_retroarch_browser_retroactivity_RetroActivityCommon_safTreeAdded |
| 637 | + (JNIEnv *env, jobject this_obj, jstring tree_obj) |
| 638 | +{ |
| 639 | +#ifdef HAVE_SAF |
| 640 | + const char *tree; |
| 641 | + char *serialized_path; |
| 642 | + |
| 643 | + tree = (*env)->GetStringUTFChars(env, tree_obj, NULL); |
| 644 | + if ((*env)->ExceptionOccurred(env)) |
| 645 | + { |
| 646 | + (*env)->ExceptionDescribe(env); |
| 647 | + (*env)->ExceptionClear(env); |
| 648 | + return; |
| 649 | + } |
| 650 | + |
| 651 | + if ((serialized_path = retro_vfs_path_join_saf(tree, "")) != NULL) |
| 652 | + { |
| 653 | + generic_action_ok_displaylist_push( |
| 654 | + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_FILE_BROWSER_OPEN_PICKER), |
| 655 | + serialized_path, |
| 656 | + msg_hash_to_str(MENU_ENUM_LABEL_FAVORITES), |
| 657 | + MENU_SETTING_ACTION, |
| 658 | + 0, |
| 659 | + 0, |
| 660 | + ACTION_OK_DL_CONTENT_LIST); |
| 661 | + free(serialized_path); |
| 662 | + } |
| 663 | + |
| 664 | + (*env)->ReleaseStringUTFChars(env, tree_obj, tree); |
| 665 | + if ((*env)->ExceptionOccurred(env)) |
| 666 | + { |
| 667 | + (*env)->ExceptionDescribe(env); |
| 668 | + (*env)->ExceptionClear(env); |
| 669 | + } |
| 670 | +#endif |
| 671 | +} |
| 672 | + |
611 | 673 | #elif !defined(DINGUX) |
612 | 674 | static bool make_proc_acpi_key_val(char **_ptr, char **_key, char **_val) |
613 | 675 | { |
@@ -1973,6 +2035,11 @@ static void android_app_destroy(struct android_app *android_app) |
1973 | 2035 | CALL_VOID_METHOD(env, android_app->activity->clazz, |
1974 | 2036 | android_app->onRetroArchExit); |
1975 | 2037 |
|
| 2038 | +#ifdef HAVE_SAF |
| 2039 | + if (android_app->have_saf) |
| 2040 | + retro_vfs_deinit_saf(); |
| 2041 | +#endif |
| 2042 | + |
1976 | 2043 | if (android_app->inputQueue) |
1977 | 2044 | AInputQueue_detachLooper(android_app->inputQueue); |
1978 | 2045 |
|
@@ -2135,6 +2202,18 @@ static void frontend_unix_init(void *data) |
2135 | 2202 | GET_METHOD_ID(env, android_app->accessibilitySpeak, class, |
2136 | 2203 | "accessibilitySpeak", "(Ljava/lang/String;)V"); |
2137 | 2204 |
|
| 2205 | + CALL_BOOLEAN_METHOD(env, android_app->is_play_store_build, android_app->activity->clazz, android_app->isPlayStoreBuild) |
| 2206 | + |
| 2207 | +#ifdef HAVE_SAF |
| 2208 | + GET_METHOD_ID(env, android_app->requestOpenDocumentTree, class, |
| 2209 | + "requestOpenDocumentTree", "()V"); |
| 2210 | + |
| 2211 | + GET_METHOD_ID(env, android_app->getPersistedSafTrees, class, |
| 2212 | + "getPersistedSafTrees", "()[Ljava/lang/String;"); |
| 2213 | + |
| 2214 | + android_app->have_saf = retro_vfs_init_saf(jni_thread_getenv, android_app->activity->clazz); |
| 2215 | +#endif |
| 2216 | + |
2138 | 2217 | GET_OBJECT_CLASS(env, class, obj); |
2139 | 2218 | GET_METHOD_ID(env, android_app->getStringExtra, class, |
2140 | 2219 | "getStringExtra", "(Ljava/lang/String;)Ljava/lang/String;"); |
@@ -2184,53 +2263,73 @@ static int frontend_unix_parse_drive_list(void *data, bool load_content) |
2184 | 2263 | CALL_OBJ_METHOD(env, obj, g_android->activity->clazz, |
2185 | 2264 | g_android->getIntent); |
2186 | 2265 |
|
2187 | | - if (g_android->getVolumeCount) |
| 2266 | + if (!g_android->is_play_store_build && g_android->getVolumeCount) |
2188 | 2267 | { |
2189 | 2268 | CALL_INT_METHOD(env, output, |
2190 | 2269 | g_android->activity->clazz, g_android->getVolumeCount); |
2191 | 2270 | volume_count = output; |
2192 | 2271 | } |
2193 | 2272 |
|
2194 | | - if (!string_is_empty(internal_storage_path)) |
| 2273 | + if (!g_android->is_play_store_build) |
2195 | 2274 | { |
2196 | | - if (storage_permissions == INTERNAL_STORAGE_WRITABLE) |
| 2275 | + if (!string_is_empty(internal_storage_path)) |
2197 | 2276 | { |
2198 | | - char user_data_path[PATH_MAX_LENGTH]; |
2199 | | - fill_pathname_join_special(user_data_path, |
2200 | | - internal_storage_path, "RetroArch", |
2201 | | - sizeof(user_data_path)); |
| 2277 | + if (storage_permissions == INTERNAL_STORAGE_WRITABLE) |
| 2278 | + { |
| 2279 | + char user_data_path[PATH_MAX_LENGTH]; |
| 2280 | + fill_pathname_join_special(user_data_path, |
| 2281 | + internal_storage_path, "RetroArch", |
| 2282 | + sizeof(user_data_path)); |
| 2283 | + |
| 2284 | + menu_entries_append(list, |
| 2285 | + user_data_path, |
| 2286 | + msg_hash_to_str(MSG_INTERNAL_STORAGE), |
| 2287 | + enum_idx, |
| 2288 | + FILE_TYPE_DIRECTORY, 0, 0, NULL); |
| 2289 | + } |
2202 | 2290 |
|
2203 | 2291 | menu_entries_append(list, |
2204 | | - user_data_path, |
| 2292 | + internal_storage_path, |
2205 | 2293 | msg_hash_to_str(MSG_INTERNAL_STORAGE), |
2206 | 2294 | enum_idx, |
2207 | 2295 | FILE_TYPE_DIRECTORY, 0, 0, NULL); |
2208 | 2296 | } |
2209 | | - |
2210 | | - menu_entries_append(list, |
2211 | | - internal_storage_path, |
2212 | | - msg_hash_to_str(MSG_INTERNAL_STORAGE), |
2213 | | - enum_idx, |
2214 | | - FILE_TYPE_DIRECTORY, 0, 0, NULL); |
| 2297 | + else |
| 2298 | + menu_entries_append(list, |
| 2299 | + "/storage/emulated/0", |
| 2300 | + msg_hash_to_str(MSG_REMOVABLE_STORAGE), |
| 2301 | + enum_idx, |
| 2302 | + FILE_TYPE_DIRECTORY, 0, 0, NULL); |
2215 | 2303 | } |
2216 | | - else |
| 2304 | + |
| 2305 | + if (!g_android->is_play_store_build) |
2217 | 2306 | menu_entries_append(list, |
2218 | | - "/storage/emulated/0", |
| 2307 | + "/storage", |
2219 | 2308 | msg_hash_to_str(MSG_REMOVABLE_STORAGE), |
2220 | 2309 | enum_idx, |
2221 | 2310 | FILE_TYPE_DIRECTORY, 0, 0, NULL); |
2222 | | - |
2223 | | - menu_entries_append(list, |
2224 | | - "/storage", |
2225 | | - msg_hash_to_str(MSG_REMOVABLE_STORAGE), |
2226 | | - enum_idx, |
2227 | | - FILE_TYPE_DIRECTORY, 0, 0, NULL); |
2228 | 2311 | if (!string_is_empty(internal_storage_app_path)) |
| 2312 | + { |
| 2313 | + if (g_android->is_play_store_build) |
| 2314 | + { |
| 2315 | + char user_data_app_path[PATH_MAX_LENGTH]; |
| 2316 | + fill_pathname_join_special(user_data_app_path, |
| 2317 | + internal_storage_app_path, "RetroArch", |
| 2318 | + sizeof(user_data_app_path)); |
| 2319 | + |
| 2320 | + menu_entries_append(list, |
| 2321 | + user_data_app_path, |
| 2322 | + msg_hash_to_str(MSG_EXTERNAL_APPLICATION_DIR), |
| 2323 | + enum_idx, |
| 2324 | + FILE_TYPE_DIRECTORY, 0, 0, NULL); |
| 2325 | + } |
| 2326 | + |
2229 | 2327 | menu_entries_append(list, |
2230 | 2328 | internal_storage_app_path, |
2231 | 2329 | msg_hash_to_str(MSG_EXTERNAL_APPLICATION_DIR), |
2232 | 2330 | enum_idx, |
2233 | 2331 | FILE_TYPE_DIRECTORY, 0, 0, NULL); |
| 2332 | + } |
2234 | 2333 | if (!string_is_empty(app_dir)) |
2235 | 2334 | menu_entries_append(list, |
2236 | 2335 | app_dir, |
@@ -2266,8 +2365,8 @@ static int frontend_unix_parse_drive_list(void *data, bool load_content) |
2266 | 2365 | enum_idx, |
2267 | 2366 | FILE_TYPE_DIRECTORY, 0, 0, NULL); |
2268 | 2367 | } |
2269 | | - |
2270 | 2368 | } |
| 2369 | + |
2271 | 2370 | #elif defined(WEBOS) |
2272 | 2371 | if (path_is_directory("/media/internal")) |
2273 | 2372 | menu_entries_append(list, "/media/internal", |
@@ -2349,10 +2448,84 @@ static int frontend_unix_parse_drive_list(void *data, bool load_content) |
2349 | 2448 | } |
2350 | 2449 | #endif |
2351 | 2450 |
|
2352 | | - menu_entries_append(list, "/", |
2353 | | - msg_hash_to_str(MENU_ENUM_LABEL_FILE_DETECT_CORE_LIST_PUSH_DIR), |
2354 | | - enum_idx, |
2355 | | - FILE_TYPE_DIRECTORY, 0, 0, NULL); |
| 2451 | +#ifdef ANDROID |
| 2452 | + if (!g_android->is_play_store_build) |
| 2453 | +#else |
| 2454 | + if (1) |
| 2455 | +#endif |
| 2456 | + { |
| 2457 | + menu_entries_append(list, "/", |
| 2458 | + msg_hash_to_str(MENU_ENUM_LABEL_FILE_DETECT_CORE_LIST_PUSH_DIR), |
| 2459 | + enum_idx, |
| 2460 | + FILE_TYPE_DIRECTORY, 0, 0, NULL); |
| 2461 | + } |
| 2462 | + |
| 2463 | +#if defined(ANDROID) && defined(HAVE_SAF) |
| 2464 | + if (g_android->have_saf) |
| 2465 | + { |
| 2466 | + JNIEnv *env = jni_thread_getenv(); |
| 2467 | + |
| 2468 | + if (env != NULL) |
| 2469 | + { |
| 2470 | + jarray trees = (*env)->CallObjectMethod(env, g_android->activity->clazz, g_android->getPersistedSafTrees); |
| 2471 | + if ((*env)->ExceptionOccurred(env)) |
| 2472 | + { |
| 2473 | + (*env)->ExceptionDescribe(env); |
| 2474 | + (*env)->ExceptionClear(env); |
| 2475 | + } |
| 2476 | + else |
| 2477 | + { |
| 2478 | + jsize trees_length = (*env)->GetArrayLength(env, trees); |
| 2479 | + if ((*env)->ExceptionOccurred(env)) |
| 2480 | + { |
| 2481 | + (*env)->ExceptionDescribe(env); |
| 2482 | + (*env)->ExceptionClear(env); |
| 2483 | + } |
| 2484 | + else |
| 2485 | + for (jsize i = 0; i < trees_length; ++i) |
| 2486 | + { |
| 2487 | + const char *tree_chars; |
| 2488 | + char *serialized_path; |
| 2489 | + jstring tree = (*env)->GetObjectArrayElement(env, trees, i); |
| 2490 | + if ((*env)->ExceptionOccurred(env)) |
| 2491 | + { |
| 2492 | + (*env)->ExceptionDescribe(env); |
| 2493 | + (*env)->ExceptionClear(env); |
| 2494 | + continue; |
| 2495 | + } |
| 2496 | + tree_chars = (*env)->GetStringUTFChars(env, tree, NULL); |
| 2497 | + if ((*env)->ExceptionOccurred(env)) |
| 2498 | + { |
| 2499 | + (*env)->ExceptionDescribe(env); |
| 2500 | + (*env)->ExceptionClear(env); |
| 2501 | + continue; |
| 2502 | + } |
| 2503 | + if ((serialized_path = retro_vfs_path_join_saf(tree_chars, "")) != NULL) |
| 2504 | + { |
| 2505 | + menu_entries_append(list, |
| 2506 | + serialized_path, |
| 2507 | + msg_hash_to_str(MSG_REMOVABLE_STORAGE), |
| 2508 | + enum_idx, |
| 2509 | + FILE_TYPE_DIRECTORY, 0, 0, NULL); |
| 2510 | + free(serialized_path); |
| 2511 | + } |
| 2512 | + (*env)->ReleaseStringUTFChars(env, tree, tree_chars); |
| 2513 | + if ((*env)->ExceptionOccurred(env)) |
| 2514 | + { |
| 2515 | + (*env)->ExceptionDescribe(env); |
| 2516 | + (*env)->ExceptionClear(env); |
| 2517 | + } |
| 2518 | + } |
| 2519 | + } |
| 2520 | + } |
| 2521 | + |
| 2522 | + menu_entries_append(list, |
| 2523 | + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_FILE_BROWSER_OPEN_PICKER), |
| 2524 | + msg_hash_to_str(MENU_ENUM_LABEL_FILE_BROWSER_OPEN_PICKER), |
| 2525 | + MENU_ENUM_LABEL_FILE_BROWSER_OPEN_PICKER, |
| 2526 | + MENU_SETTING_ACTION, 0, 0, NULL); |
| 2527 | + } |
| 2528 | +#endif |
2356 | 2529 | #endif |
2357 | 2530 |
|
2358 | 2531 | return 0; |
|
0 commit comments