package org.commcare.activities.components; import android.content.Intent; import android.os.Bundle; import android.util.Log; import org.commcare.activities.CommCareActivity; import org.commcare.views.UserfacingErrorHandling; import org.javarosa.core.util.externalizable.DeserializationException; import org.javarosa.core.util.externalizable.PrototypeFactory; import org.javarosa.form.api.FormEntrySession; import org.javarosa.form.api.FormEntrySessionReplayer; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import static org.commcare.activities.FormEntryActivity.mFormController; /** * Wrapper for the form entry action recorder, allowing for saving and * restoring to the form entry activity. * * @author Phillip Mates (pmates@dimagi.com) */ public class FormEntrySessionWrapper { public static final String KEY_RECORD_FORM_ENTRY_SESSION = "record_form_entry_session"; private static final String TAG = FormEntrySessionWrapper.class.getSimpleName(); public static final String KEY_FORM_ENTRY_SESSION = "form_entry_session"; private FormEntrySession formEntryRestoreSession = null; private boolean recordEntrySession; public void restoreFormEntrySession(Bundle savedInstanceState, PrototypeFactory prototypeFactory) { recordEntrySession = savedInstanceState.getBoolean(KEY_RECORD_FORM_ENTRY_SESSION, false); byte[] serializedObject = savedInstanceState.getByteArray(KEY_FORM_ENTRY_SESSION); if (serializedObject != null) { formEntryRestoreSession = new FormEntrySession(); DataInputStream objectInputStream = new DataInputStream(new ByteArrayInputStream(serializedObject)); try { formEntryRestoreSession.readExternal(objectInputStream, prototypeFactory); } catch (IOException | DeserializationException e) { Log.e(TAG, "failed to deserialize form entry session during saved instance restore"); } finally { try { objectInputStream.close(); } catch (IOException e) { Log.e(TAG, "failed to close deserialization stream for form entry session during saved instance restore"); } } } } public boolean isRecording() { return recordEntrySession; } public void saveFormEntrySession(Bundle outState) { outState.putBoolean(KEY_RECORD_FORM_ENTRY_SESSION, recordEntrySession); if (formEntryRestoreSession != null) { ByteArrayOutputStream objectSerialization = new ByteArrayOutputStream(); try { formEntryRestoreSession.writeExternal(new DataOutputStream(objectSerialization)); outState.putByteArray(FormEntrySessionWrapper.KEY_FORM_ENTRY_SESSION, objectSerialization.toByteArray()); } catch (IOException e) { outState.putByteArray(FormEntrySessionWrapper.KEY_FORM_ENTRY_SESSION, null); } finally { try { objectSerialization.close(); } catch (IOException e) { Log.w(TAG, "failed to store form entry session in instance bundle"); } } } } public void replaySession(CommCareActivity activity) { try { FormEntrySessionReplayer.tryReplayingFormEntry(mFormController.getFormEntryController(), formEntryRestoreSession); formEntryRestoreSession = null; } catch (FormEntrySessionReplayer.ReplayError e) { UserfacingErrorHandling.createErrorDialog(activity, e.getMessage(), FormEntryConstants.EXIT); } } public void loadFromIntent(Intent intent) { if (intent.hasExtra(KEY_FORM_ENTRY_SESSION)) { formEntryRestoreSession = FormEntrySession.fromString(intent.getStringExtra(KEY_FORM_ENTRY_SESSION)); } recordEntrySession = intent.getBooleanExtra(KEY_RECORD_FORM_ENTRY_SESSION, false); } }