diff --git a/pkg/android/phoenix/src/com/retroarch/browser/mainmenu/MigrateRetroarchFolderActivity.java b/pkg/android/phoenix/src/com/retroarch/browser/mainmenu/MigrateRetroarchFolderActivity.java index 1916aaa582..b02b6f6e10 100644 --- a/pkg/android/phoenix/src/com/retroarch/browser/mainmenu/MigrateRetroarchFolderActivity.java +++ b/pkg/android/phoenix/src/com/retroarch/browser/mainmenu/MigrateRetroarchFolderActivity.java @@ -13,6 +13,7 @@ import android.content.pm.PackageManager; import android.database.Cursor; import android.net.Uri; import android.os.AsyncTask; +import android.os.Bundle; import android.os.Environment; import android.os.ParcelFileDescriptor; import android.preference.PreferenceManager; @@ -23,10 +24,18 @@ import android.util.Pair; import com.retroarch.R; import java.io.File; -import java.lang.ref.WeakReference; +import java.io.IOException; +import java.nio.charset.StandardCharsets; import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; import java.nio.file.StandardCopyOption; +import java.nio.file.attribute.BasicFileAttributes; import java.util.ArrayList; +import java.util.function.BiPredicate; +import java.util.function.Consumer; +import java.util.stream.Stream; + @TargetApi(26) public class MigrateRetroarchFolderActivity extends Activity @@ -34,9 +43,9 @@ public class MigrateRetroarchFolderActivity extends Activity final int REQUEST_CODE_GET_OLD_RETROARCH_FOLDER = 125; @Override - public void onStart() + public void onCreate(Bundle savedInstanceState) { - super.onStart(); + super.onCreate(savedInstanceState); // Needs v26 for some of the file handling functions below. // Remove the TargetApi annotation to see which. @@ -44,7 +53,7 @@ public class MigrateRetroarchFolderActivity extends Activity if (android.os.Build.VERSION.SDK_INT < 26) { finish(); } - if(true || needToMigrate()){ + if(needToMigrate()){ askToMigrate(); }else{ finish(); @@ -79,6 +88,7 @@ public class MigrateRetroarchFolderActivity extends Activity void askToMigrate() { AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setCancelable(false); builder.setTitle(R.string.migrate_retroarch_folder_dialog_title); builder.setMessage(R.string.migrate_retroarch_folder_dialog_message); builder.setNegativeButton(R.string.migrate_retroarch_folder_dialog_negative, new DialogInterface.OnClickListener() { @@ -128,7 +138,7 @@ public class MigrateRetroarchFolderActivity extends Activity final ProgressDialog pd = new ProgressDialog(this); pd.setMax(100); pd.setTitle(R.string.migrate_retroarch_folder_inprogress); - pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); + pd.setProgressStyle(ProgressDialog.STYLE_SPINNER); pd.setCancelable(false); CopyThread thread = new CopyThread() @@ -139,11 +149,10 @@ public class MigrateRetroarchFolderActivity extends Activity pd.show(); } @Override - protected void onProgressUpdate(Pair... params) + protected void onProgressUpdate(String... params) { super.onProgressUpdate(params); - pd.setProgress(params[0].first); - pd.setMessage(params[0].second); + pd.setMessage(params[0]); } @Override protected void onPostExecute(Boolean ok) @@ -161,7 +170,7 @@ public class MigrateRetroarchFolderActivity extends Activity { SharedPreferences.Editor editor = PreferenceManager.getDefaultSharedPreferences(this).edit(); editor.putBoolean("external_retroarch_folder_needs_migrate", false); - editor.commit(); + editor.apply(); AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setMessage(ok ? @@ -176,27 +185,24 @@ public class MigrateRetroarchFolderActivity extends Activity builder.create().show(); } - class CopyThread extends AsyncTask, Boolean> + class CopyThread extends AsyncTask { - String PACKAGE_NAME; ContentResolver resolver; - Uri sourceRoot; boolean error; - ArrayList progress; - public CopyThread() + @Override + protected void onPreExecute() { - PACKAGE_NAME = MigrateRetroarchFolderActivity.this.getPackageName(); resolver = MigrateRetroarchFolderActivity.this.getContentResolver(); + error = false; } @Override protected Boolean doInBackground(Uri... params) { - sourceRoot = params[0]; + Uri source = params[0]; error = false; - progress = new ArrayList<>(); - - String destination = Environment.getExternalStorageDirectory().getAbsolutePath() + "/Android/data/" + PACKAGE_NAME + "/files/RetroArch"; - copyFolder(sourceRoot, new File(destination)); + String destination = Environment.getExternalStorageDirectory().getAbsolutePath() + "/Android/data/" + MigrateRetroarchFolderActivity.this.getPackageName() + "/files/RetroArch"; + copyFolder(source, new File(destination)); + patchConfig(); return !error; } void copyFolder(Uri sourceUri, File dest) @@ -214,8 +220,8 @@ public class MigrateRetroarchFolderActivity extends Activity }catch(IllegalArgumentException ex){ //for root selected by document picker sourceChildrenResolver = DocumentsContract.buildChildDocumentsUriUsingTree(sourceUri, DocumentsContract.getTreeDocumentId(sourceUri)); } - progress.add(new int[]{0, 1}); try( + //list children of directory Cursor c = resolver.query(sourceChildrenResolver, new String[]{DocumentsContract.Document.COLUMN_DOCUMENT_ID, DocumentsContract.Document.COLUMN_DISPLAY_NAME, DocumentsContract.Document.COLUMN_MIME_TYPE}, null, null, null) ) { if(c == null) { @@ -223,7 +229,6 @@ public class MigrateRetroarchFolderActivity extends Activity error = true; return; } - progress.get(progress.size() - 1)[1] = c.getCount(); while(c.moveToNext()){ //loop through children returned String childFilename = c.getString(1); Uri childUri = DocumentsContract.buildDocumentUriUsingTree(sourceUri, c.getString(0)); @@ -243,24 +248,59 @@ public class MigrateRetroarchFolderActivity extends Activity error = true; } } - progress.get(progress.size() - 1)[0]++; - publishProgress(new Pair(getProgressPercentage(), destFile.getPath())); + publishProgress(destFile.toString()); } }catch(Exception ex){ Log.e("MigrateRetroarchFolder", "Error while copying", ex); error = true; } - progress.remove(progress.size() - 1); } - int getProgressPercentage() - { - float sum = 0; - int lastDenominator = 1; - for(int[] frac : progress){ - sum += ((float) frac[0]) / frac[1] / lastDenominator; - lastDenominator *= frac[1]; + void patchConfig(){ + String appDir = Environment.getExternalStorageDirectory().getAbsolutePath() + "/Android/data/" + MigrateRetroarchFolderActivity.this.getPackageName() + "/files"; + String legacyDefaultRetroarchPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/RetroArch"; + String migratedRetroarchPath = appDir + "/RetroArch"; + + final ArrayList files = new ArrayList<>(); + try ( + Stream s = Files.find(Paths.get(appDir), 30, new BiPredicate() { + @Override + public boolean test(Path path, BasicFileAttributes basicFileAttributes) { + String p = path.toString(); + return p.endsWith(".lpl") || p.endsWith(".cfg"); + } + }) + ){ + // yes it's a roudabout way to gather it in a list, but Stream.collect is throwing type errors + s.forEach(new Consumer() { + @Override + public void accept(Path path) { + files.add(path); + } + }); + }catch(IOException ex){ + Log.e("MigrateRetroarchFolder", "Error searching for config files", ex); + error = true; + return; + } + + for(Path file : files){ + try{ + //back up before patching + Path backupFile = file.resolveSibling(file.getFileName() + ".old"); + Files.copy(file, backupFile, StandardCopyOption.REPLACE_EXISTING); + + //replace old retroarch prefix with new path + //assumes default old path, doesn't help if user has relocated it + //not doing any syntactical analysis because the search string is pretty long and unique + String contents = new String(Files.readAllBytes(file)); + String replaced = contents.replace(legacyDefaultRetroarchPath, migratedRetroarchPath); + Files.write(file, replaced.getBytes(StandardCharsets.UTF_8)); + }catch(IOException ex){ + Log.e("MigrateRetroarchFolder", "Error patching file " + file.toAbsolutePath(), ex); + error = true; + return; + } } - return (int) (sum * 100); } } }