Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
6a42266
Analytics for user funneling
jaypanchal-13 Sep 9, 2025
8ec5dc2
Removed yellow cross icon from earned credential screen
jaypanchal-13 Sep 9, 2025
7ae4200
Merge branch 'master' into CCCT-1671-analytic-user-funneling
jaypanchal-13 Sep 10, 2025
74e8ac2
Merge branch 'master' into CCCT-1671-analytic-user-funneling
jaypanchal-13 Sep 11, 2025
4a40b49
Revert "Removed yellow cross icon from earned credential screen"
jaypanchal-13 Sep 11, 2025
4eb7a9f
Merge remote-tracking branch 'origin/CCCT-1671-analytic-user-funnelin…
jaypanchal-13 Sep 11, 2025
c127d9b
Merge branch 'master' into CCCT-1671-analytic-user-funneling
jaypanchal-13 Sep 15, 2025
006f443
Address comments
jaypanchal-13 Sep 15, 2025
51cef50
Merge branch 'master' into CCCT-1671-analytic-user-funneling
jaypanchal-13 Sep 17, 2025
64e76c6
Changed analytics values as per comments
jaypanchal-13 Sep 17, 2025
ada6865
Merge branch 'master' into CCCT-1671-analytic-user-funneling
jaypanchal-13 Sep 18, 2025
fb48892
Merge branch 'master' into CCCT-1671-analytic-user-funneling
jaypanchal-13 Sep 18, 2025
f3628e0
Merge remote-tracking branch 'origin/master' into CCCT-1671-analytic-…
jaypanchal-13 Sep 18, 2025
21bf164
Addressed changes
jaypanchal-13 Sep 18, 2025
3e4d144
Merge remote-tracking branch 'refs/remotes/origin/master' into CCCT-1…
jaypanchal-13 Sep 19, 2025
d4250aa
Addressed commit changes
jaypanchal-13 Sep 19, 2025
63c4203
Merge branch 'master' into CCCT-1671-analytic-user-funneling
jaypanchal-13 Sep 24, 2025
0b049ab
Merge branch 'master' into CCCT-1671-analytic-user-funneling
jaypanchal-13 Sep 25, 2025
5be9197
Merge branch 'master' into CCCT-1671-analytic-user-funneling
jaypanchal-13 Sep 25, 2025
ea88ca1
Merge remote-tracking branch 'origin/master' into CCCT-1671-analytic-…
jaypanchal-13 Sep 30, 2025
3969379
comments addressed
jaypanchal-13 Sep 30, 2025
3b4c7bf
Merge branch 'master' into CCCT-1671-analytic-user-funneling
jaypanchal-13 Sep 30, 2025
9d208e6
Merge remote-tracking branch 'origin/master' into CCCT-1671-analytic-…
jaypanchal-13 Oct 1, 2025
6e006af
used 'this'
jaypanchal-13 Oct 1, 2025
7702356
Merge remote-tracking branch 'origin/CCCT-1671-analytic-user-funnelin…
jaypanchal-13 Oct 1, 2025
3f9ff60
Merge branch 'master' into CCCT-1671-analytic-user-funneling
jaypanchal-13 Oct 1, 2025
f8c0306
minor changes
jaypanchal-13 Oct 1, 2025
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 @@ -487,6 +487,12 @@ public int getLearningCompletePercentage() {
return numLearning > 0 ? (100 * getCompletedLearningModules() / numLearning) : 100;
}

public int getDeliveryProgressPercentage() {
Copy link
Contributor

Choose a reason for hiding this comment

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

@OrangeAndGreen can you confirm this logic ?

Copy link
Contributor

Choose a reason for hiding this comment

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

Confirmed, that's consistent with the logic that we use on the delivery progress page for total progress.

Copy link
Contributor

Choose a reason for hiding this comment

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

@jaypanchal-13 seems like we are maintaining this same logic in 2 places, can we also use this method from the other place Dave linked to maintain consistency of logic.

int completed = getCompletedVisits();
int total = getMaxVisits();
return total > 0 ? (100 * completed / total) : 100;
}

