Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed TransactionTooLargeException in FormDownloadList activity #2799

Merged
merged 23 commits into from Mar 7, 2019
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
3ba2a69
Added FormDownloadListViewModel class
grzesiek2010 Jan 15, 2019
bb4cf66
Moved formNamesAndURLs to FormDownloadListViewModel
grzesiek2010 Jan 15, 2019
8fceb0f
Moved alertTitle to FormDownloadListViewModel
grzesiek2010 Jan 15, 2019
1b54fa7
Moved alertMsg to FormDownloadListViewModel
grzesiek2010 Jan 15, 2019
60af635
Moved alertShowing to FormDownloadListViewModel
grzesiek2010 Jan 15, 2019
1bc879a
Moved setShouldExit to FormDownloadListViewModel
grzesiek2010 Jan 15, 2019
b20510b
Moved formList to FormDownloadListViewModel
grzesiek2010 Jan 15, 2019
4bc6167
Moved selectedForms to FormDownloadListViewModel
grzesiek2010 Jan 15, 2019
60820bb
Moved isDownloadOnlyMode to FormDownloadListViewModel
grzesiek2010 Jan 15, 2019
801a75d
Moved formResult to FormDownloadListViewModel
grzesiek2010 Jan 15, 2019
9354cdf
Moved password to FormDownloadListViewModel
grzesiek2010 Jan 15, 2019
0628009
Moved username to FormDownloadListViewModel
grzesiek2010 Jan 15, 2019
c9a8074
Moved url to FormDownloadListViewModel
grzesiek2010 Jan 15, 2019
9ebeca8
Moved formIdsToDownload to FormDownloadListViewModel
grzesiek2010 Jan 15, 2019
3999257
Moved formsFound to FormDownloadListViewModel
grzesiek2010 Jan 15, 2019
df90b4a
Removed unused import and method
grzesiek2010 Jan 15, 2019
c1ec751
Fixed broken code style rules
grzesiek2010 Jan 15, 2019
c883364
Removed unused field
grzesiek2010 Jan 15, 2019
c77c217
Code improvements
grzesiek2010 Jan 15, 2019
a03d573
Refactored the way we create and display dialogs to avoid showing a d…
grzesiek2010 Jan 15, 2019
f5da267
Dialogs should be displayed again after activity recreation if needed
grzesiek2010 Jan 15, 2019
89e6044
Fixed dialogs
grzesiek2010 Mar 5, 2019
7fcfdb7
Code improvements
grzesiek2010 Mar 6, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -17,6 +17,7 @@
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.arch.lifecycle.ViewModelProviders;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
Expand All @@ -36,6 +37,7 @@
import android.widget.ListView;

import org.odk.collect.android.R;
import org.odk.collect.android.activities.view_models.FormDownloadListViewModel;
import org.odk.collect.android.adapters.FormDownloadListAdapter;
import org.odk.collect.android.application.Collect;
import org.odk.collect.android.dao.FormsDao;
Expand Down Expand Up @@ -94,11 +96,6 @@ public class FormDownloadList extends FormListActivity implements FormListDownlo

public static final String DISPLAY_ONLY_UPDATED_FORMS = "displayOnlyUpdatedForms";
private static final String BUNDLE_SELECTED_COUNT = "selectedcount";
private static final String BUNDLE_FORM_MAP = "formmap";
private static final String DIALOG_TITLE = "dialogtitle";
private static final String DIALOG_MSG = "dialogmsg";
private static final String DIALOG_SHOWING = "dialogshowing";
private static final String FORMLIST = "formlist";
private static final String SELECTED_FORMS = "selectedForms";
private static final String IS_DOWNLOAD_ONLY_MODE = "isDownloadOnlyMode";
private static final String FORM_IDS_TO_DOWNLOAD = "formIdsToDownload";
Expand All @@ -115,10 +112,6 @@ public class FormDownloadList extends FormListActivity implements FormListDownlo
public static final String FORM_ID_KEY = "formid";
private static final String FORM_VERSION_KEY = "formversion";

private String alertMsg;
private boolean alertShowing;
private String alertTitle;

private AlertDialog alertDialog;
private ProgressDialog progressDialog;
private ProgressDialog cancelDialog;
Expand All @@ -128,15 +121,11 @@ public class FormDownloadList extends FormListActivity implements FormListDownlo
private DownloadFormsTask downloadFormsTask;
private Button toggleButton;

