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

Log filter times during form entry #6573

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package org.odk.collect.androidshared.ui

import android.app.Activity
import android.app.Application
import android.content.Context
import android.os.Build
import android.view.Gravity
import android.view.ViewGroup
Expand All @@ -21,30 +20,31 @@ object ToastUtils {
private var recordedToasts = mutableListOf<String>()

private lateinit var lastToast: Toast
private lateinit var application: Application

@JvmStatic
fun showShortToast(context: Context, message: String) {
showToast(context.applicationContext as Application, message)
fun showShortToast(message: String) {
showToast(application, message)
}

@JvmStatic
fun showShortToast(context: Context, messageResource: Int) {
fun showShortToast(messageResource: Int) {
showToast(
context.applicationContext as Application,
context.getLocalizedString(messageResource)
application,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can simplify this class even more by not passing the application param between showToast functions and just using it directly where Toast.makeText is called.

application.getLocalizedString(messageResource)
)
}

@JvmStatic
fun showLongToast(context: Context, message: String) {
showToast(context.applicationContext as Application, message, Toast.LENGTH_LONG)
fun showLongToast(message: String) {
showToast(application, message, Toast.LENGTH_LONG)
}

@JvmStatic
fun showLongToast(context: Context, messageResource: Int) {
fun showLongToast(messageResource: Int) {
showToast(
context.applicationContext as Application,
context.getLocalizedString(messageResource),
application,
application.getLocalizedString(messageResource),
Toast.LENGTH_LONG
)
}
Expand All @@ -63,13 +63,18 @@ object ToastUtils {
return copy
}

@JvmStatic
fun setApplication(application: Application) {
this.application = application
}

private fun showToast(
context: Application,
application: Application,
message: String,
duration: Int = Toast.LENGTH_SHORT
) {
hideLastToast()
lastToast = Toast.makeText(context, message, duration)
lastToast = Toast.makeText(application, message, duration)
lastToast.show()

if (recordToasts) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ public void onItemClick(AdapterView<?> parent, View view, int position, long id)
*/
private void downloadFormList() {
if (!connectivityProvider.isDeviceOnline()) {
ToastUtils.showShortToast(this, org.odk.collect.strings.R.string.no_connection);
ToastUtils.showShortToast(org.odk.collect.strings.R.string.no_connection);

if (viewModel.isDownloadOnlyMode()) {
setReturnResult(false, getString(org.odk.collect.strings.R.string.no_connection), viewModel.getFormResults());
Expand Down Expand Up @@ -408,7 +408,7 @@ private void startFormsDownload(@NonNull ArrayList<ServerFormDetails> filesToDow

downloadFormsTask.execute(filesToDownload);
} else {
ToastUtils.showShortToast(this, org.odk.collect.strings.R.string.noselect_error);
ToastUtils.showShortToast(org.odk.collect.strings.R.string.noselect_error);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -865,7 +865,7 @@ protected void onActivityResult(int requestCode, int resultCode, final Intent in
if (intent == null && requestCode != RequestCodes.DRAW_IMAGE && requestCode != RequestCodes.ANNOTATE_IMAGE
&& requestCode != RequestCodes.SIGNATURE_CAPTURE && requestCode != RequestCodes.IMAGE_CAPTURE) {
Timber.d("The intent has a null value for requestCode: %s", requestCode);
showLongToast(this, getString(org.odk.collect.strings.R.string.null_intent_value));
showLongToast(getString(org.odk.collect.strings.R.string.null_intent_value));
return;
}

Expand Down Expand Up @@ -978,7 +978,7 @@ public void setWidgetData(Object data) {
waitingForDataRegistry.cancelWaitingForData();
} catch (Exception e) {
Timber.e(e);
ToastUtils.showLongToast(this, currentViewIfODKView.getContext().getString(org.odk.collect.strings.R.string.error_attaching_binary_file,
ToastUtils.showLongToast(currentViewIfODKView.getContext().getString(org.odk.collect.strings.R.string.error_attaching_binary_file,
e.getMessage()));
}
set = true;
Expand Down Expand Up @@ -1552,7 +1552,7 @@ public boolean saveForm(boolean exit, boolean complete, String updatedSaveName,
// save current answer
if (current) {
if (!formEntryViewModel.updateAnswersForScreen(getAnswers(), complete)) {
showShortToast(this, org.odk.collect.strings.R.string.data_saved_error);
showShortToast(org.odk.collect.strings.R.string.data_saved_error);
return false;
}
}
Expand Down Expand Up @@ -1584,7 +1584,7 @@ private void handleSaveResult(FormSaveViewModel.SaveResult result) {
if (result.getRequest().viewExiting()) {
finishAndReturnInstance();
} else {
showShortToast(this, org.odk.collect.strings.R.string.data_saved_ok);
showShortToast(org.odk.collect.strings.R.string.data_saved_ok);
}

formSessionRepository.update(sessionId, formSaveViewModel.getInstance());
Expand All @@ -1604,15 +1604,15 @@ private void handleSaveResult(FormSaveViewModel.SaveResult result) {
message = getString(org.odk.collect.strings.R.string.data_saved_error);
}

showLongToast(this, message);
showLongToast(message);
formSaveViewModel.resumeFormEntry();
break;

case FINALIZE_ERROR:
DialogFragmentUtils.dismissDialog(SaveFormProgressDialogFragment.class, getSupportFragmentManager());
DialogFragmentUtils.dismissDialog(ChangesReasonPromptDialogFragment.class, getSupportFragmentManager());

showLongToast(this, String.format(getString(org.odk.collect.strings.R.string.encryption_error_message),
showLongToast(String.format(getString(org.odk.collect.strings.R.string.encryption_error_message),
result.getMessage()));
finishAndReturnInstance();
formSaveViewModel.resumeFormEntry();
Expand Down Expand Up @@ -1954,7 +1954,7 @@ public void loadingComplete(FormLoaderTask task, FormDef formDef, String warning
boolean hasUsedSavepoint = task.hasUsedSavepoint();

if (hasUsedSavepoint) {
runOnUiThread(() -> showLongToast(this, org.odk.collect.strings.R.string.savepoint_used));
runOnUiThread(() -> showLongToast(org.odk.collect.strings.R.string.savepoint_used));
}

if (formController.getInstanceFile() == null) {
Expand Down Expand Up @@ -1992,7 +1992,7 @@ && new PlayServicesChecker().isGooglePlayServicesAvailable(this)) {
formEntryViewModel.refresh();

if (warningMsg != null) {
showLongToast(this, warningMsg);
showLongToast(warningMsg);
Timber.w(warningMsg);
}
}
Expand Down Expand Up @@ -2050,7 +2050,7 @@ && new PlayServicesChecker().isGooglePlayServicesAvailable(this)) {
}
} else {
Timber.e(new Error("FormController is null"));
showLongToast(this, org.odk.collect.strings.R.string.loading_form_failed);
showLongToast(org.odk.collect.strings.R.string.loading_form_failed);
exit();
}
}
Expand Down Expand Up @@ -2129,14 +2129,14 @@ public void advance() {
@Override
public void onSavePointError(String errorMessage) {
if (errorMessage != null && errorMessage.trim().length() > 0) {
showLongToast(this, getString(org.odk.collect.strings.R.string.save_point_error, errorMessage));
showLongToast(getString(org.odk.collect.strings.R.string.save_point_error, errorMessage));
}
}

@Override
public void onSaveFormIndexError(String errorMessage) {
if (errorMessage != null && errorMessage.trim().length() > 0) {
showLongToast(this, getString(org.odk.collect.strings.R.string.save_point_error, errorMessage));
showLongToast(getString(org.odk.collect.strings.R.string.save_point_error, errorMessage));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import org.odk.collect.android.application.Collect
import org.odk.collect.android.application.initialization.upgrade.UpgradeInitializer
import org.odk.collect.android.entities.EntitiesRepositoryProvider
import org.odk.collect.android.projects.ProjectsDataService
import org.odk.collect.androidshared.ui.ToastUtils
import org.odk.collect.metadata.PropertyManager
import org.odk.collect.projects.ProjectsRepository
import org.odk.collect.settings.SettingsProvider
Expand Down Expand Up @@ -49,6 +50,7 @@ class ApplicationInitializer(
}

private fun initializeFrameworks() {
ToastUtils.setApplication(context)
initializeLogging()
AppInitializer.getInstance(context).initializeComponent(JodaTimeInitializer::class.java)
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@ class QRCodeMenuProvider internal constructor(
photoPickerIntent.type = "image/*"
intentLauncher.launchForResult(activity, photoPickerIntent, SELECT_PHOTO) {
showShortToast(
activity,
activity.getString(
org.odk.collect.strings.R.string.activity_not_found,
activity.getString(org.odk.collect.strings.R.string.choose_image)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@ class QRCodeScannerFragment : BarCodeScannerFragment() {
}

showLongToast(
requireContext(),
getString(org.odk.collect.strings.R.string.successfully_imported_settings)
)
ActivityUtils.startActivityAndCloseAllOthers(
Expand All @@ -66,14 +65,12 @@ class QRCodeScannerFragment : BarCodeScannerFragment() {
}

SettingsImportingResult.INVALID_SETTINGS -> showLongToast(
requireContext(),
getString(
org.odk.collect.strings.R.string.invalid_qrcode
)
)

SettingsImportingResult.GD_PROJECT -> showLongToast(
requireContext(),
getString(org.odk.collect.strings.R.string.settings_with_gd_protocol)
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -471,11 +471,11 @@ private void addIntentLaunchButton(Context context, FormEntryPrompt[] questionPr
} catch (ExternalParamsException e) {
Timber.e(e, "ExternalParamsException");

ToastUtils.showShortToast(getContext(), e.getMessage());
ToastUtils.showShortToast(e.getMessage());
} catch (ActivityNotFoundException e) {
Timber.d(e, "ActivityNotFoundExcept");

ToastUtils.showShortToast(getContext(), errorString);
ToastUtils.showShortToast(errorString);
}
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,11 +89,11 @@ class BlankFormListMenuProvider(
if (networkStateProvider?.isDeviceOnline == true) {
viewModel.syncWithServer().observe(activity) { success: Boolean ->
if (success) {
ToastUtils.showShortToast(activity, org.odk.collect.strings.R.string.form_update_succeeded)
ToastUtils.showShortToast(org.odk.collect.strings.R.string.form_update_succeeded)
}
}
} else {
ToastUtils.showShortToast(activity, org.odk.collect.strings.R.string.no_connection)
ToastUtils.showShortToast(org.odk.collect.strings.R.string.no_connection)
}
true
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,28 @@
package org.odk.collect.android.formmanagement

import android.os.Handler
import android.os.Looper
import org.javarosa.core.model.FormDef
import org.javarosa.core.model.condition.EvaluationContext
import org.javarosa.core.model.condition.FilterStrategy
import org.javarosa.core.model.instance.DataInstance
import org.javarosa.core.model.instance.TreeReference
import org.javarosa.form.api.FormEntryController
import org.javarosa.form.api.FormEntryModel
import org.javarosa.xpath.expr.XPathExpression
import org.odk.collect.android.application.Collect
import org.odk.collect.android.dynamicpreload.ExternalDataManagerImpl
import org.odk.collect.android.dynamicpreload.handler.ExternalDataHandlerPull
import org.odk.collect.android.tasks.FormLoaderTask.FormEntryControllerFactory
import org.odk.collect.androidshared.ui.ToastUtils
import org.odk.collect.entities.javarosa.filter.LocalEntitiesFilterStrategy
import org.odk.collect.entities.javarosa.filter.PullDataFunctionHandler
import org.odk.collect.entities.javarosa.finalization.EntityFormFinalizationProcessor
import org.odk.collect.entities.storage.EntitiesRepository
import org.odk.collect.settings.keys.ProjectKeys
import org.odk.collect.shared.settings.Settings
import java.io.File
import java.util.function.Supplier

class CollectFormEntryControllerFactory(
private val entitiesRepository: EntitiesRepository,
Expand All @@ -26,9 +36,40 @@ class CollectFormEntryControllerFactory(

return FormEntryController(FormEntryModel(formDef)).also {
val externalDataHandlerPull = ExternalDataHandlerPull(externalDataManager)
it.addFunctionHandler(PullDataFunctionHandler(entitiesRepository, externalDataHandlerPull))
it.addFunctionHandler(
PullDataFunctionHandler(
entitiesRepository,
externalDataHandlerPull
)
)
it.addPostProcessor(EntityFormFinalizationProcessor())

if (settings.getBoolean(ProjectKeys.KEY_DEBUG_FILTERS)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it's convenient for the QA team or us to enable that option every time we install a new version of the app, which might happen quite often. Wouldn't it be better to always use that strategy in debug mode?

it.addFilterStrategy(LoggingFilterStrategy())
}

it.addFilterStrategy(LocalEntitiesFilterStrategy(entitiesRepository))
}
}
}

private class LoggingFilterStrategy : FilterStrategy {
override fun filter(
sourceInstance: DataInstance<*>,
nodeSet: TreeReference,
predicate: XPathExpression,
children: MutableList<TreeReference>,
evaluationContext: EvaluationContext,
next: Supplier<MutableList<TreeReference>>
): MutableList<TreeReference> {
val startTime = System.currentTimeMillis()
val result = next.get()

val filterTime = System.currentTimeMillis() - startTime
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can take advantage of measureTimeMillis function.
It could be like:

val result: MutableList<TreeReference>
val filterTime = measureTimeMillis { result = next.get() }

Handler(Looper.getMainLooper()).post {
ToastUtils.showShortToast("Filter took ${filterTime / 1000.0}s")
}

return result
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ private void startScanning(Bundle savedInstanceState) {
try {
handleScanningResult(barcodeResult);
} catch (IOException | DataFormatException | IllegalArgumentException e) {
ToastUtils.showShortToast(requireContext(), getString(org.odk.collect.strings.R.string.invalid_qrcode));
ToastUtils.showShortToast(getString(org.odk.collect.strings.R.string.invalid_qrcode));
}
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -170,12 +170,12 @@ public void onCreate(Bundle savedInstanceState) {

public void onUploadButtonsClicked() {
if (!connectivityProvider.isDeviceOnline()) {
ToastUtils.showShortToast(this, org.odk.collect.strings.R.string.no_connection);
ToastUtils.showShortToast(org.odk.collect.strings.R.string.no_connection);
return;
}

if (autoSendOngoing) {
ToastUtils.showShortToast(this, org.odk.collect.strings.R.string.send_in_progress);
ToastUtils.showShortToast(org.odk.collect.strings.R.string.send_in_progress);
return;
}

Expand All @@ -187,7 +187,7 @@ public void onUploadButtonsClicked() {
multiSelectViewModel.unselectAll();
} else {
// no items selected
ToastUtils.showLongToast(this, org.odk.collect.strings.R.string.noselect_error);
ToastUtils.showLongToast(org.odk.collect.strings.R.string.noselect_error);
}
}

Expand Down Expand Up @@ -376,7 +376,7 @@ public void onItemClick(AdapterView<?> parent, View view, int position, long row
Cursor c = (Cursor) listView.getAdapter().getItem(position);
boolean encryptedForm = !Boolean.parseBoolean(c.getString(c.getColumnIndex(DatabaseInstanceColumns.CAN_EDIT_WHEN_COMPLETE)));
if (encryptedForm) {
ToastUtils.showLongToast(this, org.odk.collect.strings.R.string.encrypted_form);
ToastUtils.showLongToast(org.odk.collect.strings.R.string.encrypted_form);
} else {
long instanceId = c.getLong(c.getColumnIndex(DatabaseInstanceColumns._ID));
Intent intent = FormFillingIntentFactory.editInstanceIntent(this, projectsDataService.requireCurrentProject().getUuid(), instanceId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ object Defaults {
hashMap[ProjectKeys.KEY_USGS_MAP_STYLE] = "topographic"
hashMap[ProjectKeys.KEY_GOOGLE_MAP_STYLE] = GoogleMap.MAP_TYPE_NORMAL.toString()
hashMap[ProjectKeys.KEY_MAPBOX_MAP_STYLE] = "mapbox://styles/mapbox/streets-v11"
// experimental_preferences.xml
hashMap[ProjectKeys.KEY_DEBUG_FILTERS] = false
return hashMap
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import android.widget.CompoundButton
import androidx.fragment.app.DialogFragment
import androidx.lifecycle.ViewModelProvider
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import org.odk.collect.android.R
import org.odk.collect.android.databinding.AdminPasswordDialogLayoutBinding
import org.odk.collect.android.injection.DaggerUtils
import org.odk.collect.android.preferences.ProjectPreferencesViewModel
Expand Down Expand Up @@ -62,7 +61,6 @@ class AdminPasswordDialogFragment : DialogFragment() {
projectPreferencesViewModel.setStateUnlocked()
} else {
ToastUtils.showShortToast(
requireContext(),
org.odk.collect.strings.R.string.admin_password_incorrect
)
}
Expand Down
Loading