[Scummvm-git-logs] scummvm master -> 4ea7455e0976113e6d285abef0145692b917a1ae

antoniou79 a.antoniou79 at gmail.com
Tue Sep 29 19:11:09 UTC 2020


This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
4ea7455e09 ANDROID: Splash screen and additional locations to search for config and saves


Commit: 4ea7455e0976113e6d285abef0145692b917a1ae
    https://github.com/scummvm/scummvm/commit/4ea7455e0976113e6d285abef0145692b917a1ae
Author: antoniou (a.antoniou79 at gmail.com)
Date: 2020-09-29T22:10:56+03:00

Commit Message:
ANDROID: Splash screen and additional locations to search for config and saves

The splash screen is an addition that was "forced" by the need to allow for permission granted to access external physical storage

Changed paths:
  A backends/platform/android/org/scummvm/scummvm/SplashActivity.java
  A dists/android/res/drawable/splash.xml
  A dists/android/res/values/colors.xml
  A dists/android/res/values/themes.xml
    backends/platform/android/org/scummvm/scummvm/ExternalStorage.java
    backends/platform/android/org/scummvm/scummvm/ScummVM.java
    backends/platform/android/org/scummvm/scummvm/ScummVMActivity.java
    dists/android/AndroidManifest.xml
    dists/android/res/drawable/ic_scummvm_background.xml
    dists/android/res/values/strings.xml


diff --git a/backends/platform/android/org/scummvm/scummvm/ExternalStorage.java b/backends/platform/android/org/scummvm/scummvm/ExternalStorage.java
index 31b754280a..ea1b1844c5 100644
--- a/backends/platform/android/org/scummvm/scummvm/ExternalStorage.java
+++ b/backends/platform/android/org/scummvm/scummvm/ExternalStorage.java
@@ -1,5 +1,6 @@
 package org.scummvm.scummvm;
 
+import android.content.Context;
 import android.os.Environment;
 import java.io.File;
 import java.util.ArrayList;
