diff --git a/catroid/build.gradle b/catroid/build.gradle index 97b2d0a9533..4e8d9e87769 100644 --- a/catroid/build.gradle +++ b/catroid/build.gradle @@ -166,9 +166,9 @@ android { targetSdkVersion 26 applicationId appId testInstrumentationRunner 'android.support.test.runner.AndroidJUnitRunner' - versionCode 57 + versionCode 58 println "VersionCode is $versionCode" - versionName "0.9.52" + versionName "0.9.54" println "VersionName is $versionName" buildConfigField "String", "GIT_COMMIT_INFO", "\"${getGitCommitInfo()}\"" buildConfigField "String", "MAIN_URL_HTTPS", (project.hasProperty('useWebTest') ? '"https://web-test.catrob.at"' : '"https://share.catrob.at"') diff --git a/catroid/src/androidTest/java/org/catrobat/catroid/test/io/filepicker/ListProjectFilesTest.java b/catroid/src/androidTest/java/org/catrobat/catroid/test/io/filepicker/ListProjectFilesTest.java index 11a8cab230d..66a9d0b591c 100644 --- a/catroid/src/androidTest/java/org/catrobat/catroid/test/io/filepicker/ListProjectFilesTest.java +++ b/catroid/src/androidTest/java/org/catrobat/catroid/test/io/filepicker/ListProjectFilesTest.java @@ -26,6 +26,7 @@ import android.support.test.InstrumentationRegistry; import android.support.test.runner.AndroidJUnit4; +import org.catrobat.catroid.io.StorageOperations; import org.catrobat.catroid.ui.filepicker.ListProjectFilesTask; import org.junit.After; import org.junit.Before; @@ -38,6 +39,9 @@ import static junit.framework.Assert.assertTrue; +import static org.catrobat.catroid.common.Constants.CODE_XML_FILE_NAME; +import static org.catrobat.catroid.common.Constants.TMP_DIR_NAME; +import static org.catrobat.catroid.common.FlavoredConstants.EXTERNAL_STORAGE_ROOT_DIRECTORY; import static org.hamcrest.CoreMatchers.not; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.core.IsCollectionContaining.hasItem; @@ -48,23 +52,30 @@ public class ListProjectFilesTest { private File tmpFolder; @Before - public void setUp() { + public void setUp() throws IOException { tmpFolder = new File(InstrumentationRegistry.getTargetContext().getCacheDir(), "ListProjectFilesTestTmp"); - if (tmpFolder.exists()) { - tmpFolder.delete(); + if (tmpFolder.isDirectory()) { + StorageOperations.deleteDir(tmpFolder); } tmpFolder.mkdirs(); + if (EXTERNAL_STORAGE_ROOT_DIRECTORY.isDirectory()) { + StorageOperations.deleteDir(EXTERNAL_STORAGE_ROOT_DIRECTORY); + } + EXTERNAL_STORAGE_ROOT_DIRECTORY.mkdirs(); } @After - public void tearDown() { - if (tmpFolder.exists()) { - tmpFolder.delete(); + public void tearDown() throws IOException { + if (tmpFolder.isDirectory()) { + StorageOperations.deleteDir(tmpFolder); + } + if (EXTERNAL_STORAGE_ROOT_DIRECTORY.isDirectory()) { + StorageOperations.deleteDir(EXTERNAL_STORAGE_ROOT_DIRECTORY); } } @Test - public void testListFiles() throws IOException { + public void testListCatrobatFiles() throws IOException { File file0 = new File(tmpFolder, "projectWithoutExtension"); assertTrue(file0.createNewFile()); @@ -90,4 +101,35 @@ public void testListFiles() throws IOException { assertThat(projectFiles, not(hasItem(file2))); assertThat(projectFiles, not(hasItem(file4))); } + + @Test + public void testListProjectsOnExternalStorage() throws IOException { + + File backpackFolder = new File(EXTERNAL_STORAGE_ROOT_DIRECTORY, "backpack"); + assertTrue(backpackFolder.mkdirs()); + + File tempFolder = new File(EXTERNAL_STORAGE_ROOT_DIRECTORY, TMP_DIR_NAME); + assertTrue(tempFolder.mkdirs()); + + File projectFolder1 = new File(EXTERNAL_STORAGE_ROOT_DIRECTORY, "projectFolder1"); + assertTrue(projectFolder1.mkdirs()); + assertTrue(new File(projectFolder1, CODE_XML_FILE_NAME).createNewFile()); + + File projectFolder2 = new File(EXTERNAL_STORAGE_ROOT_DIRECTORY, "projectFolder2"); + assertTrue(projectFolder2.mkdirs()); + assertTrue(new File(projectFolder2, CODE_XML_FILE_NAME).createNewFile()); + + File someFolder = new File(EXTERNAL_STORAGE_ROOT_DIRECTORY, "someFolder"); + assertTrue(someFolder.mkdirs()); + + List projectFiles = ListProjectFilesTask + .task(tmpFolder); + + assertThat(projectFiles, hasItem(projectFolder1)); + assertThat(projectFiles, hasItem(projectFolder2)); + + assertThat(projectFiles, not(hasItem(backpackFolder))); + assertThat(projectFiles, not(hasItem(tempFolder))); + assertThat(projectFiles, not(hasItem(someFolder))); + } } diff --git a/catroid/src/main/java/org/catrobat/catroid/ui/filepicker/ListProjectFilesTask.java b/catroid/src/main/java/org/catrobat/catroid/ui/filepicker/ListProjectFilesTask.java index c70fa36d6db..5c4e2f9b8aa 100644 --- a/catroid/src/main/java/org/catrobat/catroid/ui/filepicker/ListProjectFilesTask.java +++ b/catroid/src/main/java/org/catrobat/catroid/ui/filepicker/ListProjectFilesTask.java @@ -30,7 +30,11 @@ import java.util.ArrayList; import java.util.List; +import static org.catrobat.catroid.common.Constants.BACKPACK_DIRECTORY; import static org.catrobat.catroid.common.Constants.CATROBAT_EXTENSION; +import static org.catrobat.catroid.common.Constants.CODE_XML_FILE_NAME; +import static org.catrobat.catroid.common.Constants.TMP_DIR_NAME; +import static org.catrobat.catroid.common.FlavoredConstants.EXTERNAL_STORAGE_ROOT_DIRECTORY; public class ListProjectFilesTask extends AsyncTask> { @@ -45,6 +49,7 @@ public static List task(File... startDir) { for (File dir : startDir) { findProjectFiles(dir, files); } + getAllProjectsFromPocketCodeFolder(files); return files; } @@ -60,6 +65,17 @@ private static void findProjectFiles(File dir, List projectFiles) { } } + public static void getAllProjectsFromPocketCodeFolder(List projectFiles) { + for (File dir : EXTERNAL_STORAGE_ROOT_DIRECTORY.listFiles()) { + if (!dir.getName().equals(BACKPACK_DIRECTORY.getName()) + && !dir.getName().equals(TMP_DIR_NAME) + && dir.isDirectory() + && new File(dir, CODE_XML_FILE_NAME).exists()) { + projectFiles.add(dir); + } + } + } + @Override protected List doInBackground(File... startDir) { return task(startDir); diff --git a/catroid/src/main/java/org/catrobat/catroid/ui/recyclerview/fragment/ProjectListFragment.java b/catroid/src/main/java/org/catrobat/catroid/ui/recyclerview/fragment/ProjectListFragment.java index a96f69b92ea..f953904c474 100644 --- a/catroid/src/main/java/org/catrobat/catroid/ui/recyclerview/fragment/ProjectListFragment.java +++ b/catroid/src/main/java/org/catrobat/catroid/ui/recyclerview/fragment/ProjectListFragment.java @@ -38,6 +38,7 @@ import org.catrobat.catroid.io.StorageOperations; import org.catrobat.catroid.io.asynctask.ProjectCopyTask; import org.catrobat.catroid.io.asynctask.ProjectExportTask; +import org.catrobat.catroid.io.asynctask.ProjectImportTask; import org.catrobat.catroid.io.asynctask.ProjectLoadTask; import org.catrobat.catroid.io.asynctask.ProjectRenameTask; import org.catrobat.catroid.io.asynctask.ProjectUnzipAndImportTask; @@ -75,8 +76,7 @@ public class ProjectListFragment extends RecyclerViewFragment implements ProjectLoadTask.ProjectLoadListener, ProjectCopyTask.ProjectCopyListener, - ProjectRenameTask.ProjectRenameListener, - ProjectUnzipAndImportTask.ProjectUnzipAndImportListener { + ProjectRenameTask.ProjectRenameListener { public static final String TAG = ProjectListFragment.class.getSimpleName(); @@ -87,6 +87,30 @@ public class ProjectListFragment extends RecyclerViewFragment imple private ProjectController projectController = new ProjectController(); + private ProjectUnzipAndImportTask.ProjectUnzipAndImportListener projectUnzipAndImportListener = + new ProjectUnzipAndImportTask.ProjectUnzipAndImportListener() { + @Override + public void onImportFinished(boolean success) { + adapter.setItems(getItemList()); + if (!success) { + ToastUtil.showError(getContext(), R.string.error_import_project); + } + setShowProgressBar(false); + } + }; + + private ProjectImportTask.ProjectImportListener projectImportListener = + new ProjectImportTask.ProjectImportListener() { + @Override + public void onImportFinished(boolean success) { + adapter.setItems(getItemList()); + if (!success) { + ToastUtil.showError(getContext(), R.string.error_import_project); + } + setShowProgressBar(false); + } + }; + @Override public void onResume() { ProjectManager.getInstance().setCurrentProject(null); @@ -162,11 +186,25 @@ private void importProject(Intent data) { return; } + if (!data.getData().getScheme().equals("file")) { + throw new IllegalArgumentException("importProject has to be called with a file uri. (not a content uri"); + } + try { - File projectZip = StorageOperations - .copyUriToDir(getContext().getContentResolver(), data.getData(), CACHE_DIR, CACHED_PROJECT_ZIP_FILE_NAME); - new ProjectUnzipAndImportTask(this) - .execute(projectZip); + File cacheFile = new File(CACHE_DIR, CACHED_PROJECT_ZIP_FILE_NAME); + if (cacheFile.exists()) { + cacheFile.delete(); + } + File src = new File(data.getData().getPath()); + if (src.isDirectory()) { + new ProjectImportTask(projectImportListener) + .execute(src); + } else { + File projectFile = StorageOperations + .copyUriToDir(getContext().getContentResolver(), data.getData(), CACHE_DIR, CACHED_PROJECT_ZIP_FILE_NAME); + new ProjectUnzipAndImportTask(projectUnzipAndImportListener) + .execute(projectFile); + } setShowProgressBar(true); } catch (IOException e) { Log.e(TAG, "Cannot resolve project to import.", e); @@ -299,15 +337,6 @@ public void onRenameFinished(boolean success) { setShowProgressBar(false); } - @Override - public void onImportFinished(boolean success) { - adapter.setItems(getItemList()); - if (!success) { - ToastUtil.showError(getContext(), R.string.error_import_project); - } - setShowProgressBar(false); - } - @Override @PluralsRes protected int getActionModeTitleId(@ActionModeType int actionModeType) {