/* * Copyright (c) 2014. The Trustees of Indiana University. * * This version of the code is licensed under the MPL 2.0 Open Source license with additional * healthcare disclaimer. If the user is an entity intending to commercialize any application * that uses this code in a for-profit venture, please contact the copyright holder. */ package com.muzima.service; import android.app.IntentService; import android.app.NotificationManager; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; import android.support.v4.app.NotificationCompat; import android.support.v4.content.LocalBroadcastManager; import android.util.Log; import com.muzima.MuzimaApplication; import com.muzima.R; import com.muzima.api.model.APIName; import com.muzima.api.model.LastSyncTime; import com.muzima.api.model.Patient; import com.muzima.api.service.LastSyncTimeService; import com.muzima.view.BroadcastListenerActivity; import java.io.IOException; import java.util.ArrayList; import java.util.List; import static com.muzima.utils.Constants.DataSyncServiceConstants; import static com.muzima.utils.Constants.DataSyncServiceConstants.SyncStatusConstants; import static com.muzima.utils.Constants.NotificationStatusConstants; import static java.util.Arrays.asList; public class DataSyncService extends IntentService { private static final int MUZIMA_NOTIFICATION = 0; private static final String TAG = "DataSyncService"; private String notificationServiceRunning; private String notificationServiceFinished; private String notificationMsg; private MuzimaSyncService muzimaSyncService; public DataSyncService() { super("DataSyncService"); } @Override public void onCreate() { super.onCreate(); notificationServiceRunning = getString(R.string.info_muzima_sync_service_in_progress); notificationServiceFinished = getString(R.string.info_muzima_sync_service_finish); muzimaSyncService = ((MuzimaApplication) getApplication()).getMuzimaSyncService(); updateNotificationMsg(notificationServiceRunning); } @Override protected void onHandleIntent(Intent intent) { int syncType = intent.getIntExtra(DataSyncServiceConstants.SYNC_TYPE, -1); Intent broadcastIntent = new Intent(); String[] credentials = intent.getStringArrayExtra(DataSyncServiceConstants.CREDENTIALS); broadcastIntent.setAction(BroadcastListenerActivity.MESSAGE_SENT_ACTION); broadcastIntent.putExtra(DataSyncServiceConstants.SYNC_TYPE, syncType); switch (syncType) { case DataSyncServiceConstants.SYNC_FORMS: updateNotificationMsg(getString(R.string.info_form_metadata_download)); if (authenticationSuccessful(credentials, broadcastIntent)) { int[] result = muzimaSyncService.downloadForms(); String msg = getString(R.string.info_form_download_delete,result[1], result[2]); prepareBroadcastMsgForDownloadForms(broadcastIntent, result, msg); saveSyncTime(result,APIName.DOWNLOAD_FORMS); } break; case DataSyncServiceConstants.SYNC_TEMPLATES: String[] formIds = intent.getStringArrayExtra(DataSyncServiceConstants.FORM_IDS); updateNotificationMsg(getString(R.string.info_form_template_with_count_download, formIds.length )); if (authenticationSuccessful(credentials, broadcastIntent)) { int[] result = muzimaSyncService.downloadFormTemplatesAndRelatedMetadata(formIds, true); String msg = getString(R.string.info_form_template_concept_download,result[1],result[2]); broadcastIntent.putExtra(DataSyncServiceConstants.DOWNLOAD_COUNT_SECONDARY, result[2]); prepareBroadcastMsg(broadcastIntent, result, msg); } break; case DataSyncServiceConstants.SYNC_COHORTS: updateNotificationMsg(getString(R.string.info_cohort_download)); if (authenticationSuccessful(credentials, broadcastIntent)) { int[] result = muzimaSyncService.downloadCohorts(); String msg = getString(R.string.info_new_cohort_download_delete,result[1],result[2]); prepareBroadcastMsg(broadcastIntent, result, msg); saveSyncTime(result, APIName.DOWNLOAD_COHORTS); consolidateAndSyncIndependentPatients(broadcastIntent); } break; case DataSyncServiceConstants.SYNC_PATIENTS_FULL_DATA: String[] cohortIds = intent.getStringArrayExtra(DataSyncServiceConstants.COHORT_IDS); updateNotificationMsg(getString(R.string.info_patient_download)); if (authenticationSuccessful(credentials, broadcastIntent)) { downloadPatients(broadcastIntent, cohortIds); downloadObservationsAndEncounters(broadcastIntent, cohortIds); } break; case DataSyncServiceConstants.SYNC_PATIENTS_ONLY: String[] cohortIdsToDownload = intent.getStringArrayExtra(DataSyncServiceConstants.COHORT_IDS); updateNotificationMsg(getString(R.string.info_patient_download)); if (authenticationSuccessful(credentials, broadcastIntent)) { downloadPatients(broadcastIntent, cohortIdsToDownload); } break; case DataSyncServiceConstants.SYNC_PATIENTS_DATA_ONLY: String[] savedCohortIds = intent.getStringArrayExtra(DataSyncServiceConstants.COHORT_IDS); updateNotificationMsg(getString(R.string.info_patient_data_download)); if (authenticationSuccessful(credentials, broadcastIntent)) { downloadObservationsAndEncounters(broadcastIntent, savedCohortIds); } break; case DataSyncServiceConstants.SYNC_UPLOAD_FORMS: updateNotificationMsg(getString(R.string.info_form_upload)); if (authenticationSuccessful(credentials, broadcastIntent)) { int[] result = muzimaSyncService.uploadAllCompletedForms(); broadcastIntent.putExtra(DataSyncServiceConstants.SYNC_TYPE, DataSyncServiceConstants.SYNC_UPLOAD_FORMS); prepareBroadcastMsgForFormUpload(broadcastIntent, result, getString(R.string.info_form_upload_success)); } break; case DataSyncServiceConstants.DOWNLOAD_PATIENT_ONLY: String[] patientsToBeDownloaded = intent.getStringArrayExtra(DataSyncServiceConstants.PATIENT_UUID_FOR_DOWNLOAD); if (authenticationSuccessful(credentials, broadcastIntent)) { downloadPatientsWithObsAndEncounters(broadcastIntent, patientsToBeDownloaded); } break; case DataSyncServiceConstants.SYNC_NOTIFICATIONS: String receiverUUid = intent.getStringExtra(NotificationStatusConstants.RECEIVER_UUID); String[] downloadedCohortIds = intent.getStringArrayExtra(DataSyncServiceConstants.COHORT_IDS); updateNotificationMsg(getString(R.string.info_notification_download_in_progress)); if (authenticationSuccessful(credentials, broadcastIntent)) { int[] result = muzimaSyncService.downloadNotifications(receiverUUid); String msg = getString(R.string.info_notification_download,result[1]); prepareBroadcastMsg(broadcastIntent, result, msg); LocalBroadcastManager.getInstance(this).sendBroadcast(broadcastIntent); downloadObservationsAndEncounters(broadcastIntent, downloadedCohortIds); } break; case DataSyncServiceConstants.SYNC_REAL_TIME_UPLOAD_FORMS: updateNotificationMsg(getString(R.string.info_real_time_upload)); if (authenticationSuccessful(credentials, broadcastIntent)) { int[] result = muzimaSyncService.uploadAllCompletedForms(); broadcastIntent.putExtra(DataSyncServiceConstants.SYNC_TYPE, DataSyncServiceConstants.SYNC_REAL_TIME_UPLOAD_FORMS); prepareBroadcastMsgForFormUpload(broadcastIntent, result, getString(R.string.info_real_time_upload_success)); } break; default: break; } LocalBroadcastManager.getInstance(this).sendBroadcast(broadcastIntent); } private void consolidateAndSyncIndependentPatients(Intent broadcastIntent) { muzimaSyncService.consolidatePatients(); List<Patient> patients = muzimaSyncService.updatePatientsNotPartOfCohorts(); List<String> patientUuids = muzimaSyncService.getPatientUuids(patients); downloadPatientsWithObsAndEncounters(broadcastIntent,patientUuids.toArray(new String[patientUuids.size()])); } private void downloadPatientsWithObsAndEncounters(Intent broadcastIntent, String[] patientUUIDs) { if(patientUUIDs.length == 0){ return; } int[] resultForPatients = muzimaSyncService.downloadPatients(patientUUIDs); broadCastMessageForPatients(broadcastIntent, resultForPatients, patientUUIDs); List<String> patientUUIDList = new ArrayList<String>(asList(patientUUIDs)); if (isSuccess(resultForPatients)) { int[] resultForObs = muzimaSyncService.downloadObservationsForPatientsByPatientUUIDs(patientUUIDList, true); broadCastMessageForObservationDownload(broadcastIntent, resultForObs); int[] resultForEncounters = muzimaSyncService.downloadEncountersForPatientsByPatientUUIDs(patientUUIDList, true); broadCastMessageForEncounters(broadcastIntent, resultForEncounters); } } private void downloadObservationsAndEncounters(Intent broadcastIntent, String[] savedCohortIds) { int[] resultForObservations = muzimaSyncService.downloadObservationsForPatientsByCohortUUIDs(savedCohortIds, true); broadCastMessageForObservationDownload(broadcastIntent, resultForObservations); int[] resultForEncounters = muzimaSyncService.downloadEncountersForPatientsByCohortUUIDs(savedCohortIds, true); broadCastMessageForEncounters(broadcastIntent, resultForEncounters); } private void downloadPatients(Intent broadcastIntent, String[] cohortIds) { int[] resultForPatients = muzimaSyncService.downloadPatientsForCohorts(cohortIds); broadCastMessageForPatients(broadcastIntent, resultForPatients); } private void broadCastMessageForEncounters(Intent broadcastIntent, int[] resultForEncounters) { String msgForEncounters = getString(R.string.info_new_encounter_download_delete,resultForEncounters[1] ,resultForEncounters[2]); prepareBroadcastMsg(broadcastIntent, resultForEncounters, msgForEncounters); broadcastIntent.putExtra(DataSyncServiceConstants.SYNC_TYPE, DataSyncServiceConstants.SYNC_ENCOUNTERS); LocalBroadcastManager.getInstance(this).sendBroadcast(broadcastIntent); } private void broadCastMessageForObservationDownload(Intent broadcastIntent, int[] resultForObservations) { String msgForObservations = getString(R.string.info_new_observation_download_delete,resultForObservations[1] , resultForObservations[2]); prepareBroadcastMsg(broadcastIntent, resultForObservations, msgForObservations); broadcastIntent.putExtra(DataSyncServiceConstants.SYNC_TYPE, DataSyncServiceConstants.SYNC_OBSERVATIONS); LocalBroadcastManager.getInstance(this).sendBroadcast(broadcastIntent); } private void broadCastMessageForPatients(Intent broadcastIntent, int[] resultForPatients) { String msgForPatients = getString(R.string.info_new_patient_download,resultForPatients[1]); prepareBroadcastMsg(broadcastIntent, resultForPatients, msgForPatients); if (isSuccess(resultForPatients) && resultForPatients.length > 1) { broadcastIntent.putExtra(DataSyncServiceConstants.DOWNLOAD_COUNT_SECONDARY, resultForPatients[1]); } LocalBroadcastManager.getInstance(this).sendBroadcast(broadcastIntent); } private void broadCastMessageForPatients(Intent broadcastIntent, int[] resultForPatients, String[] patientUUIDs) { String msgForPatients = getString(R.string.info_new_patient_download,resultForPatients[1]); prepareBroadcastMsg(broadcastIntent, resultForPatients, msgForPatients); if (isSuccess(resultForPatients) && resultForPatients.length > 1) { broadcastIntent.putExtra(DataSyncServiceConstants.DOWNLOAD_COUNT_SECONDARY, resultForPatients[1]); broadcastIntent.putExtra(DataSyncServiceConstants.PATIENT_UUID_FOR_DOWNLOAD, patientUUIDs); } LocalBroadcastManager.getInstance(this).sendBroadcast(broadcastIntent); } private void prepareBroadcastMsg(Intent broadcastIntent, int[] result, String msg) { broadcastIntent.putExtra(DataSyncServiceConstants.SYNC_STATUS, result[0]); if (isSuccess(result)) { broadcastIntent.putExtra(DataSyncServiceConstants.DOWNLOAD_COUNT_PRIMARY, result[1]); updateNotificationMsg(msg); } } private void prepareBroadcastMsgForDownloadForms(Intent broadcastIntent, int[] result, String msg) { broadcastIntent.putExtra(DataSyncServiceConstants.SYNC_STATUS, result[0]); if (isSuccess(result)) { broadcastIntent.putExtra(DataSyncServiceConstants.DOWNLOAD_COUNT_PRIMARY, result[1]); broadcastIntent.putExtra(DataSyncServiceConstants.DELETED_COUNT_PRIMARY,result[2]); updateNotificationMsg(msg); } } private boolean isSuccess(int[] result) { return result[0] == SyncStatusConstants.SUCCESS; } private void prepareBroadcastMsgForFormUpload(Intent broadcastIntent, int[] result, String msg) { broadcastIntent.putExtra(DataSyncServiceConstants.SYNC_STATUS, result[0]); if (isSuccess(result)) { updateNotificationMsg(msg); } } private void saveSyncTime(int[] result, APIName apiName) { if (isSuccess(result)) { LastSyncTimeService lastSyncTimeService = null; try { lastSyncTimeService = ((MuzimaApplication) getApplication()).getMuzimaContext().getLastSyncTimeService(); SntpService sntpService = ((MuzimaApplication)getApplicationContext()).getSntpService(); LastSyncTime lastSyncTime = new LastSyncTime(apiName, sntpService.getLocalTime()); lastSyncTimeService.saveLastSyncTime(lastSyncTime); } catch (IOException e) { Log.i(TAG, "Error setting last sync time."); } } } private boolean authenticationSuccessful(String[] credentials, Intent broadcastIntent) { int authenticationStatus = muzimaSyncService.authenticate(credentials); if (authenticationStatus != SyncStatusConstants.AUTHENTICATION_SUCCESS) { broadcastIntent.putExtra(DataSyncServiceConstants.SYNC_STATUS, authenticationStatus); return false; } return true; } @Override public void onDestroy() { showNotification(notificationServiceFinished, notificationMsg); super.onDestroy(); } private void showNotification(String title, String msg) { NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this) .setContentIntent(PendingIntent.getActivity(this, 0, new Intent(), 0)) .setSmallIcon(R.drawable.ic_launcher_logo) .setContentTitle(title) .setContentText(msg); NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); mNotificationManager.notify(MUZIMA_NOTIFICATION, mBuilder.getNotification()); } private void updateNotificationMsg(String msg) { notificationMsg = msg; showNotification(notificationServiceRunning, notificationMsg); } }