public boolean attemptedAssessment() {
return getLearningCompletePercentage() >= 100 && assessments != null && !assessments.isEmpty();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,10 @@ public void setLastAccessed(Date date) {
lastAccessed = date;
}

public String getAppId() {
return appId;
}

public static ConnectLinkedAppRecord fromV9(ConnectLinkedAppRecordV9 oldRecord) {
ConnectLinkedAppRecord newRecord = new ConnectLinkedAppRecord();

Expand Down
26 changes: 20 additions & 6 deletions app/src/org/commcare/connect/ConnectJobHelper.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,6 @@ package org.commcare.connect
import android.content.Context
import android.widget.Toast
import org.commcare.CommCareApplication
import org.commcare.android.database.connect.models.ConnectJobAssessmentRecord
import org.commcare.android.database.connect.models.ConnectJobDeliveryRecord
import org.commcare.android.database.connect.models.ConnectJobLearningRecord
import org.commcare.android.database.connect.models.ConnectJobPaymentRecord
import org.commcare.android.database.connect.models.ConnectJobRecord
import org.commcare.connect.database.ConnectJobUtils
Expand All @@ -14,6 +11,9 @@ import org.commcare.connect.network.connect.ConnectApiHandler
import org.commcare.connect.network.connect.models.DeliveryAppProgressResponseModel
import org.commcare.connect.network.connect.models.LearningAppProgressResponseModel
import org.commcare.connect.network.connectId.PersonalIdApiErrorHandler
import org.commcare.google.services.analytics.AnalyticsParamValue.FINISH_DELIVERY
import org.commcare.google.services.analytics.AnalyticsParamValue.PAID_DELIVERY
import org.commcare.google.services.analytics.AnalyticsParamValue.START_DELIVERY
import org.commcare.google.services.analytics.FirebaseAnalyticsUtil

object ConnectJobHelper {
Expand Down Expand Up @@ -65,7 +65,9 @@ object ConnectJobHelper {
learningAppProgressResponseModel.connectJobLearningRecords.size
job.assessments = learningAppProgressResponseModel.connectJobAssessmentRecords
ConnectJobUtils.updateJobLearnProgress(context, job)
FirebaseAnalyticsUtil.reportCccApiLearnProgress(true)
if (job.passedAssessment()){
FirebaseAnalyticsUtil.reportCccApiLearnProgress(true)
}
listener.connectActivityComplete(true)
}

Expand All @@ -84,24 +86,36 @@ object ConnectJobHelper {
val user = ConnectUserDatabaseUtil.getUser(context)
object : ConnectApiHandler<DeliveryAppProgressResponseModel>() {
override fun onSuccess(deliveryAppProgressResponseModel: DeliveryAppProgressResponseModel) {
val events = mutableSetOf<String?>()

if (deliveryAppProgressResponseModel.updatedJob) {
events.add(START_DELIVERY)
ConnectJobUtils.upsertJob(context, job)
}

if (deliveryAppProgressResponseModel.hasDeliveries) {
if (job.getDeliveryProgressPercentage() == 100) {
events.add(FINISH_DELIVERY)
}
ConnectJobUtils.storeDeliveries(context, job.deliveries, job.jobId, true)
}

if (deliveryAppProgressResponseModel.hasPayment) {
if (job.payments.isNotEmpty()){
events.add(PAID_DELIVERY)
}
ConnectJobUtils.storePayments(context, job.payments, job.jobId, true)
}

FirebaseAnalyticsUtil.reportCccApiDeliveryProgress(true)
events.forEach { event ->
FirebaseAnalyticsUtil.reportCccApiDeliveryProgress(true, event)
}

listener.connectActivityComplete(true)
}

override fun onFailure(errorCode: PersonalIdOrConnectApiErrorCodes, t: Throwable?) {
FirebaseAnalyticsUtil.reportCccApiDeliveryProgress(false)
FirebaseAnalyticsUtil.reportCccApiDeliveryProgress(false,null)
listener.connectActivityComplete(false)
}
}.getDeliveries(context, user, job)
Expand Down
7 changes: 7 additions & 0 deletions app/src/org/commcare/connect/PersonalIdManager.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
package org.commcare.connect;

import static org.commcare.google.services.analytics.AnalyticsParamValue.FAILURE_UNLOCK_FAILED;
import static org.commcare.google.services.analytics.AnalyticsParamValue.FAILURE_USER_DENIED;
import static org.commcare.google.services.analytics.AnalyticsParamValue.SYNC_SUCCESS;

import android.content.Context;
import android.content.Intent;
import android.os.Build;
Expand Down Expand Up @@ -343,6 +347,7 @@ private void showLinkDialog(CommCareActivity<?> activity, ConnectLinkedAppRecord
dialog.setNegativeButton(activity.getString(R.string.login_link_connectid_no), (d, w) -> {
activity.dismissAlertDialog();
ConnectAppDatabaseUtil.storeApp(activity, linkedApp);
FirebaseAnalyticsUtil.reportPersonalIDLinking(linkedApp.getAppId(),FAILURE_USER_DENIED);
callback.connectActivityComplete(false);
});

Expand All @@ -353,10 +358,12 @@ private void unlockAndLinkConnect(CommCareActivity<?> activity, ConnectLinkedApp
unlockConnect(activity, success -> {
if (!success) {
callback.connectActivityComplete(false);
FirebaseAnalyticsUtil.reportPersonalIDLinking(linkedApp.getAppId(),FAILURE_UNLOCK_FAILED);
return;
}

linkedApp.linkToPersonalId(password);
FirebaseAnalyticsUtil.reportPersonalIDLinking(linkedApp.getAppId(),SYNC_SUCCESS);
ConnectAppDatabaseUtil.storeApp(activity, linkedApp);

ConnectUserRecord user = ConnectUserDatabaseUtil.getUser(activity);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import org.commcare.dalvik.R;
import org.commcare.dalvik.databinding.FragmentConnectMessageBinding;

import org.commcare.google.services.analytics.FirebaseAnalyticsUtil;
import org.commcare.utils.FirebaseMessagingUtil;

import java.util.ArrayList;
Expand Down Expand Up @@ -176,6 +177,7 @@ private void sendMessage() {
chat.setMessageRead(success);
adapter.updateMessageReadStatus(chat);
scrollToLatestMessage();
FirebaseAnalyticsUtil.reportPersonalIDMessageSent();
}
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@ private void enableContinueButton(boolean isEnable) {
}

private void handleBackupCodeSubmission() {
FirebaseAnalyticsUtil.reportPersonalIDContinueClicked(this.getClass().getSimpleName(),null);
if (isRecovery) {
confirmBackupCode();
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@
import static org.commcare.android.database.connect.models.PersonalIdSessionData.BIOMETRIC_TYPE;
import static org.commcare.android.database.connect.models.PersonalIdSessionData.PIN;
import static org.commcare.connect.PersonalIdManager.BIOMETRIC_INVALIDATION_KEY;
import static org.commcare.google.services.analytics.AnalyticsParamValue.CONTINUE_WITH_FINGERPRINT;
import static org.commcare.google.services.analytics.AnalyticsParamValue.CONTINUE_WITH_PIN;
import static org.commcare.utils.ViewUtils.showSnackBarWithOk;

/**
Expand Down Expand Up @@ -189,6 +191,7 @@ private void updatePinSection(String buttonText) {
}

private void onFingerprintButtonClicked() {
FirebaseAnalyticsUtil.reportPersonalIDContinueClicked(this.getClass().getSimpleName(),CONTINUE_WITH_FINGERPRINT);
BiometricsHelper.ConfigurationStatus status = BiometricsHelper.checkFingerprintStatus(getActivity(),
biometricManager);

Expand Down Expand Up @@ -237,6 +240,7 @@ private void initiateBiometricAuthentication() {
}

private void onPinButtonClicked() {
FirebaseAnalyticsUtil.reportPersonalIDContinueClicked(this.getClass().getSimpleName(),CONTINUE_WITH_PIN);
BiometricsHelper.ConfigurationStatus status = BiometricsHelper.checkPinStatus(getActivity(),
biometricManager);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import org.commcare.connect.network.connectId.PersonalIdApiErrorHandler;
import org.commcare.connect.network.connectId.PersonalIdApiHandler;
import org.commcare.dalvik.databinding.ScreenPersonalidNameBinding;
import org.commcare.google.services.analytics.FirebaseAnalyticsUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

Expand Down Expand Up @@ -77,6 +78,7 @@ private void enableContinueButton(boolean isEnabled) {
}

private void verifyOrAddName() {
FirebaseAnalyticsUtil.reportPersonalIDContinueClicked(this.getClass().getSimpleName(),null);
clearError();
enableContinueButton(false);
new PersonalIdApiHandler<PersonalIdSessionData>() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@

import static android.app.ProgressDialog.show;
import static com.google.android.play.core.integrity.model.IntegrityDialogResponseCode.DIALOG_SUCCESSFUL;
import static org.commcare.fragments.personalId.PersonalIdPhoneFragmentDirections.*;
import static org.commcare.utils.Permissions.shouldShowPermissionRationale;

public class PersonalIdPhoneFragment extends BasePersonalIdFragment implements CommCareLocationListener {
Expand Down Expand Up @@ -236,6 +235,7 @@ private void displayPhoneNumber(String fullPhoneNumber) {
}

private void onContinueClicked() {
FirebaseAnalyticsUtil.reportPersonalIDContinueClicked(this.getClass().getSimpleName(),null);
enableContinueButton(false);
startConfigurationRequest();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -184,4 +184,11 @@ public class AnalyticsParamValue {
public static final String MIN_BIOMETRIC_HARDWARE_UNAVAILABLE = "min_biometric_hardware_unavailable";
public static final String MIN_BIOMETRIC_NEEDS_UPDATE = "min_biometric_needs_update";
public static final String MIN_BIOMETRIC_PIN_NEEDS_UPDATE = "min_biometric_pin_needs_update";
public static final String START_DELIVERY = "start_delivery";
public static final String FINISH_DELIVERY = "finish_delivery";
public static final String PAID_DELIVERY = "paid_delivery";
public static final String FAILURE_USER_DENIED = "failure_user_denied";
public static final String FAILURE_UNLOCK_FAILED = "failure_unlock_failed";
public static final String CONTINUE_WITH_FINGERPRINT = "continue_with_fingerprint";
public static final String CONTINUE_WITH_PIN = "continue_with_pin";
}
Original file line number Diff line number Diff line change
Expand Up @@ -55,5 +55,8 @@ public class CCAnalyticsEvent {
static final String PERSONAL_ID_CONFIGURATION_FAILURE = "personal_id_configuration_failure";
static final String NAV_DRAWER_OPEN = "nav_drawer_open";
static final String NAV_DRAWER_ITEM_SELECTED = "nav_drawer_item_selected";
static final String PERSONAL_ID_CONTINUE_CLICKED = "personal_id_continue_clicked";
static final String PERSONAL_ID_MESSAGE_SENT = "personal_id_message_sent";
static final String PERSONAL_ID_LINKING = "personal_id_linking";

}
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ public class CCAnalyticsParam {
static final String PARAM_CCC_LAUNCH_APP_TYPE = "ccc_launch_app_type";
static final String PARAM_CCC_APP_NAME = "ccc_app_name";
static final String PARAM_API_SUCCESS = "ccc_api_success";
static final String PARAM_API_SUCCESS_DELIVERY_INFO = "ccc_api_success_delivery_info";
static final String PARAM_API_TOTAL_JOBS = "ccc_api_total_jobs";
static final String PARAM_API_NEW_JOBS = "ccc_api_new_jobs";
public static final String PERSONAL_ID_CONTINUE_CLICKED_INFO = "personal_id_continue_button_clicked_info";

}
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,8 @@

import org.commcare.CommCareApplication;
import org.commcare.DiskUtils;
import org.commcare.android.database.connect.models.ConnectUserRecord;
import org.commcare.android.logging.ReportingUtils;
import org.commcare.connect.PersonalIdManager;
import org.commcare.connect.database.ConnectUserDatabaseUtil;
import org.commcare.dalvik.BuildConfig;
import org.commcare.preferences.MainConfigurablePreferences;
import org.commcare.suite.model.OfflineUserRestore;
Expand All @@ -20,6 +18,7 @@
import org.javarosa.core.services.Logger;

import java.util.Date;
import java.util.Objects;

import androidx.navigation.NavController;
import androidx.navigation.NavDestination;
Expand All @@ -36,6 +35,8 @@
import static org.commcare.google.services.analytics.AnalyticsParamValue.VIDEO_USAGE_OTHER;
import static org.commcare.google.services.analytics.AnalyticsParamValue.VIDEO_USAGE_PARTIAL;

import javax.annotation.Nullable;

/**
* Created by amstone326 on 10/13/17.
*/
Expand Down Expand Up @@ -493,9 +494,12 @@ public static void reportCccApiClaimJob(boolean success) {
reportEvent(CCAnalyticsEvent.CCC_API_CLAIM_JOB, b);
}

public static void reportCccApiDeliveryProgress(boolean success) {
public static void reportCccApiDeliveryProgress(boolean success, @Nullable String deliveryInfo) {
Bundle b = new Bundle();
b.putLong(CCAnalyticsParam.PARAM_API_SUCCESS, success ? 1 : 0);
if (deliveryInfo != null){
b.putString(CCAnalyticsParam.PARAM_API_SUCCESS_DELIVERY_INFO,deliveryInfo);
}
reportEvent(CCAnalyticsEvent.CCC_API_DELIVERY_PROGRESS, b);
}

Expand Down Expand Up @@ -533,6 +537,25 @@ public static void reportLoginClicks() {
reportEvent(CCAnalyticsEvent.LOGIN_CLICK);
}

public static void reportPersonalIDContinueClicked(String screenName,@Nullable String info) {
Bundle params = new Bundle();
params.putString(FirebaseAnalytics.Param.SCREEN_NAME, screenName);
if (info != null) {
params.putString(CCAnalyticsParam.PERSONAL_ID_CONTINUE_CLICKED_INFO,info);
}
reportEvent(CCAnalyticsEvent.PERSONAL_ID_CONTINUE_CLICKED, params);
}
public static void reportPersonalIDMessageSent() {
reportEvent(CCAnalyticsEvent.PERSONAL_ID_MESSAGE_SENT);
}

public static void reportPersonalIDLinking(String appId, String result) {
Bundle bundle = new Bundle();
bundle.putString(CCAnalyticsParam.CC_APP_ID, appId);
bundle.putString(CCAnalyticsParam.RESULT, result);
reportEvent(CCAnalyticsEvent.PERSONAL_ID_LINKING, bundle);
}

// logs screen view events when set to a navigation controller
public static NavController.OnDestinationChangedListener getNavControllerPageChangeLoggingListener() {
return (navController, navDestination, args) -> {
Expand Down
Loading