diff --git a/src/android/app/build.gradle b/src/android/app/build.gradle index 53897fd59..c425870d7 100644 --- a/src/android/app/build.gradle +++ b/src/android/app/build.gradle @@ -109,9 +109,6 @@ dependencies { implementation 'androidx.recyclerview:recyclerview:1.1.0' implementation 'com.google.android.material:material:1.1.0' - // Android TV UI libraries. - implementation 'androidx.leanback:leanback:1.0.0' - // For loading huge screenshots from the disk. implementation 'com.squareup.picasso:picasso:2.71828' @@ -120,4 +117,6 @@ dependencies { implementation 'com.nononsenseapps:filepicker:4.2.1' implementation 'org.ini4j:ini4j:0.5.4' implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + implementation 'androidx.localbroadcastmanager:localbroadcastmanager:1.0.0' + implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.0.0' } diff --git a/src/android/app/src/main/java/org/citra/citra_emu/activities/EmulationActivity.java b/src/android/app/src/main/java/org/citra/citra_emu/activities/EmulationActivity.java index 5df9b6d46..d8e36c13e 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/activities/EmulationActivity.java +++ b/src/android/app/src/main/java/org/citra/citra_emu/activities/EmulationActivity.java @@ -13,9 +13,7 @@ import android.os.Handler; import android.preference.PreferenceManager; import androidx.annotation.IntDef; -import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentActivity; -import androidx.fragment.app.FragmentManager; import androidx.core.app.NotificationCompat; import androidx.core.app.NotificationManagerCompat; import androidx.appcompat.app.AppCompatActivity; @@ -34,7 +32,6 @@ import android.widget.TextView; import org.citra.citra_emu.NativeLibrary; import org.citra.citra_emu.R; import org.citra.citra_emu.fragments.EmulationFragment; -import org.citra.citra_emu.fragments.MenuFragment; import org.citra.citra_emu.features.settings.model.view.InputBindingSetting; import org.citra.citra_emu.features.settings.ui.SettingsActivity; import org.citra.citra_emu.utils.ControllerMappingHelper; @@ -64,8 +61,6 @@ public final class EmulationActivity extends AppCompatActivity { public static final int MENU_ACTION_OPEN_SETTINGS = 12; private static final int EMULATION_RUNNING_NOTIFICATION = 0x1000; - private static final String BACKSTACK_NAME_MENU = "menu"; - private static final String BACKSTACK_NAME_SUBMENU = "submenu"; private static SparseIntArray buttonsActionsMap = new SparseIntArray(); static { @@ -77,7 +72,6 @@ public final class EmulationActivity extends AppCompatActivity { .append(R.id.menu_emulation_adjust_scale, EmulationActivity.MENU_ACTION_ADJUST_SCALE); buttonsActionsMap.append(R.id.menu_emulation_show_fps, EmulationActivity.MENU_ACTION_SHOW_FPS); - buttonsActionsMap.append(R.id.menu_exit, EmulationActivity.MENU_ACTION_EXIT); buttonsActionsMap.append(R.id.menu_screen_layout_landscape, EmulationActivity.MENU_ACTION_SCREEN_LAYOUT_LANDSCAPE); buttonsActionsMap.append(R.id.menu_screen_layout_portrait, @@ -98,8 +92,6 @@ public final class EmulationActivity extends AppCompatActivity { private EmulationFragment mEmulationFragment; private SharedPreferences mPreferences; private ControllerMappingHelper mControllerMappingHelper; - private boolean mDeviceHasTouchScreen; - private boolean mMenuVisible; private boolean activityRecreated; private String mSelectedTitle; private String mPath; @@ -154,30 +146,22 @@ public final class EmulationActivity extends AppCompatActivity { restoreState(savedInstanceState); } - mDeviceHasTouchScreen = getPackageManager().hasSystemFeature("android.hardware.touchscreen"); mControllerMappingHelper = new ControllerMappingHelper(); - int themeId; - if (mDeviceHasTouchScreen) { - themeId = R.style.CitraEmulation; + // Get a handle to the Window containing the UI. + mDecorView = getWindow().getDecorView(); + mDecorView.setOnSystemUiVisibilityChangeListener(visibility -> + { + if ((visibility & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0) { + // Go back to immersive fullscreen mode in 3s + Handler handler = new Handler(getMainLooper()); + handler.postDelayed(this::enableFullscreenImmersive, 3000 /* 3s */); + } + }); + // Set these options now so that the SurfaceView the game renders into is the right size. + enableFullscreenImmersive(); - // Get a handle to the Window containing the UI. - mDecorView = getWindow().getDecorView(); - mDecorView.setOnSystemUiVisibilityChangeListener(visibility -> - { - if ((visibility & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0) { - // Go back to immersive fullscreen mode in 3s - Handler handler = new Handler(getMainLooper()); - handler.postDelayed(this::enableFullscreenImmersive, 3000 /* 3s */); - } - }); - // Set these options now so that the SurfaceView the game renders into is the right size. - enableFullscreenImmersive(); - } else { - themeId = R.style.CitraEmulationTv; - } - - setTheme(themeId); + setTheme(R.style.CitraEmulation); setContentView(R.layout.activity_emulation); @@ -191,9 +175,7 @@ public final class EmulationActivity extends AppCompatActivity { .commit(); } - if (mDeviceHasTouchScreen) { - setTitle(mSelectedTitle); - } + setTitle(mSelectedTitle); mPreferences = PreferenceManager.getDefaultSharedPreferences(this); @@ -221,29 +203,21 @@ public final class EmulationActivity extends AppCompatActivity { @Override public void onBackPressed() { - if (!mDeviceHasTouchScreen) { - boolean popResult = getSupportFragmentManager().popBackStackImmediate( - BACKSTACK_NAME_SUBMENU, FragmentManager.POP_BACK_STACK_INCLUSIVE); - if (!popResult) { - toggleMenu(); - } - } else { - NativeLibrary.PauseEmulation(); - new AlertDialog.Builder(this) - .setTitle(R.string.emulation_close_game) - .setMessage(R.string.emulation_close_game_message) - .setPositiveButton(android.R.string.yes, (dialogInterface, i) -> - { - mEmulationFragment.stopEmulation(); - finish(); - }) - .setNegativeButton(android.R.string.cancel, (dialogInterface, i) -> - { - }).setOnDismissListener(dialogInterface -> - NativeLibrary.UnPauseEmulation()) - .create() - .show(); - } + NativeLibrary.PauseEmulation(); + new AlertDialog.Builder(this) + .setTitle(R.string.emulation_close_game) + .setMessage(R.string.emulation_close_game_message) + .setPositiveButton(android.R.string.yes, (dialogInterface, i) -> + { + mEmulationFragment.stopEmulation(); + finish(); + }) + .setNegativeButton(android.R.string.cancel, (dialogInterface, i) -> + { + }).setOnDismissListener(dialogInterface -> + NativeLibrary.UnPauseEmulation()) + .create() + .show(); } private void enableFullscreenImmersive() { @@ -257,27 +231,6 @@ public final class EmulationActivity extends AppCompatActivity { View.SYSTEM_UI_FLAG_IMMERSIVE); } - private void toggleMenu() { - boolean result = getSupportFragmentManager().popBackStackImmediate( - BACKSTACK_NAME_MENU, FragmentManager.POP_BACK_STACK_INCLUSIVE); - mMenuVisible = false; - - if (!result) { - // Removing the menu failed, so that means it wasn't visible. Add it. - Fragment fragment = MenuFragment.newInstance(mSelectedTitle); - getSupportFragmentManager().beginTransaction() - .setCustomAnimations( - R.animator.menu_slide_in_from_left, - R.animator.menu_slide_out_to_left, - R.animator.menu_slide_in_from_left, - R.animator.menu_slide_out_to_left) - .add(R.id.frame_menu, fragment) - .addToBackStack(BACKSTACK_NAME_MENU) - .commit(); - mMenuVisible = true; - } - } - @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. @@ -381,7 +334,6 @@ public final class EmulationActivity extends AppCompatActivity { } case MENU_ACTION_EXIT: - toggleMenu(); // Hide the menu (it will be showing since we just clicked it) mEmulationFragment.stopEmulation(); finish(); break; @@ -412,10 +364,6 @@ public final class EmulationActivity extends AppCompatActivity { // Gets button presses @Override public boolean dispatchKeyEvent(KeyEvent event) { - if (mMenuVisible) { - return super.dispatchKeyEvent(event); - } - int action; int button = mPreferences.getInt(InputBindingSetting.getInputButtonKey(event.getKeyCode()), event.getKeyCode()); @@ -533,10 +481,6 @@ public final class EmulationActivity extends AppCompatActivity { @Override public boolean dispatchGenericMotionEvent(MotionEvent event) { - if (mMenuVisible) { - return false; - } - if (((event.getSource() & InputDevice.SOURCE_CLASS_JOYSTICK) == 0)) { return super.dispatchGenericMotionEvent(event); } diff --git a/src/android/app/src/main/java/org/citra/citra_emu/adapters/GameAdapter.java b/src/android/app/src/main/java/org/citra/citra_emu/adapters/GameAdapter.java index dd062b8f2..35930b7cf 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/adapters/GameAdapter.java +++ b/src/android/app/src/main/java/org/citra/citra_emu/adapters/GameAdapter.java @@ -10,6 +10,7 @@ import androidx.annotation.NonNull; import androidx.annotation.RequiresApi; import androidx.fragment.app.FragmentActivity; import androidx.recyclerview.widget.RecyclerView; + import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -75,7 +76,7 @@ public final class GameAdapter extends RecyclerView.Adapter impl */ @RequiresApi(api = Build.VERSION_CODES.O) @Override - public void onBindViewHolder(GameViewHolder holder, int position) { + public void onBindViewHolder(@NonNull GameViewHolder holder, int position) { if (mDatasetValid) { if (mCursor.moveToPosition(position)) { PicassoUtils.loadGameBanner(holder.imageScreenshot, diff --git a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/SettingsActivity.java b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/SettingsActivity.java index 80e75f2f3..e8476e52b 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/SettingsActivity.java +++ b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/SettingsActivity.java @@ -14,7 +14,6 @@ import androidx.appcompat.app.AppCompatActivity; import android.view.Menu; import android.view.MenuInflater; -import android.view.MenuItem; import android.widget.Toast; import org.citra.citra_emu.R; diff --git a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/SettingsFragment.java b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/SettingsFragment.java index e77f0dd0a..a893f264d 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/SettingsFragment.java +++ b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/SettingsFragment.java @@ -3,6 +3,7 @@ package org.citra.citra_emu.features.settings.ui; import android.content.Context; import android.os.Bundle; +import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; import androidx.recyclerview.widget.LinearLayoutManager; @@ -41,7 +42,7 @@ public final class SettingsFragment extends Fragment implements SettingsFragment } @Override - public void onAttach(Context context) { + public void onAttach(@NonNull Context context) { super.onAttach(context); mActivity = (SettingsActivityView) context; diff --git a/src/android/app/src/main/java/org/citra/citra_emu/fragments/EmulationFragment.java b/src/android/app/src/main/java/org/citra/citra_emu/fragments/EmulationFragment.java index a5a27d8b5..65b35d924 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/fragments/EmulationFragment.java +++ b/src/android/app/src/main/java/org/citra/citra_emu/fragments/EmulationFragment.java @@ -7,6 +7,7 @@ import android.os.Bundle; import android.os.Handler; import android.preference.PreferenceManager; +import androidx.annotation.NonNull; import androidx.fragment.app.Fragment; import androidx.localbroadcastmanager.content.LocalBroadcastManager; @@ -59,7 +60,7 @@ public final class EmulationFragment extends Fragment implements SurfaceHolder.C } @Override - public void onAttach(Context context) { + public void onAttach(@NonNull Context context) { super.onAttach(context); if (context instanceof EmulationActivity) { diff --git a/src/android/app/src/main/java/org/citra/citra_emu/ui/main/MainActivity.java b/src/android/app/src/main/java/org/citra/citra_emu/ui/main/MainActivity.java index cf5b63432..3ff78bb86 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/ui/main/MainActivity.java +++ b/src/android/app/src/main/java/org/citra/citra_emu/ui/main/MainActivity.java @@ -2,11 +2,12 @@ package org.citra.citra_emu.ui.main; import android.content.Intent; import android.content.pm.PackageManager; -import android.database.Cursor; import android.os.Bundle; +import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.widget.Toolbar; + import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; @@ -62,7 +63,7 @@ public final class MainActivity extends AppCompatActivity implements MainView { } @Override - protected void onSaveInstanceState(Bundle outState) { + protected void onSaveInstanceState(@NonNull Bundle outState) { super.onSaveInstanceState(outState); if (PermissionsHandler.hasWriteAccess(this)) { getSupportFragmentManager().putFragment(outState, "mPlatformGamesFragment", mPlatformGamesFragment); @@ -121,11 +122,6 @@ public final class MainActivity extends AppCompatActivity implements MainView { } } - @Override - public void showGames(Cursor games) { - // no-op. Handled by PlatformGamesFragment. - } - /** * @param requestCode An int describing whether the Activity that is returning did so successfully. * @param resultCode An int describing what Activity is giving us this callback. @@ -133,6 +129,7 @@ public final class MainActivity extends AppCompatActivity implements MainView { */ @Override protected void onActivityResult(int requestCode, int resultCode, Intent result) { + super.onActivityResult(requestCode, resultCode, result); switch (requestCode) { case MainPresenter.REQUEST_ADD_DIRECTORY: // If the user picked a file, as opposed to just backing out. @@ -149,7 +146,7 @@ public final class MainActivity extends AppCompatActivity implements MainView { } @Override - public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { switch (requestCode) { case PermissionsHandler.REQUEST_CODE_WRITE_PERMISSION: if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { diff --git a/src/android/app/src/main/java/org/citra/citra_emu/utils/PermissionsHandler.java b/src/android/app/src/main/java/org/citra/citra_emu/utils/PermissionsHandler.java index 8245d8e0a..f9caec646 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/utils/PermissionsHandler.java +++ b/src/android/app/src/main/java/org/citra/citra_emu/utils/PermissionsHandler.java @@ -20,10 +20,6 @@ public class PermissionsHandler { @TargetApi(Build.VERSION_CODES.M) public static boolean checkWritePermission(final FragmentActivity activity) { - if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { - return true; - } - if (isFirstBoot(activity)) { activity.requestPermissions(new String[]{WRITE_EXTERNAL_STORAGE}, REQUEST_CODE_WRITE_PERMISSION); @@ -34,11 +30,6 @@ public class PermissionsHandler { } public static boolean hasWriteAccess(Context context) { - if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - int hasWritePermission = ContextCompat.checkSelfPermission(context, WRITE_EXTERNAL_STORAGE); - return hasWritePermission == PackageManager.PERMISSION_GRANTED; - } - - return true; + return ContextCompat.checkSelfPermission(context, WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED; } } diff --git a/src/android/app/src/main/res/layout/activity_emulation.xml b/src/android/app/src/main/res/layout/activity_emulation.xml index 7ebaceee2..105ba9036 100644 --- a/src/android/app/src/main/res/layout/activity_emulation.xml +++ b/src/android/app/src/main/res/layout/activity_emulation.xml @@ -1,17 +1,17 @@ + android:id="@+id/frame_content" + android:layout_width="match_parent" + android:layout_height="match_parent"> + android:layout_height="match_parent" /> + android:transitionName="image_game_screenshot" /> \ No newline at end of file diff --git a/src/android/app/src/main/res/values/colors.xml b/src/android/app/src/main/res/values/colors.xml index a8454c25b..aab21712c 100644 --- a/src/android/app/src/main/res/values/colors.xml +++ b/src/android/app/src/main/res/values/colors.xml @@ -5,6 +5,6 @@ #fe8a03 #c77413 - #444444 + #FFCCCCCC