diff --git a/services_app/src/androidTest/java/org/opendatakit/database/service/OdkDatabaseServiceImplTest.java b/services_app/src/androidTest/java/org/opendatakit/database/service/OdkDatabaseServiceImplTest.java index 0f5083893..a1c2196af 100644 --- a/services_app/src/androidTest/java/org/opendatakit/database/service/OdkDatabaseServiceImplTest.java +++ b/services_app/src/androidTest/java/org/opendatakit/database/service/OdkDatabaseServiceImplTest.java @@ -3,6 +3,7 @@ import android.content.ContentValues; import android.database.Cursor; +import androidx.documentfile.provider.DocumentFile; import androidx.test.core.app.ApplicationProvider; import org.junit.FixMethodOrder; @@ -999,7 +1000,7 @@ private void verifyRowExistsInLocalTable(int expectedNumRows, BaseTable baseTabl @Test public void testDeleteAllCheckpointRowsWithId() { try { - File instanceFolder = makeTemp("t3"); + DocumentFile instanceFolder = makeTemp("t3"); createTeaHouses(); setSuperuser(); thInsert("t1", SavepointTypeManipulator.complete()); @@ -1029,7 +1030,7 @@ private void verifyRowExistsInLocalTable(int expectedNumRows, BaseTable baseTabl try { - File instanceFolder = makeTemp("t3"); + DocumentFile instanceFolder = makeTemp("t3"); createTeaHouses(); setSuperuser(); thInsert("t3", SavepointTypeManipulator.incomplete()); @@ -1563,17 +1564,21 @@ private static List makeMetadata() { return l; } - private static File makeTemp(String id) throws Exception { + private static DocumentFile makeTemp(String id) throws Exception { File instanceFolder = new File( - ODKFileUtils.getInstanceFolder(APPNAME, TEA_HOUSES_TBL_NAME, id)); + ODKFileUtils.getInstanceFolder(APPNAME, TEA_HOUSES_TBL_NAME, id)); if (!instanceFolder.exists() && !instanceFolder.mkdirs()) { throw new Exception("Should have been able to create " + instanceFolder.getPath()); } assertTrue(instanceFolder.exists()); - FileOutputStream f = new FileOutputStream(new File(instanceFolder.getPath() + "/temp")); - f.write(new byte[] { 97, 98, 99 }); + File tempFile = new File(instanceFolder, "temp"); + FileOutputStream f = new FileOutputStream(tempFile); + f.write(new byte[]{97, 98, 99}); f.close(); - return instanceFolder; + + // Convert the File object to a DocumentFile + DocumentFile documentFile = DocumentFile.fromFile(tempFile); + return documentFile; } private void insertMetadata(String table, String partition, String aspect, String key, diff --git a/services_app/src/androidTest/java/org/opendatakit/services/sync/service/logic/AggregateSynchronizerTest.java b/services_app/src/androidTest/java/org/opendatakit/services/sync/service/logic/AggregateSynchronizerTest.java index 7c3f561c5..ca8284961 100644 --- a/services_app/src/androidTest/java/org/opendatakit/services/sync/service/logic/AggregateSynchronizerTest.java +++ b/services_app/src/androidTest/java/org/opendatakit/services/sync/service/logic/AggregateSynchronizerTest.java @@ -4,6 +4,7 @@ import android.app.Application; import android.content.Context; +import androidx.documentfile.provider.DocumentFile; import androidx.test.InstrumentationRegistry; import androidx.test.filters.Suppress; import androidx.test.rule.GrantPermissionRule; @@ -290,14 +291,16 @@ public void testGetAppLevelFileManifestWithNoFiles_ExpectPass() { try { AggregateSynchronizer synchronizer = new AggregateSynchronizer(sharedContext); + DocumentFile[] nullFiles = null; + FileManifestDocument tableManifestEntries = - synchronizer.getAppLevelFileManifest(null, null, true); + synchronizer.getAppLevelFileManifest(String.valueOf(nullFiles), null, true); + assertEquals(0, tableManifestEntries.entries.size()); } catch (Exception e) { fail("testGetAppLevelFileManifestWithNoFiles_ExpectPass: expected pass but got exception"); e.printStackTrace(); - } } @@ -417,6 +420,8 @@ public void testDeleteConfigFile_ExpectPass() { // Now copy this file over to the correct place on the device FileUtils.writeStringToFile(destFile, "This is a test", CharsetConsts.UTF_8); + DocumentFile documentFile = DocumentFile.fromFile(destFile); + synchronizer.uploadConfigFile(destFile); synchronizer.deleteConfigFile(destFile); @@ -1099,7 +1104,7 @@ public void testUploadInstanceFile_ExpectPass() { } RowOutcomeList rowOutList = synchronizer.pushLocalRows(testTableRes, orderedColumns, - listOfRowsToCreate); + listOfRowsToCreate); String destDir = ODKFileUtils.getInstanceFolder(appName, testTableId, rowId); @@ -1107,6 +1112,9 @@ public void testUploadInstanceFile_ExpectPass() { FileUtils.writeStringToFile(destFile, "This is a test", CharsetConsts.UTF_8); + // Convert destFile to DocumentFile + DocumentFile documentFile = DocumentFile.fromFile(destFile); + CommonFileAttachmentTerms cat1 = synchronizer.createCommonFileAttachmentTerms(testTableRes.getInstanceFilesUri(), testTableId, rowId, ODKFileUtils.asRowpathUri(appName, testTableId, rowId, destFile)); @@ -1172,8 +1180,7 @@ public void testDownloadFile_ExpectPass() { listOfRowsToCreate.add(new TypedRow(row, orderedColumns)); } - RowOutcomeList rowOutList = synchronizer.pushLocalRows(testTableRes, orderedColumns, - listOfRowsToCreate); + RowOutcomeList rowOutList = synchronizer.pushLocalRows(testTableRes, orderedColumns, listOfRowsToCreate); String fileName = "testFile.txt"; @@ -1184,7 +1191,7 @@ public void testDownloadFile_ExpectPass() { FileUtils.writeStringToFile(destFile, "This is a test", CharsetConsts.UTF_8); CommonFileAttachmentTerms cat1 = synchronizer.createCommonFileAttachmentTerms(testTableRes.getInstanceFilesUri(), - testTableId, rowId, ODKFileUtils.asRowpathUri(appName, testTableId, rowId, destFile)); + testTableId, rowId, ODKFileUtils.asRowpathUri(appName, testTableId, rowId, destFile)); synchronizer.uploadInstanceFile(destFile, cat1.instanceFileDownloadUri); @@ -1193,6 +1200,10 @@ public void testDownloadFile_ExpectPass() { String destDir2 = ODKFileUtils.getInstanceFolder(appName, testTableId, rowId); File destFile2 = new File(destDir2, fileName2); + + // Convert destFile2 to DocumentFile + DocumentFile documentFile = DocumentFile.fromFile(destFile2); + synchronizer.downloadFile(destFile2, cat1.instanceFileDownloadUri); synchronizer.deleteTable(testTableRes); @@ -1384,4 +1395,4 @@ public void testDownloadBatch_ExpectPass() { fail("testDownloadBatch_ExpectPass: expected pass but got exception"); } } -} \ No newline at end of file +} diff --git a/services_app/src/androidTest/java/org/opendatakit/utilities/AbstractPermissionsTestCase.java b/services_app/src/androidTest/java/org/opendatakit/utilities/AbstractPermissionsTestCase.java index 1c3a0cabf..795674f62 100644 --- a/services_app/src/androidTest/java/org/opendatakit/utilities/AbstractPermissionsTestCase.java +++ b/services_app/src/androidTest/java/org/opendatakit/utilities/AbstractPermissionsTestCase.java @@ -17,6 +17,8 @@ import android.Manifest; import android.content.ContentValues; import android.database.Cursor; + +import androidx.documentfile.provider.DocumentFile; import androidx.test.rule.GrantPermissionRule; import android.util.Log; import com.fasterxml.jackson.core.JsonProcessingException; @@ -416,9 +418,9 @@ protected ContentValues buildUnprivilegedInsertableRowContent(String tableId) { cvValues.put("col4", "this is a test"); // string // string with 500 varchars allocated to it cvValues.put("col5", "and a long string test"); // string(500) - File configFile = new File( - ODKFileUtils.getAssetsCsvInstanceFolder(getAppName(), tableId, rowIdFullCommon), - "sample.jpg"); + DocumentFile configFile = DocumentFile.fromFile( + new File(ODKFileUtils.getAssetsCsvInstanceFolder(getAppName(), tableId, rowIdFullCommon), + "sample.jpg")); cvValues.put("col6", ODKFileUtils.asConfigRelativePath(getAppName(), configFile)); // configpath File rowFile = new File(ODKFileUtils.getInstanceFolder(getAppName(), tableId, rowIdFullCommon), "sample.jpg"); try { diff --git a/services_app/src/androidTest/java/org/opendatakit/webkitserver/service/OdkWebserverServiceTest.java b/services_app/src/androidTest/java/org/opendatakit/webkitserver/service/OdkWebserverServiceTest.java index d3ea766d4..1484ba41c 100644 --- a/services_app/src/androidTest/java/org/opendatakit/webkitserver/service/OdkWebserverServiceTest.java +++ b/services_app/src/androidTest/java/org/opendatakit/webkitserver/service/OdkWebserverServiceTest.java @@ -37,6 +37,7 @@ import java.nio.charset.StandardCharsets; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; /** diff --git a/services_app/src/main/java/org/opendatakit/services/preferences/fragments/DeviceSettingsFragment.java b/services_app/src/main/java/org/opendatakit/services/preferences/fragments/DeviceSettingsFragment.java index b6dd6752a..493ca04e8 100644 --- a/services_app/src/main/java/org/opendatakit/services/preferences/fragments/DeviceSettingsFragment.java +++ b/services_app/src/main/java/org/opendatakit/services/preferences/fragments/DeviceSettingsFragment.java @@ -23,6 +23,7 @@ import android.provider.MediaStore; import android.widget.Toast; +import androidx.documentfile.provider.DocumentFile; import androidx.loader.app.LoaderManager; import androidx.preference.CheckBoxPreference; import androidx.preference.ListPreference; @@ -290,7 +291,7 @@ public void onClick(DialogInterface dialog, int item) { } if (newMedia.exists()) { - String appRelativePath = ODKFileUtils.asRelativePath(props.getAppName(), newMedia); + String appRelativePath = ODKFileUtils.asRelativePath(props.getAppName(), DocumentFile.fromFile(newMedia)); props.setProperties(Collections.singletonMap(CommonToolProperties .KEY_SPLASH_PATH, appRelativePath)); diff --git a/services_app/src/main/java/org/opendatakit/services/sync/service/logic/AggregateSynchronizer.java b/services_app/src/main/java/org/opendatakit/services/sync/service/logic/AggregateSynchronizer.java index e5a82d415..303922cd7 100644 --- a/services_app/src/main/java/org/opendatakit/services/sync/service/logic/AggregateSynchronizer.java +++ b/services_app/src/main/java/org/opendatakit/services/sync/service/logic/AggregateSynchronizer.java @@ -15,6 +15,8 @@ */ package org.opendatakit.services.sync.service.logic; +import androidx.documentfile.provider.DocumentFile; + import org.apache.commons.fileupload.MultipartStream; import org.opendatakit.aggregate.odktables.rest.SyncState; import org.opendatakit.aggregate.odktables.rest.entity.AppNameList; @@ -438,7 +440,6 @@ public ChangeSetList getChangeSets(TableResource table, String dataETag) throws } } - @Override public RowResourceList getChangeSet(TableResource table, String dataETag, boolean activeOnly, String websafeResumeCursor) throws HttpClientWebException, IOException { @@ -890,7 +891,7 @@ public void downloadFile(File destFile, URI downloadUrl) throws HttpClientWebExc @Override public void deleteConfigFile(File localFile) throws HttpClientWebException, IOException { String pathRelativeToConfigFolder = ODKFileUtils.asConfigRelativePath(sc.getAppName(), - localFile); + DocumentFile.fromFile(localFile)); URI filesUri = wrapper.constructConfigFileUri(pathRelativeToConfigFolder); log.i(LOGTAG, "CLARICE:[deleteConfigFile] fileDeleteUri: " + filesUri.toString()); @@ -911,7 +912,7 @@ public void deleteConfigFile(File localFile) throws HttpClientWebException, IOEx @Override public void uploadConfigFile(File localFile) throws HttpClientWebException, IOException { String pathRelativeToConfigFolder = ODKFileUtils.asConfigRelativePath(sc.getAppName(), - localFile); + DocumentFile.fromFile(localFile)); URI filesUri = wrapper.constructConfigFileUri(pathRelativeToConfigFolder); log.i(LOGTAG, "[uploadConfigFile] filePostUri: " + filesUri.toString()); String ct = HttpRestProtocolWrapper.determineContentType(localFile.getName()); diff --git a/services_app/src/main/java/org/opendatakit/services/sync/service/logic/ProcessManifestContentAndFileChanges.java b/services_app/src/main/java/org/opendatakit/services/sync/service/logic/ProcessManifestContentAndFileChanges.java index 59deaf5fa..64fecd1f0 100644 --- a/services_app/src/main/java/org/opendatakit/services/sync/service/logic/ProcessManifestContentAndFileChanges.java +++ b/services_app/src/main/java/org/opendatakit/services/sync/service/logic/ProcessManifestContentAndFileChanges.java @@ -15,6 +15,8 @@ */ package org.opendatakit.services.sync.service.logic; +import androidx.documentfile.provider.DocumentFile; + import org.opendatakit.aggregate.odktables.rest.entity.OdkTablesFileManifestEntry; import org.opendatakit.database.data.ColumnDefinition; import org.opendatakit.database.service.DbHandle; @@ -114,13 +116,13 @@ private List getAppLevelFiles() { LinkedList unexploredDirs = new LinkedList(); List relativePaths = new ArrayList(); - + unexploredDirs.add(baseFolder); boolean haveFilteredTablesDir = false; boolean haveFilteredAssetsCsvDir = false; boolean haveFilteredTableInitFile = false; - + while (!unexploredDirs.isEmpty()) { File exploring = unexploredDirs.removeFirst(); File[] files = exploring.listFiles(); @@ -158,7 +160,7 @@ private List getAppLevelFiles() { } // we'll add it to our list of files. - relativePaths.add(ODKFileUtils.asRelativePath(sc.getAppName(), f)); + relativePaths.add(ODKFileUtils.asRelativePath(sc.getAppName(), DocumentFile.fromFile(f))); } } } @@ -199,7 +201,7 @@ private static List filterInTableIdFiles(List relativePaths, Str *

* If the baseFolder exists but is not a directory, logs an error and returns an * empty list. - * + * * @param baseFolder * @param excludingNamedItemsUnderFolder * can be null--nothing will be excluded. Should be relative to the @@ -262,7 +264,7 @@ public boolean accept(File pathname) { // we want the relative path, so drop the necessary bets. for (File f : nondirFiles) { // +1 to exclude the separator. - relativePaths.add(ODKFileUtils.asRelativePath(sc.getAppName(), f)); + relativePaths.add(ODKFileUtils.asRelativePath(sc.getAppName(), DocumentFile.fromFile(f))); } return relativePaths; } @@ -323,7 +325,7 @@ public void syncAppLevelFiles(boolean pushLocalFiles, String serverReportedAppLe serverFilesToDelete.add(localFile); } else if (ODKFileUtils.getMd5Hash(sc.getAppName(), localFile).equals(entry.md5hash)) { // we are ok -- no need to upload or delete - relativePathsOnDevice.remove(ODKFileUtils.asRelativePath(sc.getAppName(), localFile)); + relativePathsOnDevice.remove(ODKFileUtils.asRelativePath(sc.getAppName(), DocumentFile.fromFile(localFile))); } } @@ -345,7 +347,7 @@ public void syncAppLevelFiles(boolean pushLocalFiles, String serverReportedAppLe for (File localFile : serverFilesToDelete) { - String relativePath = ODKFileUtils.asRelativePath(sc.getAppName(), localFile); + String relativePath = ODKFileUtils.asRelativePath(sc.getAppName(), DocumentFile.fromFile(localFile)); syncStatus.updateNotification(SyncProgressState.APP_FILES, R.string.sync_deleting_file_on_server, new Object[] { relativePath }, stepCount * stepSize, false); @@ -362,7 +364,7 @@ public void syncAppLevelFiles(boolean pushLocalFiles, String serverReportedAppLe for (OdkTablesFileManifestEntry entry : manifestDocument.entries) { File localFile = ODKFileUtils.asConfigFile(sc.getAppName(), entry.filename); - String relativePath = ODKFileUtils.asRelativePath(sc.getAppName(), localFile); + String relativePath = ODKFileUtils.asRelativePath(sc.getAppName(), DocumentFile.fromFile(localFile)); syncStatus.updateNotification(SyncProgressState.APP_FILES, R.string.sync_verifying_local_file, @@ -455,7 +457,7 @@ public void syncTableLevelFiles(String tableId, String serverReportedTableLevelE return; } String tableIdPropertiesFile = ODKFileUtils.asRelativePath(sc.getAppName(), - new File(ODKFileUtils.getTablePropertiesCsvFile(sc.getAppName(), tableId))); + DocumentFile.fromFile(new File(ODKFileUtils.getTablePropertiesCsvFile(sc.getAppName(), tableId)))); boolean tablePropertiesChanged = false; @@ -491,7 +493,7 @@ public void syncTableLevelFiles(String tableId, String serverReportedTableLevelE serverFilesToDelete.add(localFile); } else if (ODKFileUtils.getMd5Hash(sc.getAppName(), localFile).equals(entry.md5hash)) { // we are ok -- no need to upload or delete - relativePathsOnDevice.remove(ODKFileUtils.asRelativePath(sc.getAppName(), localFile)); + relativePathsOnDevice.remove(ODKFileUtils.asRelativePath(sc.getAppName(), DocumentFile.fromFile(localFile))); } } @@ -512,7 +514,7 @@ public void syncTableLevelFiles(String tableId, String serverReportedTableLevelE for (File localFile : serverFilesToDelete) { - String relativePath = ODKFileUtils.asRelativePath(sc.getAppName(), localFile); + String relativePath = ODKFileUtils.asRelativePath(sc.getAppName(), DocumentFile.fromFile(localFile)); syncStatus.updateNotification(SyncProgressState.TABLE_FILES, R.string.sync_deleting_file_on_server, new Object[] { relativePath }, stepCount * stepSize, false); @@ -529,7 +531,7 @@ public void syncTableLevelFiles(String tableId, String serverReportedTableLevelE for (OdkTablesFileManifestEntry entry : manifestDocument.entries) { File localFile = ODKFileUtils.asConfigFile(sc.getAppName(), entry.filename); - String relativePath = ODKFileUtils.asRelativePath(sc.getAppName(), localFile); + String relativePath = ODKFileUtils.asRelativePath(sc.getAppName(), DocumentFile.fromFile(localFile)); syncStatus.updateNotification(SyncProgressState.TABLE_FILES, R.string.sync_verifying_local_file,