From 116a5a79daa9033e80392486731ef43f8884c3f6 Mon Sep 17 00:00:00 2001 From: JosJuice Date: Fri, 8 Jan 2021 16:12:18 +0100 Subject: [PATCH] Android: Use old folder picker on Android TV See the comment I added to the code. This is a rather serious issue for Android TV users from what I've heard. --- .../dolphinemu/ui/main/MainActivity.java | 20 ++++++++++++--- .../dolphinemu/ui/main/MainPresenter.java | 11 ++++++++ .../dolphinemu/ui/main/TvMainActivity.java | 20 ++++++++++++--- .../utils/DirectoryInitialization.java | 25 +++++++++++++++++++ 4 files changed, 70 insertions(+), 6 deletions(-) diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/MainActivity.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/MainActivity.java index e5150758d4..7b4f886d87 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/MainActivity.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/MainActivity.java @@ -163,8 +163,15 @@ public final class MainActivity extends AppCompatActivity implements MainView @Override public void launchFileListActivity() { - Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE); - startActivityForResult(intent, MainPresenter.REQUEST_DIRECTORY); + if (DirectoryInitialization.preferOldFolderPicker(this)) + { + FileBrowserHelper.openDirectoryPicker(this, FileBrowserHelper.GAME_EXTENSIONS); + } + else + { + Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE); + startActivityForResult(intent, MainPresenter.REQUEST_DIRECTORY); + } } @Override @@ -202,7 +209,14 @@ public final class MainActivity extends AppCompatActivity implements MainView switch (requestCode) { case MainPresenter.REQUEST_DIRECTORY: - mPresenter.onDirectorySelected(result); + if (DirectoryInitialization.preferOldFolderPicker(this)) + { + mPresenter.onDirectorySelected(FileBrowserHelper.getSelectedPath(result)); + } + else + { + mPresenter.onDirectorySelected(result); + } break; case MainPresenter.REQUEST_GAME_FILE: diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/MainPresenter.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/MainPresenter.java index cc06689c9b..1ded576794 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/MainPresenter.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/MainPresenter.java @@ -112,6 +112,17 @@ public final class MainPresenter } } + /** + * Called when a selection is made using the legacy folder picker. + */ + public void onDirectorySelected(String dir) + { + mDirToAdd = dir; + } + + /** + * Called when a selection is made using the Storage Access Framework folder picker. + */ public void onDirectorySelected(Intent result) { Uri uri = result.getData(); diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/TvMainActivity.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/TvMainActivity.java index 1141b98dbf..8e96083ce1 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/TvMainActivity.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/TvMainActivity.java @@ -168,8 +168,15 @@ public final class TvMainActivity extends FragmentActivity implements MainView @Override public void launchFileListActivity() { - Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE); - startActivityForResult(intent, MainPresenter.REQUEST_DIRECTORY); + if (DirectoryInitialization.preferOldFolderPicker(this)) + { + FileBrowserHelper.openDirectoryPicker(this, FileBrowserHelper.GAME_EXTENSIONS); + } + else + { + Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE); + startActivityForResult(intent, MainPresenter.REQUEST_DIRECTORY); + } } @Override @@ -226,7 +233,14 @@ public final class TvMainActivity extends FragmentActivity implements MainView switch (requestCode) { case MainPresenter.REQUEST_DIRECTORY: - mPresenter.onDirectorySelected(result); + if (DirectoryInitialization.preferOldFolderPicker(this)) + { + mPresenter.onDirectorySelected(FileBrowserHelper.getSelectedPath(result)); + } + else + { + mPresenter.onDirectorySelected(result); + } break; case MainPresenter.REQUEST_GAME_FILE: diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/DirectoryInitialization.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/DirectoryInitialization.java index 712d4aa707..7af6350d64 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/DirectoryInitialization.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/DirectoryInitialization.java @@ -9,6 +9,7 @@ package org.dolphinemu.dolphinemu.utils; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; +import android.os.Build; import android.os.Environment; import android.preference.PreferenceManager; @@ -347,6 +348,30 @@ public final class DirectoryInitialization } } + public static boolean isExternalStorageLegacy() + { + return Build.VERSION.SDK_INT < Build.VERSION_CODES.Q || Environment.isExternalStorageLegacy(); + } + + public static boolean preferOldFolderPicker(Context context) + { + // As of January 2021, ACTION_OPEN_DOCUMENT_TREE seems to be broken on the Nvidia Shield TV + // (the activity can't be navigated correctly with a gamepad). We can use the old folder picker + // for the time being - Android 11 hasn't been released for this device. We have an explicit + // check for Android 11 below in hopes that Nvidia will fix this before releasing Android 11. + // + // No Android TV device other than the Nvidia Shield TV is known to have an implementation + // of ACTION_OPEN_DOCUMENT or ACTION_OPEN_DOCUMENT_TREE that even launches, but "fortunately" + // for us, the Nvidia Shield TV is the only Android TV device in existence so far that can + // run Dolphin at all (due to the 64-bit requirement), so we can ignore this problem. + // + // All phones which are running a compatible version of Android support ACTION_OPEN_DOCUMENT and + // ACTION_OPEN_DOCUMENT_TREE, as this is required by the Android CTS (unlike with Android TV). + + return Build.VERSION.SDK_INT < Build.VERSION_CODES.R && isExternalStorageLegacy() && + TvUtil.isLeanback(context); + } + private static native void CreateUserDirectories(); private static native void SetSysDirectory(String path);