@@ -25,7 +26,9 @@ import android.os.Build;
 public class ExternalStorage {
 	public static final String SD_CARD = "sdCard";
 	public static final String EXTERNAL_SD_CARD = "externalSdCard";
-	public static final String DATA_DIRECTORY = "ScummVM data directory";
+	public static final String DATA_DIRECTORY = "ScummVM data";
+	public static final String DATA_DIRECTORY_INT = "ScummVM data (Int)";
+	public static final String DATA_DIRECTORY_EXT = "ScummVM data (Ext))";
 
 
 	// Find candidate removable sd card paths
@@ -215,14 +218,20 @@ public class ExternalStorage {
 		//   /storage/sdcard1/Android/data/com.mybackuparchives.android/files
 		// so we want the great-great-grandparent folder.
 
+		// TODO Note, This method was deprecated in API level 29.
+		//      To improve user privacy, direct access to shared/external storage devices is deprecated.
+		//      When an app targets Build.VERSION_CODES.Q, the path returned from this method is no longer directly accessible to apps.
+		//      Apps can continue to access content stored on shared/external storage by migrating to
+		//      alternatives such as Context#getExternalFilesDir(String), MediaStore, or Intent#ACTION_OPEN_DOCUMENT.
+		//
 		// This may be non-removable.
 		Log.d(ScummVM.LOG_TAG, "Environment.getExternalStorageDirectory():");
 		addPath(ancestor(Environment.getExternalStorageDirectory()), candidatePaths);
 
-		// TODO maybe: use getExternalStorageState(File path), with and without an argument, when
-		// available. With an argument is available since API level 21.
-		// This may not be necessary, since we also check whether a directory exists,
-		// which would fail if the external storage state is neither MOUNTED nor MOUNTED_READ_ONLY.
+		// TODO maybe use getExternalStorageState(File path), with and without an argument,
+		//      when available. With an argument is available since API level 21.
+		//      This may not be necessary, since we also check whether a directory exists,
+		//      which would fail if the external storage state is neither MOUNTED nor MOUNTED_READ_ONLY.
 
 		// A "public" external storage directory. But in my experience it doesn't add anything helpful.
 		// Note that you can't pass null, or you'll get an NPE.
@@ -353,7 +362,7 @@ public class ExternalStorage {
 	/**
 	 * @return list of locations available. Odd elements are names, even are paths
 	 */
-	public static List<String> getAllStorageLocations() {
+	public static List<String> getAllStorageLocations(Context ctx) {
 		List<String> map = new ArrayList<>(20);
 
 		List<String> mMounts = new ArrayList<>(10);
@@ -440,15 +449,25 @@ public class ExternalStorage {
 
 		mMounts.clear();
 
-		map.add(DATA_DIRECTORY);
-		map.add(Environment.getDataDirectory().getAbsolutePath());
+		if (Environment.getDataDirectory() != null
+		    && !"".equals(Environment.getDataDirectory().getAbsolutePath())) {
+			File dataFilePath = new File(Environment.getDataDirectory().getAbsolutePath());
+			if (dataFilePath.exists() && dataFilePath.isDirectory()) {
+				map.add(DATA_DIRECTORY);
+				map.add(Environment.getDataDirectory().getAbsolutePath());
+			}
+		}
+		map.add(DATA_DIRECTORY_INT);
+		map.add(ctx.getFilesDir().getPath());
+		map.add(DATA_DIRECTORY_EXT);
+		map.add(ctx.getExternalFilesDir(null).getPath());
 
 		// Now go through the external storage
 		if (isAvailable()) {  // we can read the External Storage...
 			// Retrieve the primary External Storage:
 			File primaryExternalStorage = Environment.getExternalStorageDirectory();
 
-			//Retrieve the External Storages root directory:
+			// Retrieve the External Storages root directory:
 			String externalStorageRootDir;
 			if ((externalStorageRootDir = primaryExternalStorage.getParent()) == null) {  // no parent...
 				String key = primaryExternalStorage.getAbsolutePath();
diff --git a/backends/platform/android/org/scummvm/scummvm/ScummVM.java b/backends/platform/android/org/scummvm/scummvm/ScummVM.java
index e793bcfb0f..d8095c70d3 100644
--- a/backends/platform/android/org/scummvm/scummvm/ScummVM.java
+++ b/backends/platform/android/org/scummvm/scummvm/ScummVM.java
@@ -66,6 +66,7 @@ public abstract class ScummVM implements SurfaceHolder.Callback, Runnable {
 	abstract protected String[] getSysArchives();
 	abstract protected byte[] convertEncoding(String to, String from, byte[] string) throws UnsupportedEncodingException;
 	abstract protected String[] getAllStorageLocations();
+	abstract protected String[] getAllStorageLocationsNoPermissionRequest();
 
 	public ScummVM(AssetManager asset_manager, SurfaceHolder holder) {
 		_asset_manager = asset_manager;
diff --git a/backends/platform/android/org/scummvm/scummvm/ScummVMActivity.java b/backends/platform/android/org/scummvm/scummvm/ScummVMActivity.java
index f3413b0475..8b5537a8ba 100644
--- a/backends/platform/android/org/scummvm/scummvm/ScummVMActivity.java
+++ b/backends/platform/android/org/scummvm/scummvm/ScummVMActivity.java
@@ -17,6 +17,7 @@ import android.net.wifi.WifiManager;
 import android.os.Build;
 import android.os.Bundle;
 import android.os.Environment;
+import android.os.Handler;
 import android.text.ClipboardManager;
 import android.util.DisplayMetrics;
 import android.util.Log;
@@ -47,10 +48,13 @@ import java.io.Reader;
 import java.io.UnsupportedEncodingException;
 import java.util.HashMap;
 import java.util.LinkedHashMap;
+import java.util.List;
 import java.util.Map;
 import java.util.Objects;
 import java.util.Properties;
 
+import static org.scummvm.scummvm.ExternalStorage.getAllStorageLocations;
+
 //import android.os.Environment;
 //import java.util.List;
 
@@ -66,11 +70,20 @@ public class ScummVMActivity extends Activity implements OnKeyboardVisibilityLis
 	private File _usingScummVMSavesDir;
 //	private File _usingLogFile;
 
-
 	/**
-	* Id to identify an external storage read request.
-	*/
-	private static final int MY_PERMISSIONS_REQUEST_READ_EXT_STORAGE = 100; // is an app-defined int constant. The callback method gets the result of the request.
+	 * Ids to identify an external storage read (and write) request.
+	 * They are app-defined int constants. The callback method gets the result of the request.
+	 * Ie. returned in the Activity's onRequestPermissionsResult()
+	 */
+
+	private static final int MY_PERMISSIONS_REQUEST_READ_EXT_STORAGE = 100;
+	private static final int MY_PERMISSIONS_REQUEST_WRITE_EXT_STORAGE = 101;
+	private static final int MY_PERMISSION_ALL = 110;
+
+	private static final String[] MY_PERMISSIONS_STR_LIST = {
+		Manifest.permission.READ_EXTERNAL_STORAGE,
+		Manifest.permission.WRITE_EXTERNAL_STORAGE,
+	};
 
 	static {
 		try {
@@ -85,10 +98,10 @@ public class ScummVMActivity extends Activity implements OnKeyboardVisibilityLis
 		@Override
 		public void onClick(View v) {
 			runOnUiThread(new Runnable() {
-					public void run() {
-						toggleKeyboard();
-					}
-				});
+				public void run() {
+					toggleKeyboard();
+				}
+			});
 		}
 	};
 
@@ -157,28 +170,28 @@ public class ScummVMActivity extends Activity implements OnKeyboardVisibilityLis
 		@Override
 		protected void setWindowCaption(final String caption) {
 			runOnUiThread(new Runnable() {
-					public void run() {
-						setTitle(caption);
-					}
-				});
+				public void run() {
+					setTitle(caption);
+				}
+			});
 		}
 
 		@Override
 		protected void showVirtualKeyboard(final boolean enable) {
 			runOnUiThread(new Runnable() {
-					public void run() {
-						showKeyboard(enable);
-					}
-				});
+				public void run() {
+					showKeyboard(enable);
+				}
+			});
 		}
 
 		@Override
 		protected void showKeyboardControl(final boolean enable) {
 			runOnUiThread(new Runnable() {
-					public void run() {
-						showKeyboardView(enable);
-					}
-				});
+				public void run() {
+					showKeyboardView(enable);
+				}
+			});
 		}
 
 		@Override
@@ -196,15 +209,26 @@ public class ScummVMActivity extends Activity implements OnKeyboardVisibilityLis
 		@Override
 		protected String[] getAllStorageLocations() {
 			if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
-			    && checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED
+				&& checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED
 			) {
 				requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, MY_PERMISSIONS_REQUEST_READ_EXT_STORAGE);
 			} else {
-				return ExternalStorage.getAllStorageLocations().toArray(new String[0]);
+				return ExternalStorage.getAllStorageLocations(getApplicationContext()).toArray(new String[0]);
 			}
 			return new String[0]; // an array of zero length
 		}
 
+		@Override
+		protected String[] getAllStorageLocationsNoPermissionRequest() {
+			if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M
+				|| checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED
+			) {
+				return ExternalStorage.getAllStorageLocations(getApplicationContext()).toArray(new String[0]);
+			}
+			// TODO we might be able to return something even if READ_EXTERNAL_STORAGE was not granted
+			//      but for now, just return nothing
+			return new String[0]; // an array of zero length
+		}
 	}
 
 	private MyScummVM _scummvm;