private HashMap<String, FormDetails> formNamesAndURLs = new HashMap<String, FormDetails>();
private ArrayList<HashMap<String, String>> formList;
private final ArrayList<HashMap<String, String>> filteredFormList = new ArrayList<>();
private LinkedHashSet<String> selectedForms = new LinkedHashSet<>();

private static final boolean EXIT = true;
private static final boolean DO_NOT_EXIT = false;
private boolean shouldExit;
private static final String SHOULD_EXIT = "shouldexit";

private boolean displayOnlyUpdatedForms;

Expand All @@ -149,6 +138,8 @@ public class FormDownloadList extends FormListActivity implements FormListDownlo
private ArrayList<String> formsFound;
private HashMap<String, Boolean> formResult;

private FormDownloadListViewModel viewModel;

@Inject
WebCredentialsUtils webCredentialsUtils;

Expand All @@ -160,6 +151,8 @@ public void onCreate(Bundle savedInstanceState) {
getComponent().inject(this);
setTitle(getString(R.string.get_forms));

viewModel = ViewModelProviders.of(this).get(FormDownloadListViewModel.class);

// This activity is accessed directly externally
new PermissionUtils(this).requestStoragePermissions(new PermissionListener() {
@Override
Expand Down Expand Up @@ -214,7 +207,7 @@ private void init(Bundle savedInstanceState) {
}
}

alertMsg = getString(R.string.please_wait);
viewModel.setAlertMsg(getString(R.string.please_wait));

downloadButton = findViewById(R.id.add_button);
downloadButton.setEnabled(listView.getCheckedItemCount() > 0);
Expand All @@ -234,7 +227,7 @@ public void onClick(View v) {
toggleButtonLabel(toggleButton, listView);
selectedForms.clear();
if (listView.getCheckedItemCount() == listView.getCount()) {
for (HashMap<String, String> map : formList) {
for (HashMap<String, String> map : viewModel.getFormList()) {
selectedForms.add(map.get(FORMDETAIL_KEY));
}
}
Expand All @@ -245,40 +238,20 @@ public void onClick(View v) {
refreshButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
formList.clear();
viewModel.clearFormList();
updateAdapter();
clearChoices();
downloadFormList();
}
});

if (savedInstanceState != null) {
// If the screen has rotated, the hashmap with the form ids and urls is passed here.
if (savedInstanceState.containsKey(BUNDLE_FORM_MAP)) {
formNamesAndURLs =
(HashMap<String, FormDetails>) savedInstanceState
.getSerializable(BUNDLE_FORM_MAP);
}

// how many items we've selected
// Android should keep track of this, but broken on rotate...
if (savedInstanceState.containsKey(BUNDLE_SELECTED_COUNT)) {
downloadButton.setEnabled(savedInstanceState.getInt(BUNDLE_SELECTED_COUNT) > 0);
}

// to restore alert dialog.
if (savedInstanceState.containsKey(DIALOG_TITLE)) {
alertTitle = savedInstanceState.getString(DIALOG_TITLE);
}
if (savedInstanceState.containsKey(DIALOG_MSG)) {
alertMsg = savedInstanceState.getString(DIALOG_MSG);
}
if (savedInstanceState.containsKey(DIALOG_SHOWING)) {
alertShowing = savedInstanceState.getBoolean(DIALOG_SHOWING);
}
if (savedInstanceState.containsKey(SHOULD_EXIT)) {
shouldExit = savedInstanceState.getBoolean(SHOULD_EXIT);
}
if (savedInstanceState.containsKey(SELECTED_FORMS)) {
selectedForms = (LinkedHashSet<String>) savedInstanceState.getSerializable(SELECTED_FORMS);
}
Expand All @@ -298,15 +271,7 @@ public void onClick(View v) {
}
}

if (savedInstanceState != null && savedInstanceState.containsKey(FORMLIST)) {
formList =
(ArrayList<HashMap<String, String>>) savedInstanceState.getSerializable(
FORMLIST);
} else {
formList = new ArrayList<HashMap<String, String>>();
}

filteredFormList.addAll(formList);
filteredFormList.addAll(viewModel.getFormList());

if (getLastCustomNonConfigurationInstance() instanceof DownloadFormListTask) {
downloadFormListTask = (DownloadFormListTask) getLastCustomNonConfigurationInstance();
Expand All @@ -328,7 +293,7 @@ public void onClick(View v) {
}
downloadFormsTask = null;
}
} else if (formNamesAndURLs.isEmpty() && getLastCustomNonConfigurationInstance() == null) {
} else if (viewModel.getFormNamesAndURLs().isEmpty() && getLastCustomNonConfigurationInstance() == null) {
// first time, so get the formlist
downloadFormList();
}
Expand Down Expand Up @@ -374,8 +339,7 @@ private void downloadFormList() {
finish();
}
} else {

formNamesAndURLs = new HashMap<String, FormDetails>();
viewModel.clearFormNamesAndURLs();
if (progressDialog != null) {
// This is needed because onPrepareDialog() is broken in 1.6.
progressDialog.setMessage(getString(R.string.please_wait));
Expand Down Expand Up @@ -414,12 +378,6 @@ protected void onRestoreInstanceState(Bundle state) {
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt(BUNDLE_SELECTED_COUNT, listView.getCheckedItemCount());
outState.putSerializable(BUNDLE_FORM_MAP, formNamesAndURLs);
outState.putString(DIALOG_TITLE, alertTitle);
outState.putString(DIALOG_MSG, alertMsg);
outState.putBoolean(DIALOG_SHOWING, alertShowing);
outState.putBoolean(SHOULD_EXIT, shouldExit);
outState.putSerializable(FORMLIST, formList);
outState.putSerializable(SELECTED_FORMS, selectedForms);

// Download mode variables
Expand Down Expand Up @@ -469,14 +427,14 @@ public void onClick(DialogInterface dialog, int which) {
}
};
progressDialog.setTitle(getString(R.string.downloading_data));
progressDialog.setMessage(alertMsg);
progressDialog.setMessage(viewModel.getAlertMsg());
progressDialog.setIcon(android.R.drawable.ic_dialog_info);
progressDialog.setIndeterminate(true);
progressDialog.setCancelable(false);
progressDialog.setButton(getString(R.string.cancel), loadingButtonListener);
return progressDialog;
case AUTH_DIALOG:
alertShowing = false;
viewModel.setAlertShowing(false);

AuthDialogUtility authDialogUtility = new AuthDialogUtility();
if (url != null && username != null && password != null) {
Expand Down Expand Up @@ -507,20 +465,20 @@ protected void updateAdapter() {
CharSequence charSequence = getFilterText();
filteredFormList.clear();
if (charSequence.length() > 0) {
for (HashMap<String, String> form : formList) {
for (HashMap<String, String> form : viewModel.getFormList()) {
if (form.get(FORMNAME).toLowerCase(Locale.US).contains(charSequence.toString().toLowerCase(Locale.US))) {
filteredFormList.add(form);
}
}
} else {
filteredFormList.addAll(formList);
filteredFormList.addAll(viewModel.getFormList());
}
sortList();
if (listView.getAdapter() == null) {
listView.setAdapter(new FormDownloadListAdapter(this, filteredFormList, formNamesAndURLs));
listView.setAdapter(new FormDownloadListAdapter(this, filteredFormList, viewModel.getFormNamesAndURLs()));
} else {
FormDownloadListAdapter formDownloadListAdapter = (FormDownloadListAdapter) listView.getAdapter();
formDownloadListAdapter.setFromIdsToDetails(formNamesAndURLs);
formDownloadListAdapter.setFromIdsToDetails(viewModel.getFormNamesAndURLs());
formDownloadListAdapter.notifyDataSetChanged();
}
toggleButton.setEnabled(!filteredFormList.isEmpty());
Expand Down Expand Up @@ -564,7 +522,7 @@ private void downloadSelectedFiles() {
if (sba.get(i, false)) {
HashMap<String, String> item =
(HashMap<String, String>) listView.getAdapter().getItem(i);
filesToDownload.add(formNamesAndURLs.get(item.get(FORMDETAIL_KEY)));
filesToDownload.add(viewModel.getFormNamesAndURLs().get(item.get(FORMDETAIL_KEY)));
}
}

Expand Down Expand Up @@ -623,8 +581,8 @@ protected void onResume() {
if (downloadFormsTask != null) {
downloadFormsTask.setDownloaderListener(this);
}
if (alertShowing) {
createAlertDialog(alertTitle, alertMsg, shouldExit);
if (viewModel.isAlertShowing()) {
createAlertDialog(viewModel.getAlertTitle(), viewModel.getAlertMsg(), viewModel.shouldExit());
}
super.onResume();
}
Expand All @@ -645,8 +603,8 @@ public boolean isLocalFormSuperseded(String formId) {

try (Cursor formCursor = new FormsDao().getFormsCursorForFormId(formId)) {
return formCursor != null && formCursor.getCount() == 0 // form does not already exist locally
|| formNamesAndURLs.get(formId).isNewerFormVersionAvailable() // or a newer version of this form is available
|| formNamesAndURLs.get(formId).areNewerMediaFilesAvailable(); // or newer versions of media files are available
|| viewModel.getFormNamesAndURLs().get(formId).isNewerFormVersionAvailable() // or a newer version of this form is available
|| viewModel.getFormNamesAndURLs().get(formId).areNewerMediaFilesAvailable(); // or newer versions of media files are available
}
}

Expand Down Expand Up @@ -705,14 +663,14 @@ public void formListDownloadingComplete(HashMap<String, FormDetails> result) {
createAlertDialog(dialogTitle, dialogMessage, DO_NOT_EXIT);
} else {
// Everything worked. Clear the list and add the results.
formNamesAndURLs = result;
viewModel.setFormNamesAndURLs(result);

formList.clear();
viewModel.clearFormList();

ArrayList<String> ids = new ArrayList<String>(formNamesAndURLs.keySet());
ArrayList<String> ids = new ArrayList<String>(viewModel.getFormNamesAndURLs().keySet());
for (int i = 0; i < result.size(); i++) {
String formDetailsKey = ids.get(i);
FormDetails details = formNamesAndURLs.get(formDetailsKey);
FormDetails details = viewModel.getFormNamesAndURLs().get(formDetailsKey);

if (!displayOnlyUpdatedForms || (details.isNewerFormVersionAvailable() || details.areNewerMediaFilesAvailable())) {
HashMap<String, String> item = new HashMap<String, String>();
Expand All @@ -725,22 +683,22 @@ public void formListDownloadingComplete(HashMap<String, FormDetails> result) {
item.put(FORM_VERSION_KEY, details.getFormVersion());

// Insert the new form in alphabetical order.
if (formList.isEmpty()) {
formList.add(item);
if (viewModel.getFormList().isEmpty()) {
viewModel.addFormList(item);
} else {
int j;
for (j = 0; j < formList.size(); j++) {
HashMap<String, String> compareMe = formList.get(j);
for (j = 0; j < viewModel.getFormList().size(); j++) {
HashMap<String, String> compareMe = viewModel.getFormList().get(j);
String name = compareMe.get(FORMNAME);
if (name.compareTo(formNamesAndURLs.get(ids.get(i)).getFormName()) > 0) {
if (name.compareTo(viewModel.getFormNamesAndURLs().get(ids.get(i)).getFormName()) > 0) {
break;
}
}
formList.add(j, item);
viewModel.addFormList(j, item);
}
}
}
filteredFormList.addAll(formList);
filteredFormList.addAll(viewModel.getFormList());
updateAdapter();
selectSupersededForms();
downloadButton.setEnabled(listView.getCheckedItemCount() > 0);
Expand All @@ -756,7 +714,7 @@ public void formListDownloadingComplete(HashMap<String, FormDetails> result) {

ArrayList<FormDetails> filesToDownload = new ArrayList<>();

for (FormDetails formDetails: formNamesAndURLs.values()) {
for (FormDetails formDetails: viewModel.getFormNamesAndURLs().values()) {
String formId = formDetails.getFormID();

if (formResult.containsKey(formId)) {
Expand Down Expand Up @@ -792,7 +750,7 @@ public void onClick(DialogInterface dialog, int i) {
switch (i) {
case DialogInterface.BUTTON_POSITIVE: // ok
// just close the dialog
alertShowing = false;
viewModel.setAlertShowing(false);
// successful download, so quit
// Also quit if in download_mode only(called by another app/activity just to download)
if (shouldExit || isDownloadOnlyMode) {
Expand All @@ -805,17 +763,17 @@ public void onClick(DialogInterface dialog, int i) {
alertDialog.setCancelable(false);
alertDialog.setButton(getString(R.string.ok), quitListener);
alertDialog.setIcon(android.R.drawable.ic_dialog_info);
alertMsg = message;
alertTitle = title;
alertShowing = true;
this.shouldExit = shouldExit;
viewModel.setAlertMsg(message);
viewModel.setAlertTitle(title);
viewModel.setAlertShowing(true);
viewModel.setShouldExit(shouldExit);
DialogUtils.showDialog(alertDialog, this);
}

@Override
public void progressUpdate(String currentFile, int progress, int total) {
alertMsg = getString(R.string.fetching_file, currentFile, String.valueOf(progress), String.valueOf(total));
progressDialog.setMessage(alertMsg);
viewModel.setAlertMsg(getString(R.string.fetching_file, currentFile, String.valueOf(progress), String.valueOf(total)));
progressDialog.setMessage(viewModel.getAlertMsg());
}

@Override
Expand Down