summaryrefslogtreecommitdiff
path: root/src/android
diff options
context:
space:
mode:
authorGravatar Charles Lombardo2023-03-11 00:33:51 -0500
committerGravatar bunnei2023-06-03 00:05:39 -0700
commit5c8372a56603f185c6b193d05dea3cfb0130d59c (patch)
treeab6893959dd2288a064fe5208ba871e5b23c86ce /src/android
parentandroid: Remove ExampleInstrumentedTest (diff)
downloadyuzu-5c8372a56603f185c6b193d05dea3cfb0130d59c.tar.gz
yuzu-5c8372a56603f185c6b193d05dea3cfb0130d59c.tar.xz
yuzu-5c8372a56603f185c6b193d05dea3cfb0130d59c.zip
android: Convert MainActivity to Kotlin
Diffstat (limited to 'src/android')
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/MainActivity.java249
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/MainActivity.kt228
-rw-r--r--src/android/app/src/main/res/values/strings.xml2
3 files changed, 229 insertions, 250 deletions
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/MainActivity.java b/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/MainActivity.java
deleted file mode 100644
index d5009bc60..000000000
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/MainActivity.java
+++ /dev/null
@@ -1,249 +0,0 @@
1package org.yuzu.yuzu_emu.ui.main;
2
3import android.content.Intent;
4import android.net.Uri;
5import android.os.Bundle;
6import android.view.Menu;
7import android.view.MenuInflater;
8import android.view.MenuItem;
9import android.widget.Toast;
10
11import androidx.annotation.NonNull;
12import androidx.appcompat.app.AlertDialog;
13import androidx.appcompat.app.AppCompatActivity;
14import androidx.appcompat.widget.Toolbar;
15
16import org.yuzu.yuzu_emu.NativeLibrary;
17import org.yuzu.yuzu_emu.R;
18import org.yuzu.yuzu_emu.activities.EmulationActivity;
19import org.yuzu.yuzu_emu.features.settings.ui.SettingsActivity;
20import org.yuzu.yuzu_emu.model.GameProvider;
21import org.yuzu.yuzu_emu.ui.platform.PlatformGamesFragment;
22import org.yuzu.yuzu_emu.utils.AddDirectoryHelper;
23import org.yuzu.yuzu_emu.utils.DirectoryInitialization;
24import org.yuzu.yuzu_emu.utils.FileBrowserHelper;
25import org.yuzu.yuzu_emu.utils.FileUtil;
26import org.yuzu.yuzu_emu.utils.GpuDriverHelper;
27import org.yuzu.yuzu_emu.utils.PicassoUtils;
28import org.yuzu.yuzu_emu.utils.StartupHandler;
29import org.yuzu.yuzu_emu.utils.ThemeUtil;
30
31/**
32 * The main Activity of the Lollipop style UI. Manages several PlatformGamesFragments, which
33 * individually display a grid of available games for each Fragment, in a tabbed layout.
34 */
35public final class MainActivity extends AppCompatActivity implements MainView {
36 private Toolbar mToolbar;
37 private int mFrameLayoutId;
38 private PlatformGamesFragment mPlatformGamesFragment;
39
40 private MainPresenter mPresenter = new MainPresenter(this);
41
42 @Override
43 protected void onCreate(Bundle savedInstanceState) {
44 ThemeUtil.applyTheme();
45
46 super.onCreate(savedInstanceState);
47 setContentView(R.layout.activity_main);
48
49 findViews();
50
51 setSupportActionBar(mToolbar);
52
53 mFrameLayoutId = R.id.games_platform_frame;
54 mPresenter.onCreate();
55
56 if (savedInstanceState == null) {
57 StartupHandler.handleInit(this);
58 mPlatformGamesFragment = new PlatformGamesFragment();
59 getSupportFragmentManager().beginTransaction().add(mFrameLayoutId, mPlatformGamesFragment).commit();
60 } else {
61 mPlatformGamesFragment = (PlatformGamesFragment) getSupportFragmentManager().getFragment(savedInstanceState, "mPlatformGamesFragment");
62 }
63 PicassoUtils.init();
64
65 // Dismiss previous notifications (should not happen unless a crash occurred)
66 EmulationActivity.tryDismissRunningNotification(this);
67 }
68
69 @Override
70 protected void onSaveInstanceState(@NonNull Bundle outState) {
71 super.onSaveInstanceState(outState);
72 if (getSupportFragmentManager() == null) {
73 return;
74 }
75 if (outState == null) {
76 return;
77 }
78 getSupportFragmentManager().putFragment(outState, "mPlatformGamesFragment", mPlatformGamesFragment);
79 }
80
81 @Override
82 protected void onResume() {
83 super.onResume();
84 mPresenter.addDirIfNeeded(new AddDirectoryHelper(this));
85 }
86
87 // TODO: Replace with a ButterKnife injection.
88 private void findViews() {
89 mToolbar = findViewById(R.id.toolbar_main);
90 }
91
92 @Override
93 public boolean onCreateOptionsMenu(Menu menu) {
94 MenuInflater inflater = getMenuInflater();
95 inflater.inflate(R.menu.menu_game_grid, menu);
96
97 return true;
98 }
99
100 /**
101 * MainView
102 */
103
104 @Override
105 public void setVersionString(String version) {
106 mToolbar.setSubtitle(version);
107 }
108
109 @Override
110 public void refresh() {
111 getContentResolver().insert(GameProvider.URI_REFRESH, null);
112 refreshFragment();
113 }
114
115 @Override
116 public void launchSettingsActivity(String menuTag) {
117 SettingsActivity.launch(this, menuTag, "");
118 }
119
120 @Override
121 public void launchFileListActivity(int request) {
122 switch (request) {
123 case MainPresenter.REQUEST_ADD_DIRECTORY:
124 FileBrowserHelper.openDirectoryPicker(this,
125 MainPresenter.REQUEST_ADD_DIRECTORY,
126 R.string.select_game_folder);
127 break;
128 case MainPresenter.REQUEST_INSTALL_KEYS:
129 FileBrowserHelper.openFilePicker(this,
130 MainPresenter.REQUEST_INSTALL_KEYS,
131 R.string.install_keys);
132 break;
133 case MainPresenter.REQUEST_SELECT_GPU_DRIVER:
134 AlertDialog.Builder builder = new AlertDialog.Builder(this);
135
136 // Get the driver name for the dialog message.
137 String driverName = GpuDriverHelper.getCustomDriverName();
138 if (driverName == null) {
139 driverName = getString(R.string.system_gpu_driver);
140 }
141
142 // Set the dialog message and title.
143 builder.setTitle(getString(R.string.select_gpu_driver_title));
144 builder.setMessage(driverName);
145
146 // Cancel button is a no-op.
147 builder.setNegativeButton(android.R.string.cancel, null);
148
149 // Select the default system driver.
150 builder.setPositiveButton(R.string.select_gpu_driver_default, (dialogInterface, i) ->
151 {
152 GpuDriverHelper.installDefaultDriver(this);
153 Toast.makeText(this, R.string.select_gpu_driver_use_default, Toast.LENGTH_SHORT).show();
154 });
155
156 // Use the file picker to install a custom driver.
157 builder.setNeutralButton(R.string.select_gpu_driver_install, (dialogInterface, i) -> {
158 FileBrowserHelper.openFilePicker(this,
159 MainPresenter.REQUEST_SELECT_GPU_DRIVER,
160 R.string.select_gpu_driver);
161 });
162
163 // Show the dialog.
164 AlertDialog alertDialog = builder.create();
165 alertDialog.show();
166
167 break;
168 }
169 }
170
171 /**
172 * @param requestCode An int describing whether the Activity that is returning did so successfully.
173 * @param resultCode An int describing what Activity is giving us this callback.
174 * @param result The information the returning Activity is providing us.
175 */
176 @Override
177 protected void onActivityResult(int requestCode, int resultCode, Intent result) {
178 super.onActivityResult(requestCode, resultCode, result);
179 switch (requestCode) {
180 case MainPresenter.REQUEST_ADD_DIRECTORY:
181 if (resultCode == MainActivity.RESULT_OK) {
182 int takeFlags = (Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
183 getContentResolver().takePersistableUriPermission(Uri.parse(result.getDataString()), takeFlags);
184 // When a new directory is picked, we currently will reset the existing games
185 // database. This effectively means that only one game directory is supported.
186 // TODO(bunnei): Consider fixing this in the future, or removing code for this.
187 getContentResolver().insert(GameProvider.URI_RESET, null);
188 // Add the new directory
189 mPresenter.onDirectorySelected(FileBrowserHelper.getSelectedDirectory(result));
190 }
191 break;
192
193 case MainPresenter.REQUEST_INSTALL_KEYS:
194 if (resultCode == MainActivity.RESULT_OK) {
195 int takeFlags = (Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
196 getContentResolver().takePersistableUriPermission(Uri.parse(result.getDataString()), takeFlags);
197 String dstPath = DirectoryInitialization.getUserDirectory() + "/keys/";
198 if (FileUtil.copyUriToInternalStorage(this, result.getData(), dstPath, "prod.keys")) {
199 if (NativeLibrary.ReloadKeys()) {
200 Toast.makeText(this, R.string.install_keys_success, Toast.LENGTH_SHORT).show();
201 refreshFragment();
202 } else {
203 Toast.makeText(this, R.string.install_keys_failure, Toast.LENGTH_LONG).show();
204 launchFileListActivity(MainPresenter.REQUEST_INSTALL_KEYS);
205 }
206 }
207 }
208 break;
209
210 case MainPresenter.REQUEST_SELECT_GPU_DRIVER:
211 if (resultCode == MainActivity.RESULT_OK) {
212 int takeFlags = (Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
213 getContentResolver().takePersistableUriPermission(Uri.parse(result.getDataString()), takeFlags);
214 GpuDriverHelper.installCustomDriver(this, result.getData());
215 String driverName = GpuDriverHelper.getCustomDriverName();
216 if (driverName != null) {
217 Toast.makeText(this, getString(R.string.select_gpu_driver_install_success) + " " + driverName, Toast.LENGTH_SHORT).show();
218 } else {
219 Toast.makeText(this, R.string.select_gpu_driver_error, Toast.LENGTH_LONG).show();
220 }
221 }
222 break;
223 }
224 }
225
226 /**
227 * Called by the framework whenever any actionbar/toolbar icon is clicked.
228 *
229 * @param item The icon that was clicked on.
230 * @return True if the event was handled, false to bubble it up to the OS.
231 */
232 @Override
233 public boolean onOptionsItemSelected(MenuItem item) {
234 return mPresenter.handleOptionSelection(item.getItemId());
235 }
236
237 private void refreshFragment() {
238 if (mPlatformGamesFragment != null) {
239 NativeLibrary.ResetRomMetadata();
240 mPlatformGamesFragment.refresh();
241 }
242 }
243
244 @Override
245 protected void onDestroy() {
246 EmulationActivity.tryDismissRunningNotification(this);
247 super.onDestroy();
248 }
249}
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/MainActivity.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/MainActivity.kt
new file mode 100644
index 000000000..6ea5fed27
--- /dev/null
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/MainActivity.kt
@@ -0,0 +1,228 @@
1package org.yuzu.yuzu_emu.ui.main
2
3import android.content.DialogInterface
4import android.content.Intent
5import android.net.Uri
6import android.os.Bundle
7import android.view.Menu
8import android.view.MenuItem
9import android.widget.Toast
10import androidx.appcompat.app.AppCompatActivity
11import androidx.appcompat.widget.Toolbar
12import com.google.android.material.dialog.MaterialAlertDialogBuilder
13import org.yuzu.yuzu_emu.NativeLibrary
14import org.yuzu.yuzu_emu.R
15import org.yuzu.yuzu_emu.activities.EmulationActivity
16import org.yuzu.yuzu_emu.features.settings.ui.SettingsActivity
17import org.yuzu.yuzu_emu.model.GameProvider
18import org.yuzu.yuzu_emu.ui.platform.PlatformGamesFragment
19import org.yuzu.yuzu_emu.utils.*
20
21class MainActivity : AppCompatActivity(), MainView {
22 private lateinit var toolbar: Toolbar
23 private var platformGamesFragment: PlatformGamesFragment? = null
24 private val presenter = MainPresenter(this)
25
26 override fun onCreate(savedInstanceState: Bundle?) {
27 super.onCreate(savedInstanceState)
28 setContentView(R.layout.activity_main)
29 findViews()
30 setSupportActionBar(toolbar)
31 presenter.onCreate()
32 if (savedInstanceState == null) {
33 StartupHandler.handleInit(this)
34 platformGamesFragment = PlatformGamesFragment()
35 supportFragmentManager.beginTransaction()
36 .add(R.id.games_platform_frame, platformGamesFragment!!)
37 .commit()
38 } else {
39 platformGamesFragment = supportFragmentManager.getFragment(
40 savedInstanceState,
41 PlatformGamesFragment.TAG
42 ) as PlatformGamesFragment?
43 }
44 PicassoUtils.init()
45
46 // Dismiss previous notifications (should not happen unless a crash occurred)
47 EmulationActivity.tryDismissRunningNotification(this)
48 }
49
50 override fun onSaveInstanceState(outState: Bundle) {
51 super.onSaveInstanceState(outState)
52 supportFragmentManager.putFragment(
53 outState,
54 PlatformGamesFragment.TAG,
55 platformGamesFragment!!
56 )
57 }
58
59 override fun onResume() {
60 super.onResume()
61 presenter.addDirIfNeeded(AddDirectoryHelper(this))
62 }
63
64 // TODO: Replace with view binding
65 private fun findViews() {
66 toolbar = findViewById(R.id.toolbar_main)
67 }
68
69 override fun onCreateOptionsMenu(menu: Menu): Boolean {
70 menuInflater.inflate(R.menu.menu_game_grid, menu)
71 return true
72 }
73
74 /**
75 * MainView
76 */
77 override fun setVersionString(version: String) {
78 toolbar.subtitle = version
79 }
80
81 override fun refresh() {
82 contentResolver.insert(GameProvider.URI_REFRESH, null)
83 refreshFragment()
84 }
85
86 override fun launchSettingsActivity(menuTag: String) {
87 SettingsActivity.launch(this, menuTag, "")
88 }
89
90 override fun launchFileListActivity(request: Int) {
91 when (request) {
92 MainPresenter.REQUEST_ADD_DIRECTORY -> FileBrowserHelper.openDirectoryPicker(
93 this,
94 MainPresenter.REQUEST_ADD_DIRECTORY,
95 R.string.select_game_folder
96 )
97 MainPresenter.REQUEST_INSTALL_KEYS -> FileBrowserHelper.openFilePicker(
98 this,
99 MainPresenter.REQUEST_INSTALL_KEYS,
100 R.string.install_keys
101 )
102 MainPresenter.REQUEST_SELECT_GPU_DRIVER -> {
103 // Get the driver name for the dialog message.
104 var driverName = GpuDriverHelper.customDriverName
105 if (driverName == null) {
106 driverName = getString(R.string.system_gpu_driver)
107 }
108
109 MaterialAlertDialogBuilder(this)
110 .setTitle(getString(R.string.select_gpu_driver_title))
111 .setMessage(driverName)
112 .setNegativeButton(android.R.string.cancel, null)
113 .setPositiveButton(R.string.select_gpu_driver_default) { _: DialogInterface?, _: Int ->
114 GpuDriverHelper.installDefaultDriver(this)
115 Toast.makeText(
116 this,
117 R.string.select_gpu_driver_use_default,
118 Toast.LENGTH_SHORT
119 ).show()
120 }
121 .setNeutralButton(R.string.select_gpu_driver_install) { _: DialogInterface?, _: Int ->
122 FileBrowserHelper.openFilePicker(
123 this,
124 MainPresenter.REQUEST_SELECT_GPU_DRIVER,
125 R.string.select_gpu_driver
126 )
127 }
128 .show()
129 }
130 }
131 }
132
133 /**
134 * @param requestCode An int describing whether the Activity that is returning did so successfully.
135 * @param resultCode An int describing what Activity is giving us this callback.
136 * @param result The information the returning Activity is providing us.
137 */
138 override fun onActivityResult(requestCode: Int, resultCode: Int, result: Intent?) {
139 super.onActivityResult(requestCode, resultCode, result)
140 when (requestCode) {
141 MainPresenter.REQUEST_ADD_DIRECTORY -> if (resultCode == RESULT_OK) {
142 val takeFlags =
143 Intent.FLAG_GRANT_WRITE_URI_PERMISSION or Intent.FLAG_GRANT_READ_URI_PERMISSION
144 contentResolver.takePersistableUriPermission(
145 Uri.parse(result!!.dataString),
146 takeFlags
147 )
148 // When a new directory is picked, we currently will reset the existing games
149 // database. This effectively means that only one game directory is supported.
150 // TODO(bunnei): Consider fixing this in the future, or removing code for this.
151 contentResolver.insert(GameProvider.URI_RESET, null)
152 // Add the new directory
153 presenter.onDirectorySelected(FileBrowserHelper.getSelectedDirectory(result))
154 }
155 MainPresenter.REQUEST_INSTALL_KEYS -> if (resultCode == RESULT_OK) {
156 val takeFlags =
157 Intent.FLAG_GRANT_WRITE_URI_PERMISSION or Intent.FLAG_GRANT_READ_URI_PERMISSION
158 contentResolver.takePersistableUriPermission(
159 Uri.parse(result!!.dataString),
160 takeFlags
161 )
162 val dstPath = DirectoryInitialization.userDirectory + "/keys/"
163 if (FileUtil.copyUriToInternalStorage(this, result.data, dstPath, "prod.keys")) {
164 if (NativeLibrary.ReloadKeys()) {
165 Toast.makeText(
166 this,
167 R.string.install_keys_success,
168 Toast.LENGTH_SHORT
169 ).show()
170 refreshFragment()
171 } else {
172 Toast.makeText(
173 this,
174 R.string.install_keys_failure,
175 Toast.LENGTH_LONG
176 ).show()
177 launchFileListActivity(MainPresenter.REQUEST_INSTALL_KEYS)
178 }
179 }
180 }
181 MainPresenter.REQUEST_SELECT_GPU_DRIVER -> if (resultCode == RESULT_OK) {
182 val takeFlags =
183 Intent.FLAG_GRANT_WRITE_URI_PERMISSION or Intent.FLAG_GRANT_READ_URI_PERMISSION
184 contentResolver.takePersistableUriPermission(
185 Uri.parse(result!!.dataString),
186 takeFlags
187 )
188 GpuDriverHelper.installCustomDriver(this, result.data)
189 val driverName = GpuDriverHelper.customDriverName
190 if (driverName != null) {
191 Toast.makeText(
192 this,
193 getString(R.string.select_gpu_driver_install_success, driverName),
194 Toast.LENGTH_SHORT
195 ).show()
196 } else {
197 Toast.makeText(
198 this,
199 R.string.select_gpu_driver_error,
200 Toast.LENGTH_LONG
201 ).show()
202 }
203 }
204 }
205 }
206
207 /**
208 * Called by the framework whenever any actionbar/toolbar icon is clicked.
209 *
210 * @param item The icon that was clicked on.
211 * @return True if the event was handled, false to bubble it up to the OS.
212 */
213 override fun onOptionsItemSelected(item: MenuItem): Boolean {
214 return presenter.handleOptionSelection(item.itemId)
215 }
216
217 private fun refreshFragment() {
218 if (platformGamesFragment != null) {
219 NativeLibrary.ResetRomMetadata()
220 platformGamesFragment!!.refresh()
221 }
222 }
223
224 override fun onDestroy() {
225 EmulationActivity.tryDismissRunningNotification(this)
226 super.onDestroy()
227 }
228}
diff --git a/src/android/app/src/main/res/values/strings.xml b/src/android/app/src/main/res/values/strings.xml
index 7ef6b803e..fbf8fe9c1 100644
--- a/src/android/app/src/main/res/values/strings.xml
+++ b/src/android/app/src/main/res/values/strings.xml
@@ -64,7 +64,7 @@
64 <string name="select_gpu_driver_title">Would you like to replace your current GPU driver?</string> 64 <string name="select_gpu_driver_title">Would you like to replace your current GPU driver?</string>
65 <string name="select_gpu_driver_install">Install</string> 65 <string name="select_gpu_driver_install">Install</string>
66 <string name="select_gpu_driver_default">Default</string> 66 <string name="select_gpu_driver_default">Default</string>
67 <string name="select_gpu_driver_install_success">Installed</string> 67 <string name="select_gpu_driver_install_success">Installed %s</string>
68 <string name="select_gpu_driver_use_default">Using default GPU driver</string> 68 <string name="select_gpu_driver_use_default">Using default GPU driver</string>
69 <string name="select_gpu_driver_error">Invalid driver selected, using system default!</string> 69 <string name="select_gpu_driver_error">Invalid driver selected, using system default!</string>
70 <string name="system_gpu_driver">System GPU driver</string> 70 <string name="system_gpu_driver">System GPU driver</string>