@@ -224,14 +248,6 @@ public class ScummVMActivity extends Activity implements OnKeyboardVisibilityLis
 		setContentView(R.layout.main);
 		takeKeyEvents(true);
 
-		if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
-			&& checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED
-		) {
-			requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, MY_PERMISSIONS_REQUEST_READ_EXT_STORAGE);
-		}
-
-		// REMOVED: Dialogue prompt with only option to Quit the app if !Environment.getExternalStorageDirectory().canRead()
-
 		SurfaceView main_surface = findViewById(R.id.main_surface);
 
 		main_surface.requestFocus();
@@ -239,7 +255,7 @@ public class ScummVMActivity extends Activity implements OnKeyboardVisibilityLis
 		_clipboard = (ClipboardManager)getSystemService(CLIPBOARD_SERVICE);
 
 		_currentScummVMVersion = new Version(BuildConfig.VERSION_NAME);
-		Log.d(ScummVM.LOG_TAG, "Current ScummVM version being installed is: " + _currentScummVMVersion.getDescription() + " (" + _currentScummVMVersion.get() + ")");
+		Log.d(ScummVM.LOG_TAG, "Current ScummVM version running is: " + _currentScummVMVersion.getDescription() + " (" + _currentScummVMVersion.get() + ")");
 
 		// REMOVED: Since getFilesDir() is guaranteed to exist, getFilesDir().mkdirs() might be related to crashes in Android version 9+ (Pie or above, API 28+)!
 
@@ -254,6 +270,8 @@ public class ScummVMActivity extends Activity implements OnKeyboardVisibilityLis
 		//                            so app's internal space (which would be deleted on uninstall) was set as WORLD_READABLE which is no longer supported in newer versions of Android API
 		//                            In newer APIs we can set that path as Context.MODE_PRIVATE which is the default - but this makes the files inaccessible to other apps
 
+		_scummvm = new MyScummVM(main_surface.getHolder());
+
 		//
 		// seekAndInitScummvmConfiguration() returns false if something went wrong
 		// when initializing configuration (or when seeking and trying to use an existing ini file) for ScummVM
@@ -264,8 +282,6 @@ public class ScummVMActivity extends Activity implements OnKeyboardVisibilityLis
 			// We should have a valid path to a configuration file here
 
 			// Start ScummVM
-			_scummvm = new MyScummVM(main_surface.getHolder());
-
 //			Log.d(ScummVM.LOG_TAG, "CONFIG: " +  _configScummvmFile.getPath());
 //			Log.d(ScummVM.LOG_TAG, "PATH: " +  _actualScummVMDataDir.getPath());
 //			Log.d(ScummVM.LOG_TAG, "LOG: " +  _usingLogFile.getPath());
@@ -366,7 +382,26 @@ public class ScummVMActivity extends Activity implements OnKeyboardVisibilityLis
 
 	@Override
 	public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
-		if (requestCode == MY_PERMISSIONS_REQUEST_READ_EXT_STORAGE) {
+		if (requestCode == MY_PERMISSION_ALL) {
+			int numOfReqPermsGranted = 0;
+			// If request is cancelled, the result arrays are empty.
+			if (grantResults.length > 0) {
+				for (int iterGrantResult: grantResults) {
+					if (iterGrantResult == PackageManager.PERMISSION_GRANTED) {
+						Log.i(ScummVM.LOG_TAG, permissions[0] + " permission was granted at Runtime");
+						++numOfReqPermsGranted;
+					} else {
+						Log.i(ScummVM.LOG_TAG, permissions[0] + " permission was denied at Runtime");
+					}
+				}
+			}
+
+			if (numOfReqPermsGranted != grantResults.length) {
+				// permission denied! We won't be able to make use of functionality depending on this permission.
+				Toast.makeText(this, "Until permission is granted, some storage locations may be inaccessible for r/w!", Toast.LENGTH_SHORT)
+					.show();
+			}
+		} else if (requestCode == MY_PERMISSIONS_REQUEST_READ_EXT_STORAGE) {
 			// If request is cancelled, the result arrays are empty.
 			if (grantResults.length > 0
 				&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
@@ -377,6 +412,17 @@ public class ScummVMActivity extends Activity implements OnKeyboardVisibilityLis
 				Toast.makeText(this, "Until permission is granted, some storage locations may be inaccessible!", Toast.LENGTH_SHORT)
 					.show();
 			}
+		} else if (requestCode == MY_PERMISSIONS_REQUEST_WRITE_EXT_STORAGE) {
+			// If request is cancelled, the result arrays are empty.
+			if (grantResults.length > 0
+				&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
+				// permission was granted
+				Log.i(ScummVM.LOG_TAG, "Write External Storage permission was granted at Runtime");
+			} else {
+				// permission denied! We won't be able to make use of functionality depending on this permission.
+				Toast.makeText(this, "Until permission is granted, it might be impossible to write to some locations!", Toast.LENGTH_SHORT)
+					.show();
+			}
 		}
 	}
 
@@ -400,10 +446,10 @@ public class ScummVMActivity extends Activity implements OnKeyboardVisibilityLis
 
 	@Override
 	public void onWindowFocusChanged(boolean hasFocus) {
-	    super.onWindowFocusChanged(hasFocus);
-	    if (hasFocus) {
-		hideSystemUI();
-	    }
+		super.onWindowFocusChanged(hasFocus);
+		if (hasFocus) {
+			hideSystemUI();
+		}
 	}
 
 
