AdbDeviceFileSystem implements DeviceFileSystem { @NotNull @Override public ListenableFuture<DeviceFileEntry> getEntry(@NotNull String path) { SettableFuture<DeviceFileEntry> resultFuture = SettableFuture.create(); ListenableFuture<DeviceFileEntry> currentDir = getRootDirectory(); getTaskExecutor().addCallback(currentDir, new FutureCallback<DeviceFileEntry>() { @Override public void onSuccess(@Nullable DeviceFileEntry result) { assert result != null; if (StringUtil.isEmpty(path) || StringUtil.equals(path, FileListingService.FILE_SEPARATOR)) { resultFuture.set(result); return; } String[] pathSegments = path.substring(1).split(FileListingService.FILE_SEPARATOR); resolvePathSegments(resultFuture, result, pathSegments, 0); } @Override public void onFailure(@NotNull Throwable t) { resultFuture.setException(t); } }); return resultFuture; } AdbDeviceFileSystem(@NotNull IDevice device, @NotNull Executor edtExecutor, @NotNull Executor taskExecutor);  AdbDeviceFileSystem(AdbDeviceFileSystemService service, IDevice device); @NotNull AdbDeviceCapabilities getCapabilities(); @NotNull AdbFileListing getAdbFileListing(); @NotNull AdbFileOperations getAdbFileOperations(); @NotNull AdbFileTransfer getAdbFileTransfer(); @NotNull @Override String getName(); @NotNull @Override DeviceState getDeviceState(); @NotNull @Override ListenableFuture<DeviceFileEntry> getRootDirectory(); @NotNull @Override ListenableFuture<DeviceFileEntry> getEntry(@NotNull String path); @NotNull ListenableFuture<AdbDeviceFileEntry> resolveMountPoint(@NotNull AdbDeviceFileEntry entry);  }
@Test public void test_FileSystem_GetEntry_Fails_ForInvalidPath() throws Exception { assert myFileSystem != null; assert myMockDevice != null; TestDevices.addNexus7Api23Commands(myMockDevice.getShellCommands()); thrown.expect(ExecutionException.class); thrown.expectCause(IsInstanceOf.instanceOf(IllegalArgumentException.class)); waitForFuture(myFileSystem.getEntry("/data/invalid/path")); }
@Test public void test_FileSystem_UploadLocalFile_Works() throws Exception { assert myFileSystem != null; assert myMockDevice != null; TestDevices.addNexus7Api23Commands(myMockDevice.getShellCommands()); DeviceFileEntry dataEntry = waitForFuture(myFileSystem.getEntry("/data/local/tmp")); Path tempFile = FileUtil.createTempFile("localFile", "tmp").toPath(); Files.write(tempFile, new byte[1024]); AtomicReference<Long> totalBytesRef = new AtomicReference<>(); Void result = waitForFuture(dataEntry.uploadFile(tempFile, new FileTransferProgress() { @Override public void progress(long currentBytes, long totalBytes) { totalBytesRef.set(totalBytes); } @Override public boolean isCancelled() { return false; } })); myCallbackExecutor.submit(EmptyRunnable.getInstance()).get(TIMEOUT_MILLISECONDS, TimeUnit.MILLISECONDS); assertThat(result).isNull(); assertThat(totalBytesRef.get()).isEqualTo(1024); }
@Test public void test_FileSystem_DownloadRemoteFile_Works() throws Exception { assert myFileSystem != null; assert myMockDevice != null; assert myCallbackExecutor != null; TestDevices.addNexus7Api23Commands(myMockDevice.getShellCommands()); DeviceFileEntry deviceEntry = waitForFuture(myFileSystem.getEntry("/default.prop")); myMockDevice.addRemoteFile(deviceEntry.getFullPath(), deviceEntry.getSize()); Path tempFile = FileUtil.createTempFile("localFile", "tmp").toPath(); AtomicReference<Long> totalBytesRef = new AtomicReference<>(); Void result = waitForFuture(deviceEntry.downloadFile(tempFile, new FileTransferProgress() { @Override public void progress(long currentBytes, long totalBytes) { totalBytesRef.set(totalBytes); } @Override public boolean isCancelled() { return false; } })); myCallbackExecutor.submit(EmptyRunnable.getInstance()).get(TIMEOUT_MILLISECONDS, TimeUnit.MILLISECONDS); assertThat(result).isNull(); assertThat(totalBytesRef.get()).isEqualTo(deviceEntry.getSize()); assertThat(Files.exists(tempFile)).isTrue(); assertThat(tempFile.toFile().length()).isEqualTo(deviceEntry.getSize()); }
@Test public void test_FileSystem_UploadSystemFile_ReturnsError() throws Exception { assert myFileSystem != null; assert myMockDevice != null; TestDevices.addEmulatorApi25Commands(myMockDevice.getShellCommands()); myMockDevice.addRemoteRestrictedAccessFile("/system/build.prop", 1_024); DeviceFileEntry dataEntry = waitForFuture(myFileSystem.getEntry("/system")); Path tempFile = FileUtil.createTempFile("localFile", "tmp").toPath(); Files.write(tempFile, new byte[1024]); AtomicReference<Long> totalBytesRef = new AtomicReference<>(); Throwable error = waitForFutureException(dataEntry.uploadFile(tempFile, "build.prop", new FileTransferProgress() { @Override public void progress(long currentBytes, long totalBytes) { totalBytesRef.set(totalBytes); } @Override public boolean isCancelled() { return false; } })); myCallbackExecutor.submit(EmptyRunnable.getInstance()).get(TIMEOUT_MILLISECONDS, TimeUnit.MILLISECONDS); assertThat(error).isNotNull(); assertThat(error).isInstanceOf(AdbShellCommandException.class); assertThat(error.getMessage()).isEqualTo("cp: /system/build.prop: Read-only file system"); }
@Test public void test_FileSystem_DownloadAccessibleSystemFile_Works() throws Exception { assert myFileSystem != null; assert myMockDevice != null; assert myCallbackExecutor != null; TestDevices.addEmulatorApi25Commands(myMockDevice.getShellCommands()); DeviceFileEntry deviceEntry = waitForFuture(myFileSystem.getEntry("/system/build.prop")); myMockDevice.addRemoteFile(deviceEntry.getFullPath(), deviceEntry.getSize()); Path tempFile = FileUtil.createTempFile("localFile", "tmp").toPath(); AtomicReference<Long> totalBytesRef = new AtomicReference<>(); Void result = waitForFuture(deviceEntry.downloadFile(tempFile, new FileTransferProgress() { @Override public void progress(long currentBytes, long totalBytes) { totalBytesRef.set(totalBytes); } @Override public boolean isCancelled() { return false; } })); myCallbackExecutor.submit(EmptyRunnable.getInstance()).get(TIMEOUT_MILLISECONDS, TimeUnit.MILLISECONDS); assertThat(result).isNull(); assertThat(totalBytesRef.get()).isEqualTo(deviceEntry.getSize()); assertThat(Files.exists(tempFile)).isTrue(); assertThat(tempFile.toFile().length()).isEqualTo(deviceEntry.getSize()); }
@Test public void test_FileSystem_DownloadRestrictedSystemFile_RecoversFromPullError() throws Exception { assert myFileSystem != null; assert myMockDevice != null; assert myCallbackExecutor != null; TestDevices.addEmulatorApi25Commands(myMockDevice.getShellCommands()); DeviceFileEntry deviceEntry = waitForFuture(myFileSystem.getEntry("/system/build.prop")); myMockDevice.addRemoteRestrictedAccessFile(deviceEntry.getFullPath(), deviceEntry.getSize()); myMockDevice.addRemoteFile("/data/local/tmp/temp0", deviceEntry.getSize()); Path tempFile = FileUtil.createTempFile("localFile", "tmp").toPath(); AtomicReference<Long> totalBytesRef = new AtomicReference<>(); Void result = waitForFuture(deviceEntry.downloadFile(tempFile, new FileTransferProgress() { @Override public void progress(long currentBytes, long totalBytes) { totalBytesRef.set(totalBytes); } @Override public boolean isCancelled() { return false; } })); myCallbackExecutor.submit(EmptyRunnable.getInstance()).get(TIMEOUT_MILLISECONDS, TimeUnit.MILLISECONDS); assertThat(result).isNull(); assertThat(totalBytesRef.get()).isEqualTo(deviceEntry.getSize()); assertThat(Files.exists(tempFile)).isTrue(); assertThat(tempFile.toFile().length()).isEqualTo(deviceEntry.getSize()); }