/** * Checks and handles the update success and failure scenarios */ function checkUpdateStatus() { var filesToCache = null, downloadCompleted = updateJsonHandler.get("downloadCompleted"), updateInitiatedInPrevSession = updateJsonHandler.get("updateInitiatedInPrevSession"); if (downloadCompleted && updateInitiatedInPrevSession) { var isNewVersion = checkIfVersionUpdated(); if (isNewVersion) { // We get here if the update was successful UpdateInfoBar.showUpdateBar({ type: "success", title: Strings.UPDATE_SUCCESSFUL, description: "" }); } else { // We get here if the update started but failed filesToCache = ['.logs']; //AUTOUPDATE_PRERELEASE UpdateInfoBar.showUpdateBar({ type: "error", title: Strings.UPDATE_FAILED, description: Strings.GO_TO_SITE }); } } else if (downloadCompleted && !updateInitiatedInPrevSession) { // We get here if the download was complete and user selected UpdateLater if (brackets.platform === "mac") { filesToCache = ['.dmg', '.json']; } else if (brackets.platform === "win") { filesToCache = ['.msi', '.json']; } } postMessageToNode(MessageIds.PERFORM_CLEANUP, filesToCache); }
/** * Handles the Cancel button click by user in * Unsaved changes prompt, which would come up if user * has dirty files and he/she clicked UpdateNow */ function dirtyFileSaveCancelled() { UpdateInfoBar.showUpdateBar({ type: "warning", title: Strings.WARNING_TYPE, description: Strings.UPDATE_ON_NEXT_LAUNCH }); }
.fail(function () { UpdateInfoBar.showUpdateBar({ type: "error", title: Strings.INITIALISATION_FAILED, description: "" }); });
/** * Handles the download failure callback from Node * @param {string} message - reason of download failure */ function handleDownloadFailure(message) { console.log("AutoUpdate : Download of latest installer failed in Attempt " + (MAX_DOWNLOAD_ATTEMPTS - downloadAttemptsRemaining) + ".\n Reason : " + message); if (downloadAttemptsRemaining) { // Retry the downloading attemptToDownload(); } else { // Download could not completed, all attempts exhausted enableCheckForUpdateEntry(true); UpdateStatus.cleanUpdateStatus(); var descriptionMessage; if (message === _nodeErrorMessages.DOWNLOAD_ERROR) { descriptionMessage = Strings.DOWNLOAD_ERROR; } UpdateInfoBar.showUpdateBar({ type: "error", title: Strings.DOWNLOAD_FAILED, description: descriptionMessage }); } }
/** * Checks and handles the update success and failure scenarios */ function checkUpdateStatus() { var filesToCache = ['.logs'], downloadCompleted = updateJsonHandler.get("downloadCompleted"), updateInitiatedInPrevSession = updateJsonHandler.get("updateInitiatedInPrevSession"); if (downloadCompleted && updateInitiatedInPrevSession) { var isNewVersion = checkIfVersionUpdated(); updateJsonHandler.reset(); if (isNewVersion) { // We get here if the update was successful UpdateInfoBar.showUpdateBar({ type: "success", title: Strings.UPDATE_SUCCESSFUL, description: "" }); HealthLogger.sendAnalyticsData( autoUpdateEventNames.AUTOUPDATE_INSTALLATION_SUCCESS, "autoUpdate", "install", "complete", "" ); } else { // We get here if the update started but failed checkInstallationStatus(); UpdateInfoBar.showUpdateBar({ type: "error", title: Strings.UPDATE_FAILED, description: Strings.GO_TO_SITE }); } } else if (downloadCompleted && !updateInitiatedInPrevSession) { // We get here if the download was complete and user selected UpdateLater if (brackets.platform === "mac") { filesToCache = ['.dmg', '.json']; } else if (brackets.platform === "win") { filesToCache = ['.msi', '.json']; } } postMessageToNode(MessageIds.PERFORM_CLEANUP, filesToCache); }
/** * Attempts a download of the latest installer, while cleaning up any existing downloaded installers */ function attemptToDownload() { if (checkIfOnline()) { postMessageToNode(MessageIds.PERFORM_CLEANUP, ['.json'], true); } else { UpdateInfoBar.showUpdateBar({ type: "warning", title: Strings.DOWNLOAD_FAILED, description: Strings.INTERNET_UNAVAILABLE }); } }
/** * Resets the update state in updatehelper.json in case of failure, * and logs an error with the message * @param {string} message - the message to be logged onto console */ function resetStateInFailure(message) { updateJsonHandler.reset(); UpdateInfoBar.showUpdateBar({ type: "error", title: Strings.UPDATE_FAILED, description: "" }); enableCheckForUpdateEntry(true); console.error(message); }
.done(function(inProgress) { if(inProgress) { UpdateInfoBar.showUpdateBar({ type: "error", title: Strings.AUTOUPDATE_ERROR, description: Strings.AUTOUPDATE_IN_PROGRESS }); } else { setUpdateStateInJSON("autoUpdateInProgress", true) .done(setUpdateInProgress); } })
var statusValidFn = function () { // Restart button click handler var restartBtnClicked = function () { HealthLogger.sendAnalyticsData( autoUpdateEventNames.AUTOUPDATE_DOWNLOAD_COMPLETE_USER_CLICK_RESTART, "autoUpdate", "installNotification", "installNow ", "click" ); detachUpdateBarBtnHandlers(); initiateUpdateProcess(statusObj.installerPath, statusObj.logFilePath, statusObj.installStatusFilePath); }; // Later button click handler var laterBtnClicked = function () { HealthLogger.sendAnalyticsData( autoUpdateEventNames.AUTOUPDATE_DOWNLOAD_COMPLETE_USER_CLICK_LATER, "autoUpdate", "installNotification", "cancel", "click" ); detachUpdateBarBtnHandlers(); setUpdateStateInJSON('updateInitiatedInPrevSession', false); }; //attaching UpdateBar handlers UpdateInfoBar.on(UpdateInfoBar.RESTART_BTN_CLICKED, restartBtnClicked); UpdateInfoBar.on(UpdateInfoBar.LATER_BTN_CLICKED, laterBtnClicked); UpdateInfoBar.showUpdateBar({ title: Strings.DOWNLOAD_COMPLETE, description: Strings.CLICK_RESTART_TO_UPDATE, needButtons: true }); setUpdateStateInJSON("autoUpdateInProgress", false); HealthLogger.sendAnalyticsData( autoUpdateEventNames.AUTOUPDATE_DOWNLOADCOMPLETE_UPDATE_BAR_RENDERED, "autoUpdate", "installNotification", "render", "" ); };
/** * Handles the error messages from Node, in a popup displayed to the user. * @param {string} message - error string */ function showErrorMessage(message) { var descriptionMessage; switch (message) { case _nodeErrorMessages.UPDATEDIR_READ_FAILED: descriptionMessage = Strings.UPDATEDIR_READ_FAILED; break; case _nodeErrorMessages.UPDATEDIR_CLEAN_FAILED: descriptionMessage = Strings.UPDATEDIR_CLEAN_FAILED; break; } UpdateInfoBar.showUpdateBar({ type: "error", title: Strings.CLEANUP_FAILED, description: descriptionMessage }); }
/** * Handles the download failure callback from Node * @param {string} message - reason of download failure */ function handleDownloadFailure(message) { console.log("AutoUpdate : Download of latest installer failed in Attempt " + (MAX_DOWNLOAD_ATTEMPTS - downloadAttemptsRemaining) + ".\n Reason : " + message); if (downloadAttemptsRemaining) { // Retry the downloading attemptToDownload(); } else { // Download could not completed, all attempts exhausted enableCheckForUpdateEntry(true); UpdateStatus.cleanUpdateStatus(); var descriptionMessage = "", analyticsDescriptionMessage = ""; if (message === _nodeErrorMessages.DOWNLOAD_ERROR) { descriptionMessage = Strings.DOWNLOAD_ERROR; analyticsDescriptionMessage = "Error occurred while downloading."; } else if (message === _nodeErrorMessages.NETWORK_SLOW_OR_DISCONNECTED) { descriptionMessage = Strings.NETWORK_SLOW_OR_DISCONNECTED; analyticsDescriptionMessage = "Network is Disconnected or too slow."; } HealthLogger.sendAnalyticsData( autoUpdateEventNames.AUTOUPDATE_DOWNLOAD_FAILED, "autoUpdate", "download", "fail", analyticsDescriptionMessage ); UpdateInfoBar.showUpdateBar({ type: "error", title: Strings.DOWNLOAD_FAILED, description: descriptionMessage }); setUpdateStateInJSON("autoUpdateInProgress", false); } }
/** * Attempts a download of the latest installer, while cleaning up any existing downloaded installers */ function attemptToDownload() { if (checkIfOnline()) { postMessageToNode(MessageIds.PERFORM_CLEANUP, ['.json'], true); } else { enableCheckForUpdateEntry(true); UpdateStatus.cleanUpdateStatus(); HealthLogger.sendAnalyticsData( autoUpdateEventNames.AUTOUPDATE_DOWNLOAD_FAILED, "autoUpdate", "download", "fail", "No Internet connection available." ); UpdateInfoBar.showUpdateBar({ type: "warning", title: Strings.DOWNLOAD_FAILED, description: Strings.INTERNET_UNAVAILABLE }); setUpdateStateInJSON("autoUpdateInProgress", false); } }
var statusValidFn = function () { // Restart button click handler var restartBtnClicked = function () { detachUpdateBarBtnHandlers(); initiateUpdateProcess(statusObj.installerPath, statusObj.logFilePath, statusObj.installStatusFilePath); }; // Later button click handler var laterBtnClicked = function () { detachUpdateBarBtnHandlers(); setUpdateStateInJSON('updateInitiatedInPrevSession', false); }; //attaching UpdateBar handlers UpdateInfoBar.on(UpdateInfoBar.RESTART_BTN_CLICKED, restartBtnClicked); UpdateInfoBar.on(UpdateInfoBar.LATER_BTN_CLICKED, laterBtnClicked); UpdateInfoBar.showUpdateBar({ title: Strings.DOWNLOAD_COMPLETE, description: Strings.CLICK_RESTART_TO_UPDATE, needButtons: true }); };
/** * Handles the installer validation callback from Node * @param {object} statusObj - json containing - { * valid - (boolean)true for a valid installer, false otherwise, * installerPath, logFilePath, * installStatusFilePath - for a valid installer, * err - for an invalid installer } */ function handleValidationStatus(statusObj) { enableCheckForUpdateEntry(true); UpdateStatus.cleanUpdateStatus(); if (statusObj.valid) { // Installer is validated successfully var statusValidFn = function () { // Restart button click handler var restartBtnClicked = function () { HealthLogger.sendAnalyticsData( autoUpdateEventNames.AUTOUPDATE_DOWNLOAD_COMPLETE_USER_CLICK_RESTART, "autoUpdate", "installNotification", "installNow ", "click" ); detachUpdateBarBtnHandlers(); initiateUpdateProcess(statusObj.installerPath, statusObj.logFilePath, statusObj.installStatusFilePath); }; // Later button click handler var laterBtnClicked = function () { HealthLogger.sendAnalyticsData( autoUpdateEventNames.AUTOUPDATE_DOWNLOAD_COMPLETE_USER_CLICK_LATER, "autoUpdate", "installNotification", "cancel", "click" ); detachUpdateBarBtnHandlers(); setUpdateStateInJSON('updateInitiatedInPrevSession', false); }; //attaching UpdateBar handlers UpdateInfoBar.on(UpdateInfoBar.RESTART_BTN_CLICKED, restartBtnClicked); UpdateInfoBar.on(UpdateInfoBar.LATER_BTN_CLICKED, laterBtnClicked); UpdateInfoBar.showUpdateBar({ title: Strings.DOWNLOAD_COMPLETE, description: Strings.CLICK_RESTART_TO_UPDATE, needButtons: true }); setUpdateStateInJSON("autoUpdateInProgress", false); HealthLogger.sendAnalyticsData( autoUpdateEventNames.AUTOUPDATE_DOWNLOADCOMPLETE_UPDATE_BAR_RENDERED, "autoUpdate", "installNotification", "render", "" ); }; if(!isAutoUpdateInitiated) { isAutoUpdateInitiated = true; updateJsonHandler.refresh() .done(function() { setUpdateStateInJSON('downloadCompleted', true) .done(statusValidFn); }); } else { setUpdateStateInJSON('downloadCompleted', true) .done(statusValidFn); } } else { // Installer validation failed if (updateJsonHandler.get("downloadCompleted")) { // If this was a cached download, retry downloading updateJsonHandler.reset(); var statusInvalidFn = function () { downloadAttemptsRemaining = MAX_DOWNLOAD_ATTEMPTS; getLatestInstaller(); }; setUpdateStateInJSON('downloadCompleted', false) .done(statusInvalidFn); } else { // If this is a new download, prompt the message on update bar var descriptionMessage = "", analyticsDescriptionMessage = ""; switch (statusObj.err) { case _nodeErrorMessages.CHECKSUM_DID_NOT_MATCH: descriptionMessage = Strings.CHECKSUM_DID_NOT_MATCH; analyticsDescriptionMessage = "Checksum didn't match."; break; case _nodeErrorMessages.INSTALLER_NOT_FOUND: descriptionMessage = Strings.INSTALLER_NOT_FOUND; analyticsDescriptionMessage = "Installer not found."; break; } HealthLogger.sendAnalyticsData( autoUpdateEventNames.AUTOUPDATE_DOWNLOAD_FAILED, "autoUpdate", "download", "fail", analyticsDescriptionMessage ); UpdateInfoBar.showUpdateBar({ type: "error", title: Strings.VALIDATION_FAILED, description: descriptionMessage }); setUpdateStateInJSON("autoUpdateInProgress", false); } } }
/** * Handles the installer validation callback from Node * @param {object} statusObj - json containing - { * valid - (boolean)true for a valid installer, false otherwise, * installerPath, logFilePath, * installStatusFilePath - for a valid installer, * err - for an invalid installer } */ function handleValidationStatus(statusObj) { enableCheckForUpdateEntry(true); UpdateStatus.cleanUpdateStatus(); if (statusObj.valid) { // Installer is validated successfully var statusValidFn = function () { // Restart button click handler var restartBtnClicked = function () { detachUpdateBarBtnHandlers(); initiateUpdateProcess(statusObj.installerPath, statusObj.logFilePath, statusObj.installStatusFilePath); }; // Later button click handler var laterBtnClicked = function () { detachUpdateBarBtnHandlers(); setUpdateStateInJSON('updateInitiatedInPrevSession', false); }; //attaching UpdateBar handlers UpdateInfoBar.on(UpdateInfoBar.RESTART_BTN_CLICKED, restartBtnClicked); UpdateInfoBar.on(UpdateInfoBar.LATER_BTN_CLICKED, laterBtnClicked); UpdateInfoBar.showUpdateBar({ title: Strings.DOWNLOAD_COMPLETE, description: Strings.CLICK_RESTART_TO_UPDATE, needButtons: true }); }; setUpdateStateInJSON('downloadCompleted', true, statusValidFn); } else { // Installer validation failed if (updateJsonHandler.get("downloadCompleted")) { // If this was a cached download, retry downloading updateJsonHandler.reset(); var statusInvalidFn = function () { downloadAttemptsRemaining = MAX_DOWNLOAD_ATTEMPTS; getLatestInstaller(); }; setUpdateStateInJSON('downloadCompleted', false, statusInvalidFn); } else { // If this is a new download, prompt the message on update bar var descriptionMessage; switch (statusObj.err) { case _nodeErrorMessages.CHECKSUM_DID_NOT_MATCH: descriptionMessage = Strings.CHECKSUM_DID_NOT_MATCH; break; case _nodeErrorMessages.INSTALLER_NOT_FOUND: descriptionMessage = Strings.INSTALLER_NOT_FOUND; break; } UpdateInfoBar.showUpdateBar({ type: "error", title: Strings.VALIDATION_FAILED, description: descriptionMessage }); } } }