@@ -420,15 +466,15 @@ public class ScummVMActivity extends Activity implements OnKeyboardVisibilityLis
 		// Or for "sticky immersive," replace it with SYSTEM_UI_FLAG_IMMERSIVE_STICKY
 		View decorView = getWindow().getDecorView();
 		decorView.setSystemUiVisibility(
-		View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
-		// Set the content to appear under the system bars so that the
-		// content doesn't resize when the system bars hide and show.
-		| View.SYSTEM_UI_FLAG_LAYOUT_STABLE
-		| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
-		| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
-		// Hide the nav bar and status bar
-		| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
-		| View.SYSTEM_UI_FLAG_FULLSCREEN);
+			View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
+				// Set the content to appear under the system bars so that the
+				// content doesn't resize when the system bars hide and show.
+				| View.SYSTEM_UI_FLAG_LAYOUT_STABLE
+				| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
+				| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
+				// Hide the nav bar and status bar
+				| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
+				| View.SYSTEM_UI_FLAG_FULLSCREEN);
 	}
 
 //	// Shows the system bars by removing all the flags
@@ -466,8 +512,8 @@ public class ScummVMActivity extends Activity implements OnKeyboardVisibilityLis
 			getSystemService(INPUT_METHOD_SERVICE);
 
 		imm.toggleSoftInputFromWindow(main_surface.getWindowToken(),
-		                              InputMethodManager.SHOW_IMPLICIT,
-		                              InputMethodManager.HIDE_IMPLICIT_ONLY);
+			InputMethodManager.SHOW_IMPLICIT,
+			InputMethodManager.HIDE_IMPLICIT_ONLY);
 	}
 
 	// Show or hide the semi-transparent keyboard btn (which is used to explicitly bring up the android keyboard).
@@ -495,8 +541,8 @@ public class ScummVMActivity extends Activity implements OnKeyboardVisibilityLis
 			   intents, please add them here as well */
 			Intent intent =
 				new Intent(show?
-					   "tv.ouya.controller.action.SHOW_CURSOR" :
-					   "tv.ouya.controller.action.HIDE_CURSOR");
+					"tv.ouya.controller.action.SHOW_CURSOR" :
+					"tv.ouya.controller.action.HIDE_CURSOR");
 			sendBroadcast(intent);
 		}
 	}
@@ -515,17 +561,17 @@ public class ScummVMActivity extends Activity implements OnKeyboardVisibilityLis
 			@TargetApi(Build.VERSION_CODES.CUPCAKE)
 			@Override
 			public void onGlobalLayout() {
-				    int estimatedKeyboardHeight = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, EstimatedKeyboardDP, parentView.getResources().getDisplayMetrics());
-				    parentView.getWindowVisibleDisplayFrame(rect);
-				    int heightDiff = parentView.getRootView().getHeight() - (rect.bottom - rect.top);
-				    boolean isShown = heightDiff >= estimatedKeyboardHeight;
+				int estimatedKeyboardHeight = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, EstimatedKeyboardDP, parentView.getResources().getDisplayMetrics());
+				parentView.getWindowVisibleDisplayFrame(rect);
+				int heightDiff = parentView.getRootView().getHeight() - (rect.bottom - rect.top);
+				boolean isShown = heightDiff >= estimatedKeyboardHeight;
 
-				    if (isShown == alreadyOpen) {
+				if (isShown == alreadyOpen) {
 					Log.i("Keyboard state", "Ignoring global layout change...");
 					return;
-				    }
-				    alreadyOpen = isShown;
-				    onKeyboardVisibilityListener.onVisibilityChanged(isShown);
+				}
+				alreadyOpen = isShown;
+				onKeyboardVisibilityListener.onVisibilityChanged(isShown);
 			}
 		});
 	}
@@ -758,10 +804,47 @@ public class ScummVMActivity extends Activity implements OnKeyboardVisibilityLis
 		candidateOldLocationsOfScummVMConfigMap.put("(scummvm.ini) (SDL port - B)", new File(_actualScummVMDataDir, "../.config/scummvm/scummvm.ini"));
 		candidateOldLocationsOfScummVMConfigMap.put("(scummvm.ini) (SDL port - C)", new File(externalPossibleAlternateScummVMFilesDir, ".config/scummvm/scummvm.ini"));
 		candidateOldLocationsOfScummVMConfigMap.put("(scummvm.ini) (SDL port - D)", new File(externalPossibleAlternateScummVMFilesDir, "../.config/scummvm/scummvm.ini"));
+		candidateOldLocationsOfScummVMConfigMap.put("(scummvm.ini) (SDL port - E)", new File(Environment.getExternalStorageDirectory(), ".config/scummvm/scummvm.ini"));
 		candidateOldLocationsOfScummVMConfigMap.put("(scummvmrc) (version 1.8.1- or PlayStore 2.1.0) - Internal", new File(_actualScummVMDataDir, "scummvmrc"));
-		candidateOldLocationsOfScummVMConfigMap.put("(scummvmrc) (version 1.8.1- or PlayStore 2.1.0) - External", new File(externalPossibleAlternateScummVMFilesDir, "scummvmrc"));
+		candidateOldLocationsOfScummVMConfigMap.put("(scummvmrc) (version 1.8.1- or PlayStore 2.1.0) - Ext Emu", new File(externalPossibleAlternateScummVMFilesDir, "scummvmrc"));
+		candidateOldLocationsOfScummVMConfigMap.put("(scummvmrc) (version 1.8.1- or PlayStore 2.1.0) - Ext SD", new File(Environment.getExternalStorageDirectory(), "scummvmrc"));
 		candidateOldLocationsOfScummVMConfigMap.put("(.scummvmrc) (POSIX conformance) - Internal", new File(_actualScummVMDataDir, ".scummvmrc"));
