aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJorge Ruesga <jorge@ruesga.com>2013-09-05 02:01:27 +0200
committerJorge Ruesga <jorge@ruesga.com>2013-09-05 02:01:27 +0200
commit208960abcfd19558b985203195a50068288368e8 (patch)
treed28812de1b22df7620df4a069d60bf9dbd14d2ca
parent73d6b66b604fa85767f38c4de961ab05f5eaf967 (diff)
downloadandroid_packages_apps_CMFileManager-cm-10.1.tar.gz
android_packages_apps_CMFileManager-cm-10.1.tar.bz2
android_packages_apps_CMFileManager-cm-10.1.zip
CMFileManager: Check write operationcm-10.1.3cm-10.1
Check that write operation writes exactly the expected bytes to the backend filesystem. Otherway, retry the write operation. Change-Id: I4c2267a76b4190edcc3edba2836124a4651708ea JIRA: CYAN-2129 Issue: https://jira.cyanogenmod.org/browse/CYAN-2129 Signed-off-by: Jorge Ruesga <jorge@ruesga.com>
-rw-r--r--src/com/cyanogenmod/filemanager/activities/EditorActivity.java146
1 files changed, 97 insertions, 49 deletions
diff --git a/src/com/cyanogenmod/filemanager/activities/EditorActivity.java b/src/com/cyanogenmod/filemanager/activities/EditorActivity.java
index d943c4b5..2a6b9d87 100644
--- a/src/com/cyanogenmod/filemanager/activities/EditorActivity.java
+++ b/src/com/cyanogenmod/filemanager/activities/EditorActivity.java
@@ -96,6 +96,8 @@ public class EditorActivity extends Activity implements TextWatcher {
private static boolean DEBUG = false;
+ private static final int WRITE_RETRIES = 3;
+
private final BroadcastReceiver mNotificationReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
@@ -1052,15 +1054,15 @@ public class EditorActivity extends Activity implements TextWatcher {
if (activity.mBinary && hexDump) {
// we do not use the Hexdump helper class, because we need to show the
// progress of the dump process
- this.mReader.mBuffer =
- new SpannableStringBuilder(
- toHexPrintableString(
+ final String data = toHexPrintableString(
toHexDump(
- this.mReader.mByteBuffer.toByteArray())));
+ this.mReader.mByteBuffer.toByteArray()));
+ this.mReader.mBuffer = new SpannableStringBuilder(data);
+ Log.i(TAG, "Bytes read: " + data.getBytes().length); //$NON-NLS-1$
} else {
- this.mReader.mBuffer =
- new SpannableStringBuilder(
- new String(this.mReader.mByteBuffer.toByteArray()));
+ final String data = new String(this.mReader.mByteBuffer.toByteArray());
+ this.mReader.mBuffer = new SpannableStringBuilder(data);
+ Log.i(TAG, "Bytes read: " + data.getBytes().length); //$NON-NLS-1$
}
this.mReader.mByteBuffer = null;
@@ -1246,7 +1248,7 @@ public class EditorActivity extends Activity implements TextWatcher {
null);
// Write the file
- syncWrite();
+ ensureSyncWrite();
} catch (Exception ex) {
ExceptionUtil.translateException(
@@ -1254,7 +1256,7 @@ public class EditorActivity extends Activity implements TextWatcher {
@Override
public void onSuccess() {
// Write the file
- syncWrite();
+ ensureSyncWrite();
}
@Override
@@ -1267,53 +1269,57 @@ public class EditorActivity extends Activity implements TextWatcher {
}
/**
- * Method that write the file.
+ * Method that checks that the write to disk operation was successfully and the
+ * expected bytes are written to disk.
* @hide
*/
- void syncWrite() {
+ void ensureSyncWrite() {
try {
- // Configure the writer
- AsyncWriter writer = new AsyncWriter();
+ for (int i = 0; i < WRITE_RETRIES; i++) {
+ // Configure the writer
+ AsyncWriter writer = new AsyncWriter();
- // Create the writable command
- WriteExecutable cmd =
- CommandHelper.write(this, this.mFso.getFullPath(), writer, null);
+ // Write to disk
+ final byte[] data = this.mEditor.getText().toString().getBytes();
+ long expected = data.length;
+ syncWrite(writer, data);
- // Obtain access to the buffer (IMP! don't close the buffer here, it's manage
- // by the command)
- OutputStream os = cmd.createOutputStream();
- try {
- // Retrieve the text from the editor
- String text = this.mEditor.getText().toString();
- ByteArrayInputStream bais = new ByteArrayInputStream(text.getBytes());
- text = null;
- try {
- // Buffered write
- byte[] data = new byte[this.mBufferSize];
- int read = 0;
- while ((read = bais.read(data, 0, this.mBufferSize)) != -1) {
- os.write(data, 0, read);
+ // Sleep a bit
+ Thread.sleep(150L);
+
+ // Is error?
+ if (writer.mCause != null) {
+ Log.e(TAG, "Write operation failed. Retries: " + i, writer.mCause);
+ if (i == (WRITE_RETRIES-1)) {
+ // Something was wrong. The file probably is corrupted
+ DialogHelper.showToast(
+ this, R.string.msgs_operation_failure, Toast.LENGTH_SHORT);
+ break;
}
- } finally {
- try {
- bais.close();
- } catch (Exception e) {/**NON BLOCK**/}
+
+ // Retry
+ continue;
}
- } finally {
- // Ok. Data is written or ensure buffer close
- cmd.end();
- }
+ // Check that all the bytes were written
+ FileSystemObject fso =
+ CommandHelper.getFileInfo(this, this.mFso.getFullPath(), true, null);
+ if (fso == null || fso.getSize() != expected) {
+ Log.e(TAG, String.format(
+ "Size is not the same. Expected: %d, Written: %d. Retries: %d",
+ expected, fso == null ? -1 : fso.getSize(), i));
+ if (i == (WRITE_RETRIES-1)) {
+ // Something was wrong. The destination data is not the same
+ // as the source data
+ DialogHelper.showToast(
+ this, R.string.msgs_operation_failure, Toast.LENGTH_SHORT);
+ break;
+ }
- // Sleep a bit
- Thread.sleep(150L);
+ // Retry
+ continue;
+ }
- // Is error?
- if (writer.mCause != null) {
- // Something was wrong. The file probably is corrupted
- DialogHelper.showToast(
- this, R.string.msgs_operation_failure, Toast.LENGTH_SHORT);
- } else {
// Success. The file was saved
DialogHelper.showToast(
this, R.string.editor_successfully_saved, Toast.LENGTH_SHORT);
@@ -1324,13 +1330,55 @@ public class EditorActivity extends Activity implements TextWatcher {
intent.putExtra(
FileManagerSettings.EXTRA_FILE_CHANGED_KEY, this.mFso.getFullPath());
sendBroadcast(intent);
- }
- } catch (Exception e) {
+ // Done
+ break;
+
+ }
+ } catch (Exception ex) {
// Something was wrong, but the file was NOT written
+ Log.e(TAG, "The file wasn't written.", ex);
DialogHelper.showToast(
this, R.string.msgs_operation_failure, Toast.LENGTH_SHORT);
- return;
+ }
+ }
+
+ /**
+ * Method that write the file.
+ *
+ * @param writer The command listener
+ * @param bytes The bytes to write
+ * @throws Exception If something was wrong
+ */
+ private void syncWrite(AsyncWriter writer, byte[] bytes) throws Exception {
+ // Create the writable command
+ WriteExecutable cmd =
+ CommandHelper.write(this, this.mFso.getFullPath(), writer, null);
+
+ // Obtain access to the buffer (IMP! don't close the buffer here, it's manage
+ // by the command)
+ OutputStream os = cmd.createOutputStream();
+ try {
+ // Retrieve the text from the editor
+ ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
+ try {
+ // Buffered write
+ byte[] data = new byte[this.mBufferSize];
+ int read = 0, written = 0;
+ while ((read = bais.read(data, 0, this.mBufferSize)) != -1) {
+ os.write(data, 0, read);
+ written += read;
+ }
+ Log.i(TAG, "Bytes written: " + written); //$NON-NLS-1$
+ } finally {
+ try {
+ bais.close();
+ } catch (Exception e) {/**NON BLOCK**/}
+ }
+
+ } finally {
+ // Ok. Data is written or ensure buffer close
+ cmd.end();
}
}