-		candidateOldLocationsOfScummVMConfigMap.put("(.scummvmrc) (POSIX conformance) - External", new File(externalPossibleAlternateScummVMFilesDir, ".scummvmrc"));
+		candidateOldLocationsOfScummVMConfigMap.put("(.scummvmrc) (POSIX conformance) - Ext Emu", new File(externalPossibleAlternateScummVMFilesDir, ".scummvmrc"));
+		candidateOldLocationsOfScummVMConfigMap.put("(.scummvmrc) (POSIX conformance) - Ext SD)", new File(Environment.getExternalStorageDirectory(), ".scummvmrc"));
+
+		String[] listOfAuxExtStoragePaths = _scummvm.getAllStorageLocationsNoPermissionRequest();
+
+		int incKeyId = 0;
+		for (int incIndx = 0; incIndx + 1 < listOfAuxExtStoragePaths.length; incIndx += 2) {
+			// exclude identical matches for internal and emulated external app dir, since we take them into account below explicitly
+			if (listOfAuxExtStoragePaths[incIndx + 1].compareToIgnoreCase(_actualScummVMDataDir.getPath()) != 0
+				&& listOfAuxExtStoragePaths[incIndx + 1].compareToIgnoreCase(externalPossibleAlternateScummVMFilesDir.getPath()) != 0
+			) {
+				//
+				// Possible for Config file locations on top of paths returned by getAllStorageLocationsNoPermissionRequest
+				//
+				candidateOldLocationsOfScummVMConfigMap.put("A-" + (++incKeyId) + "-" + listOfAuxExtStoragePaths[incIndx],
+					new File(listOfAuxExtStoragePaths[incIndx + 1] + "/Android/data/" + getPackageName() + "/files/.config/scummvm/scummvm.ini"));
+				candidateOldLocationsOfScummVMConfigMap.put("A-" + (++incKeyId) + "-" + listOfAuxExtStoragePaths[incIndx],
+					new File(listOfAuxExtStoragePaths[incIndx + 1] + "/Android/data/" + getPackageName() + "/files/../.config/scummvm/scummvm.ini"));
+				candidateOldLocationsOfScummVMConfigMap.put("A-" + (++incKeyId) + "-" + listOfAuxExtStoragePaths[incIndx],
+					new File(listOfAuxExtStoragePaths[incIndx + 1] + "/scummvm.ini"));
+
+				candidateOldLocationsOfScummVMConfigMap.put("A-" + (++incKeyId) + "-" + listOfAuxExtStoragePaths[incIndx],
+					new File(listOfAuxExtStoragePaths[incIndx + 1] + "/Android/data/" + getPackageName() + "/files/scummvmrc"));
+				candidateOldLocationsOfScummVMConfigMap.put("A-" + (++incKeyId) + "-" + listOfAuxExtStoragePaths[incIndx],
+					new File(listOfAuxExtStoragePaths[incIndx + 1] + "/Android/data/" + getPackageName() + "/files/../scummvmrc"));
+				candidateOldLocationsOfScummVMConfigMap.put("A-" + (++incKeyId) + "-" + listOfAuxExtStoragePaths[incIndx],
+					new File(listOfAuxExtStoragePaths[incIndx + 1] + "/scummvmrc"));
+
+				candidateOldLocationsOfScummVMConfigMap.put("A-" + (++incKeyId) + "-" + listOfAuxExtStoragePaths[incIndx],
+					new File(listOfAuxExtStoragePaths[incIndx + 1] + "/Android/data/" + getPackageName() + "/files/.scummvmrc"));
+				candidateOldLocationsOfScummVMConfigMap.put("A-" + (++incKeyId) + "-" + listOfAuxExtStoragePaths[incIndx],
+					new File(listOfAuxExtStoragePaths[incIndx + 1] + "/Android/data/" + getPackageName() + "/files/../.scummvmrc"));
+				candidateOldLocationsOfScummVMConfigMap.put("A-" + (++incKeyId) + "-" + listOfAuxExtStoragePaths[incIndx],
+					new File(listOfAuxExtStoragePaths[incIndx + 1] + "/.scummvmrc"));
+			}
+		}
 
 		boolean scummVMConfigHandled = false;
 		Version maxOldVersionFound = new Version("0"); // dummy initializer
@@ -924,7 +1007,7 @@ public class ScummVMActivity extends Activity implements OnKeyboardVisibilityLis
 		File[] defaultSaveDirFiles = defaultScummVMSavesPath.listFiles();
 		if (defaultSaveDirFiles != null) {
 			Log.d(ScummVM.LOG_TAG, "Size: "+ defaultSaveDirFiles.length);
-
+			// TODO remove debug listing of files
 			if (defaultSaveDirFiles.length > 0 ) {
 				Log.d(ScummVM.LOG_TAG, "Listing ScummVM save files in default saves path...");
 				for (File savfile : defaultSaveDirFiles) {
@@ -971,6 +1054,40 @@ public class ScummVMActivity extends Activity implements OnKeyboardVisibilityLis
 				// this was for old Android plain port
 				candidateOldLocationsOfScummVMSavesMap.put("A17", new File(Environment.getExternalStorageDirectory(), "ScummVM/Saves"));
 
+				incKeyId = 0;
+				for (int incIndx = 0; incIndx + 1 < listOfAuxExtStoragePaths.length; incIndx += 2) {
+					// exclude identical matches for internal and emulated external app dir, since we take them into account below explicitly
+					if (listOfAuxExtStoragePaths[incIndx + 1].compareToIgnoreCase(_actualScummVMDataDir.getPath()) != 0
+						&& listOfAuxExtStoragePaths[incIndx + 1].compareToIgnoreCase(externalPossibleAlternateScummVMFilesDir.getPath()) != 0
+					) {
+						//
+						// Possible for Saves dirs locations on top of paths returned by getAllStorageLocationsNoPermissionRequest
+						//
+						candidateOldLocationsOfScummVMSavesMap.put("A-" + (++incKeyId) + "-" + listOfAuxExtStoragePaths[incIndx],
+							new File(listOfAuxExtStoragePaths[incIndx + 1] + "/ScummVM/Saves"));
+						candidateOldLocationsOfScummVMSavesMap.put("A-" + (++incKeyId) + "-" + listOfAuxExtStoragePaths[incIndx],
+							new File(listOfAuxExtStoragePaths[incIndx + 1] + "/Android/data/" +  getPackageName() + "/files/.local/share/scummvm/saves"));
+						candidateOldLocationsOfScummVMSavesMap.put("A-" + (++incKeyId) + "-" + listOfAuxExtStoragePaths[incIndx],
+							new File(listOfAuxExtStoragePaths[incIndx + 1] + "/Android/data/" +  getPackageName() + "/files/.local/scummvm/saves"));
+
+						candidateOldLocationsOfScummVMSavesMap.put("A-" + (++incKeyId) + "-" + listOfAuxExtStoragePaths[incIndx],
+							new File(listOfAuxExtStoragePaths[incIndx + 1] + "/Android/data/" +  getPackageName() + "/files/saves"));
+						candidateOldLocationsOfScummVMSavesMap.put("A-" + (++incKeyId) + "-" + listOfAuxExtStoragePaths[incIndx],
+							new File(listOfAuxExtStoragePaths[incIndx + 1] + "/Android/data/" +  getPackageName() + "/files/scummvm/saves"));
+						candidateOldLocationsOfScummVMSavesMap.put("A-" + (++incKeyId) + "-" + listOfAuxExtStoragePaths[incIndx],
+							new File(listOfAuxExtStoragePaths[incIndx + 1] + "/Android/data/" +  getPackageName() + "/files/../.local/share/scummvm/saves"));
+						candidateOldLocationsOfScummVMSavesMap.put("A-" + (++incKeyId) + "-" + listOfAuxExtStoragePaths[incIndx],
+							new File(listOfAuxExtStoragePaths[incIndx + 1] + "/Android/data/" +  getPackageName() + "/files/../.local/scummvm/saves"));
+
+						candidateOldLocationsOfScummVMSavesMap.put("A-" + (++incKeyId) + "-" + listOfAuxExtStoragePaths[incIndx],
+							new File(listOfAuxExtStoragePaths[incIndx + 1] + "/Android/data/" +  getPackageName() + "/files/../saves"));
+						candidateOldLocationsOfScummVMSavesMap.put("A-" + (++incKeyId) + "-" + listOfAuxExtStoragePaths[incIndx],
+							new File(listOfAuxExtStoragePaths[incIndx + 1] + "/Android/data/" +  getPackageName() + "/files/../scummvm/saves"));
+						candidateOldLocationsOfScummVMSavesMap.put("A-" + (++incKeyId) + "-" + listOfAuxExtStoragePaths[incIndx],
+							new File(listOfAuxExtStoragePaths[incIndx + 1] + "/.scummvmrc"));
+					}
+				}
+
 				for (String oldSavesPathDescription : candidateOldLocationsOfScummVMSavesMap.keySet()) {
 					File iterCandidateScummVMSavesPath = candidateOldLocationsOfScummVMSavesMap.get(oldSavesPathDescription);
 					Log.d(ScummVM.LOG_TAG, "Looking for old saves path " + oldSavesPathDescription + "...");
@@ -1114,12 +1231,12 @@ public class ScummVMActivity extends Activity implements OnKeyboardVisibilityLis
 					if (extfile.isFile()) {
 						if (extfile.getName().compareToIgnoreCase("scummvm.ini") != 0
 							&& (!containsStringEntry(filesItenary, extfile.getName())
-								|| !sideUpgrade)
+							|| !sideUpgrade)
 						) {
-								Log.d(ScummVM.LOG_TAG, "Deleting file:" + extfile.getName());
-								if (!extfile.delete()) {
-									Log.e(ScummVM.LOG_TAG, "Failed to delete file:" + extfile.getName());
-								}
+							Log.d(ScummVM.LOG_TAG, "Deleting file:" + extfile.getName());
+							if (!extfile.delete()) {
+								Log.e(ScummVM.LOG_TAG, "Failed to delete file:" + extfile.getName());
+							}
 						}
 					}
 				}
diff --git a/backends/platform/android/org/scummvm/scummvm/SplashActivity.java b/backends/platform/android/org/scummvm/scummvm/SplashActivity.java
new file mode 100644
index 0000000000..2eb84eb65e
--- /dev/null
+++ b/backends/platform/android/org/scummvm/scummvm/SplashActivity.java
@@ -0,0 +1,109 @@
+package org.scummvm.scummvm;
+
+import android.Manifest;
+import android.annotation.TargetApi;
+import android.app.Activity;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.os.Build;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.View;
+import android.widget.Toast;
+
+import androidx.annotation.NonNull;
+
+public class SplashActivity extends Activity {
+
+	/**
+	 * Ids to identify an external storage read (and write) request.
+	 * They are app-defined int constants. The callback method gets the result of the request.
+	 * Ie. returned in the Activity's onRequestPermissionsResult()
+	 */
+	private static final int MY_PERMISSION_ALL = 110;
+
+	private static final String[] MY_PERMISSIONS_STR_LIST = {
+		Manifest.permission.READ_EXTERNAL_STORAGE,
+		Manifest.permission.WRITE_EXTERNAL_STORAGE,
+	};
+
+
+	@Override
+	public void onCreate(Bundle savedInstanceState) {
+
+		super.onCreate(savedInstanceState);
+		hideSystemUI();
+
+		Version _currentScummVMVersion = new Version(BuildConfig.VERSION_NAME);
+		Log.d(ScummVM.LOG_TAG, "Splash: Current ScummVM version running is: " + _currentScummVMVersion.getDescription() + " (" + _currentScummVMVersion.get() + ")");
+
+		if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
+		    && (checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED
+		        || checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED)
+		) {
+			requestPermissions(MY_PERMISSIONS_STR_LIST, MY_PERMISSION_ALL);
+		} else {
+			startActivity(new Intent(this, ScummVMActivity.class));
+			finish();
+		}
+	}
+
+	@Override
+	public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
+		if (requestCode == MY_PERMISSION_ALL) {
+			int numOfReqPermsGranted = 0;
+			// If request is cancelled, the result arrays are empty.
+			if (grantResults.length > 0) {
+				for (int iterGrantResult: grantResults) {
+					if (iterGrantResult == PackageManager.PERMISSION_GRANTED) {
+						Log.i(ScummVM.LOG_TAG, permissions[0] + " permission was granted at Runtime");
+						++numOfReqPermsGranted;
+					} else {
+						Log.i(ScummVM.LOG_TAG, permissions[0] + " permission was denied at Runtime");
+					}
+				}
+			}
+
+			if (numOfReqPermsGranted != grantResults.length) {
+				// permission denied! We won't be able to make use of functionality depending on this permission.
+				Toast.makeText(this, "Until permission is granted, some storage locations may be inaccessible for r/w!", Toast.LENGTH_SHORT)
+					.show();
+			}
+		}
+		startActivity(new Intent(this, ScummVMActivity.class));
+		finish();
+	}
+
+	// TODO setSystemUiVisibility is introduced in API 11 and deprecated in API 30 - When we move to API 30 we will have to replace this code
+	//	https://developer.android.com/training/system-ui/immersive.html#java
+	//
+	//  The code sample in the url below contains code to switch between immersive and default mode
+	//	https://github.com/android/user-interface-samples/tree/master/AdvancedImmersiveMode
+	//  We could do something similar by making it a Global UI option.
+	@TargetApi(Build.VERSION_CODES.KITKAT)
+	private void hideSystemUI() {
+		// Enables regular immersive mode.
+		// For "lean back" mode, remove SYSTEM_UI_FLAG_IMMERSIVE.
+		// Or for "sticky immersive," replace it with SYSTEM_UI_FLAG_IMMERSIVE_STICKY
+		View decorView = getWindow().getDecorView();
+		decorView.setSystemUiVisibility(
+			View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
+				// Set the content to appear under the system bars so that the
+				// content doesn't resize when the system bars hide and show.
+				| View.SYSTEM_UI_FLAG_LAYOUT_STABLE
+				| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
+				| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
+				// Hide the nav bar and status bar
+				| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
+				| View.SYSTEM_UI_FLAG_FULLSCREEN);
+	}
+
+	@Override
+	public void onWindowFocusChanged(boolean hasFocus) {
+		super.onWindowFocusChanged(hasFocus);
+		if (hasFocus) {
+			hideSystemUI();
+		}
+	}
+
+}
diff --git a/dists/android/AndroidManifest.xml b/dists/android/AndroidManifest.xml
index be7c9b4f27..40f734fd18 100644
--- a/dists/android/AndroidManifest.xml
+++ b/dists/android/AndroidManifest.xml
@@ -1,69 +1,68 @@
 <?xml version="1.0" encoding="utf-8"?>
-
-<!-- NB: android:versionCode needs to be bumped for formal releases -->
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-		package="org.scummvm.scummvm"
-		android:launchMode="singleTask"
-		android:installLocation="auto"
-		android:sharedUserId="org.scummvm.scummvm">
-
-
-		<uses-permission
-			android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
-
-	<uses-permission
-			android:name="android.permission.READ_EXTERNAL_STORAGE"/>
+	package="org.scummvm.scummvm"
+	android:installLocation="auto"
+	android:launchMode="singleTask"
+	android:sharedUserId="org.scummvm.scummvm">
 
-	<uses-permission
-			android:name="android.permission.ACCESS_WIFI_STATE"/>
-
-	<uses-permission
-			android:name="android.permission.INTERNET" />
-
-	<uses-permission
-			android:name="android.permission.ACCESS_NETWORK_STATE" />
+	<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+	<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
+	<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
+	<uses-permission android:name="android.permission.INTERNET" />
+	<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
 
 	<uses-feature
-			android:name="android.hardware.wifi"
-			android:required="false"/>
-
+		android:name="android.hardware.wifi"
+		android:required="false" />
 	<uses-feature
-			android:name="android.hardware.screen.landscape"
-			android:required="false"/>
-
+		android:name="android.hardware.screen.landscape"
+		android:required="false" />
 	<uses-feature
-			android:name="android.hardware.touchscreen"
-			android:required="false"/>
-
+		android:name="android.hardware.touchscreen"
+		android:required="false" />
 	<uses-feature
-			android:name="android.software.leanback"
-			android:required="false"/>
+		android:name="android.software.leanback"
+		android:required="false" />
 
 	<supports-screens
-			android:smallScreens="true"
-			android:normalScreens="true"
-			android:largeScreens="true"
-			android:xlargeScreens="true" />
+		android:largeScreens="true"
+		android:normalScreens="true"
+		android:smallScreens="true"
+		android:xlargeScreens="true" />
 
 	<application
-			android:label="@string/app_name"
-			android:description="@string/app_desc"
-			android:allowBackup="true"
-			android:isGame="true"
-			android:resizeableActivity="false"
-			android:icon="@mipmap/scummvm">
-		<activity android:name=".ScummVMActivity"
-				android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
-				android:banner="@drawable/leanback_icon"
-				android:screenOrientation="landscape"
-				android:configChanges="orientation|keyboardHidden|screenSize"
-				android:windowSoftInputMode="adjustResize">
+		android:allowBackup="true"
+		android:description="@string/app_desc"
+		android:icon="@mipmap/scummvm"
+		android:isGame="true"
+		android:label="@string/app_name"
+		android:resizeableActivity="false">
+		<activity
+			android:name=".SplashActivity"
+			android:banner="@drawable/leanback_icon"
+			android:configChanges="orientation|keyboardHidden|screenSize"
+			android:screenOrientation="landscape"
+			android:theme="@style/SplashTheme"
+			android:windowSoftInputMode="adjustResize">
 			<intent-filter>
-				<action android:name="android.intent.action.MAIN"/>
-				<category android:name="android.intent.category.LAUNCHER"/>
-				<category android:name="tv.ouya.intent.category.GAME"/>
-				<category android:name="android.intent.category.LEANBACK_LAUNCHER"/>
+				<action android:name="android.intent.action.MAIN" />
+
+				<category android:name="android.intent.category.LAUNCHER" />
+				<category android:name="tv.ouya.intent.category.GAME" />
+				<category android:name="android.intent.category.LEANBACK_LAUNCHER" />
+			</intent-filter>
+		</activity>
+		<activity
+			android:name=".ScummVMActivity"
+			android:banner="@drawable/leanback_icon"
+			android:configChanges="orientation|keyboardHidden|screenSize"
+			android:screenOrientation="landscape"
+			android:theme="@style/AppTheme"
+			android:windowSoftInputMode="adjustResize">
+			<intent-filter>
+				<category android:name="tv.ouya.intent.category.GAME" />
 			</intent-filter>
 		</activity>
 	</application>
+
 </manifest>
diff --git a/dists/android/res/drawable/ic_scummvm_background.xml b/dists/android/res/drawable/ic_scummvm_background.xml
index 5b1d1c4088..d95f9f1a56 100644
--- a/dists/android/res/drawable/ic_scummvm_background.xml
+++ b/dists/android/res/drawable/ic_scummvm_background.xml
@@ -5,7 +5,7 @@
 	xmlns:android="http://schemas.android.com/apk/res/android">
     <group>
 		<path
-			android:fillColor="#cc6600"
+			android:fillColor="@color/colorPrimary"
 			android:pathData="M0,0h108v108h-108z" />
 	</group>
 </vector>
diff --git a/dists/android/res/drawable/splash.xml b/dists/android/res/drawable/splash.xml
new file mode 100644
index 0000000000..7ef066a4f8
--- /dev/null
+++ b/dists/android/res/drawable/splash.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android" android:opacity="opaque">
+<item android:drawable="@color/colorPrimary"/>
+<item>
+	<bitmap
+		android:gravity="center"
+		android:src="@drawable/scummvm_big"/>
+</item>
+</layer-list>
diff --git a/dists/android/res/values/colors.xml b/dists/android/res/values/colors.xml
new file mode 100644
index 0000000000..4bbfb35813
--- /dev/null
+++ b/dists/android/res/values/colors.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+	<!--   color for the app bar and other primary UI elements -->
+	<color name="colorPrimary">#FFCC6600</color>
+
+	<!--   a darker variant of the primary color, used for
+           the status bar (on Android 5.0+) and contextual app bars -->
+	<color name="colorPrimaryDark">#FFCC4400</color>
+
+	<!--   a secondary color for controls like checkboxes and text fields -->
+	<color name="colorAccent">#FFCC5500</color>
+
+    <color name="colorBackground">#FFCC6600</color>
+</resources>
+
diff --git a/dists/android/res/values/strings.xml b/dists/android/res/values/strings.xml
index beef262c4e..26bc8acb34 100644
--- a/dists/android/res/values/strings.xml
+++ b/dists/android/res/values/strings.xml
@@ -32,4 +32,8 @@
 		packages, from wherever you found ScummVM.</string>
 	<string name="to_market">To Market</string>
 	<string name="keyboard_toggle_btn_desc">Toggle virtual keyboard</string>
+	<string name="title_activity_splash">ScummVM Logo Activity</string>
+	<string name="title_activity_main">ScummVM Main Activity</string>
+	<string name="dummy_button">Dummy Button</string>
+	<string name="dummy_content">DUMMY\nCONTENT</string>
 </resources>
diff --git a/dists/android/res/values/themes.xml b/dists/android/res/values/themes.xml
new file mode 100644
index 0000000000..de8da852e5
--- /dev/null
+++ b/dists/android/res/values/themes.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+
+	<style name="AppTheme" parent="@android:style/Theme.NoTitleBar.Fullscreen">
+		<item name="android:colorBackground">@color/colorBackground</item>
+	</style>
+
+	<style name="SplashTheme" parent="AppTheme">
+		<item name="android:windowBackground">@drawable/splash</item>
+	</style>
+</resources>




More information about the Scummvm-git-logs mailing list