Bug 1161661 - Provide progress and state feedback via the stub installer taskbar icon. r=bbondy

This commit is contained in:
Robert Strong 2015-05-07 10:35:00 -07:00
parent e97515ddca
commit 909ef1650a
4 changed files with 248 additions and 87 deletions

View File

@ -254,10 +254,7 @@ Section "-InstallStartCleanup"
${CleanUpdateDirectories} "Mozilla\Firefox" "Mozilla\updates"
${RemoveDeprecatedFiles}
StrCpy $R2 "false"
StrCpy $R3 "false"
${RemovePrecompleteEntries} "$R2" "$R3"
${RemovePrecompleteEntries} "false"
${If} ${FileExists} "$INSTDIR\defaults\pref\channel-prefs.js"
Delete "$INSTDIR\defaults\pref\channel-prefs.js"

View File

@ -71,6 +71,8 @@ Var CanSetAsDefault
Var InstallCounterStep
Var InstallStepSize
Var InstallTotalSteps
Var ProgressCompleted
Var ProgressTotal
Var TmpVal
Var ExitCode
@ -258,6 +260,7 @@ Var ControlRightPX
!insertmacro IsUserAdmin
!insertmacro RemovePrecompleteEntries
!insertmacro SetBrandNameVars
!insertmacro ITBL3Create
!insertmacro UnloadUAC
VIAddVersionKey "FileDescription" "${BrandShortName} Stub Installer"
@ -1293,6 +1296,9 @@ Function createInstall
StrCpy $InstallTotalSteps ${InstallCleanTotalSteps}
${EndIf}
${ITBL3Create}
${ITBL3SetProgressState} "${TBPF_INDETERMINATE}"
${NSD_CreateTimer} StartDownload ${DownloadIntervalMS}
LockWindow off
@ -1315,6 +1321,21 @@ Function StartDownload
${EndIf}
FunctionEnd
Function SetProgressBars
SendMessage $Progressbar ${PBM_SETPOS} $ProgressCompleted 0
${ITBL3SetProgressValue} "$ProgressCompleted" "$ProgressTotal"
FunctionEnd
Function RemoveFileProgressCallback
IntOp $InstallCounterStep $InstallCounterStep + 2
System::Int64Op $ProgressCompleted + $InstallStepSize
Pop $ProgressCompleted
Call SetProgressBars
System::Int64Op $ProgressCompleted + $InstallStepSize
Pop $ProgressCompleted
Call SetProgressBars
FunctionEnd
Function OnDownload
InetBgDL::GetStats
# $0 = HTTP status code, 0=Completed
@ -1333,6 +1354,7 @@ Function OnDownload
${NSD_AddStyle} $Progressbar ${PBS_MARQUEE}
SendMessage $Progressbar ${PBM_SETMARQUEE} 1 \
$ProgressbarMarqueeIntervalMS ; start=1|stop=0 interval(ms)=+N
${ITBL3SetProgressState} "${TBPF_INDETERMINATE}"
${EndIf}
InetBgDL::Get /RESET /END
StrCpy $DownloadSizeBytes ""
@ -1390,8 +1412,9 @@ Function OnDownload
SendMessage $Progressbar ${PBM_SETMARQUEE} 0 0 ; start=1|stop=0 interval(ms)=+N
${RemoveStyle} $Progressbar ${PBS_MARQUEE}
System::Int64Op $HalfOfDownload + $DownloadSizeBytes
Pop $R9
SendMessage $Progressbar ${PBM_SETRANGE32} 0 $R9
Pop $ProgressTotal
StrCpy $ProgressCompleted 0
SendMessage $Progressbar ${PBM_SETRANGE32} $ProgressCompleted $ProgressTotal
${EndIf}
; Don't update the status until after the download starts
@ -1448,12 +1471,13 @@ Function OnDownload
LockWindow on
; Update the progress bars first in the UI change so they take affect
; before other UI changes.
SendMessage $Progressbar ${PBM_SETPOS} $DownloadSizeBytes 0
StrCpy $ProgressCompleted "$DownloadSizeBytes"
Call SetProgressBars
System::Int64Op $InstallStepSize * ${InstallProgressFirstStep}
Pop $R9
SendMessage $Progressbar ${PBM_SETSTEP} $R9 0
SendMessage $Progressbar ${PBM_STEPIT} 0 0
SendMessage $Progressbar ${PBM_SETSTEP} $InstallStepSize 0
System::Int64Op $ProgressCompleted + $R9
Pop $ProgressCompleted
Call SetProgressBars
ShowWindow $LabelDownloading ${SW_HIDE}
ShowWindow $LabelInstalling ${SW_SHOW}
ShowWindow $LabelBlurb2 ${SW_HIDE}
@ -1540,7 +1564,8 @@ Function OnDownload
WriteIniStr "$0" "TASKBAR" "Migrated" "true"
${EndIf}
${RemovePrecompleteEntries} $Progressbar $InstallCounterStep
GetFunctionAddress $0 RemoveFileProgressCallback
${RemovePrecompleteEntries} $0
; Delete the install.log and let the full installer create it. When the
; installer closes it we can detect that it has completed.
@ -1569,7 +1594,8 @@ Function OnDownload
LockWindow off
${EndIf}
StrCpy $DownloadedBytes "$3"
SendMessage $Progressbar ${PBM_SETPOS} $3 0
StrCpy $ProgressCompleted "$DownloadedBytes"
Call SetProgressBars
${EndIf}
${EndIf}
FunctionEnd
@ -1608,7 +1634,9 @@ Function CheckInstall
Return
${EndIf}
SendMessage $Progressbar ${PBM_STEPIT} 0 0
System::Int64Op $ProgressCompleted + $InstallStepSize
Pop $ProgressCompleted
Call SetProgressBars
${If} ${FileExists} "$INSTDIR\install.log"
Delete "$INSTDIR\install.tmp"
@ -1632,7 +1660,6 @@ Function CheckInstall
Pop $EndInstallPhaseTickCount
System::Int64Op $InstallStepSize * ${InstallProgressFinishStep}
Pop $InstallStepSize
SendMessage $Progressbar ${PBM_SETSTEP} $InstallStepSize 0
${NSD_CreateTimer} FinishInstall ${InstallIntervalMS}
${EndUnless}
${EndIf}
@ -1647,14 +1674,16 @@ Function FinishInstall
${EndIf}
${If} $InstallTotalSteps != $InstallCounterStep
SendMessage $Progressbar ${PBM_STEPIT} 0 0
System::Int64Op $ProgressCompleted + $InstallStepSize
Pop $ProgressCompleted
Call SetProgressBars
Return
${EndIf}
${NSD_KillTimer} FinishInstall
SendMessage $Progressbar ${PBM_GETRANGE} 0 0 $R9
SendMessage $Progressbar ${PBM_SETPOS} $R9 0
StrCpy $ProgressCompleted "$ProgressTotal"
Call SetProgressBars
${If} "$CheckboxSetAsDefault" == "1"
${GetParameters} $0
@ -1935,6 +1964,10 @@ FunctionEnd
Function DisplayDownloadError
${NSD_KillTimer} DisplayDownloadError
; To better display the error state on the taskbar set the progress completed
; value to the total value.
${ITBL3SetProgressValue} "100" "100"
${ITBL3SetProgressState} "${TBPF_ERROR}"
MessageBox MB_OKCANCEL|MB_ICONSTOP "$(ERROR_DOWNLOAD)" IDCANCEL +2 IDOK +1
StrCpy $OpenedDownloadPage "1" ; Already initialized to 0

View File

@ -397,9 +397,7 @@ Section "Uninstall"
${UnregisterDLL} "$INSTDIR\AccessibleMarshal.dll"
${EndIf}
StrCpy $R2 "false"
StrCpy $R3 "false"
${un.RemovePrecompleteEntries} "$R2" "$R3"
${un.RemovePrecompleteEntries} "false"
${If} ${FileExists} "$INSTDIR\defaults\pref\channel-prefs.js"
Delete /REBOOTOK "$INSTDIR\defaults\pref\channel-prefs.js"

View File

@ -1641,8 +1641,8 @@
!macroend
!define RegisterDLL `!insertmacro RegisterDLL`
!define UnregisterDLL `!insertmacro UnregisterDLL`
!define RegisterDLL "!insertmacro RegisterDLL"
!define UnregisterDLL "!insertmacro UnregisterDLL"
################################################################################
@ -4332,24 +4332,21 @@
!macroend
/**
* Parses the precomplete file to remove an installation's files and directories.
* Parses the precomplete file to remove an installation's files and
* directories.
*
* @param _PROGRESSBAR
* The progress bar to update using PBM_STEPIT. Can also be "false" if
* updating a progressbar isn't needed.
* @param _INSTALL_STEP_COUNTER
* The install step counter to increment. The variable specified in
* this parameter is also updated. Can also be "false" if a counter
* isn't needed.
* $R2 = false if all files were deleted or moved to the tobedeleted directory.
* @param _CALLBACK
* The function address of a callback function for progress or "false"
* if there is no callback function.
*
* $R3 = false if all files were deleted or moved to the tobedeleted directory.
* true if file(s) could not be moved to the tobedeleted directory.
* $R3 = Path to temporary precomplete file.
* $R4 = File handle for the temporary precomplete file.
* $R5 = String returned from FileRead.
* $R6 = First seven characters of the string returned from FileRead.
* $R7 = Temporary file path used to rename files that are in use.
* $R8 = _PROGRESSBAR
* $R9 = _INSTALL_STEP_COUNTER
* $R4 = Path to temporary precomplete file.
* $R5 = File handle for the temporary precomplete file.
* $R6 = String returned from FileRead.
* $R7 = First seven characters of the string returned from FileRead.
* $R8 = Temporary file path used to rename files that are in use.
* $R9 = _CALLBACK
*/
!macro RemovePrecompleteEntries
@ -4368,95 +4365,89 @@
Function ${_MOZFUNC_UN}RemovePrecompleteEntries
Exch $R9
Exch 1
Exch $R8
Push $R8
Push $R7
Push $R6
Push $R5
Push $R4
Push $R3
Push $R2
${If} ${FileExists} "$INSTDIR\precomplete"
StrCpy $R2 "false"
StrCpy $R3 "false"
RmDir /r "$INSTDIR\${TO_BE_DELETED}"
CreateDirectory "$INSTDIR\${TO_BE_DELETED}"
GetTempFileName $R3 "$INSTDIR\${TO_BE_DELETED}"
Delete "$R3"
Rename "$INSTDIR\precomplete" "$R3"
GetTempFileName $R4 "$INSTDIR\${TO_BE_DELETED}"
Delete "$R4"
Rename "$INSTDIR\precomplete" "$R4"
ClearErrors
; Rename and then remove files
FileOpen $R4 "$R3" r
FileOpen $R5 "$R4" r
${Do}
FileRead $R4 $R5
FileRead $R5 $R6
${If} ${Errors}
${Break}
${EndIf}
${${_MOZFUNC_UN}TrimNewLines} "$R5" $R5
${${_MOZFUNC_UN}TrimNewLines} "$R6" $R6
; Replace all occurrences of "/" with "\".
${${_MOZFUNC_UN}WordReplace} "$R5" "/" "\" "+" $R5
${${_MOZFUNC_UN}WordReplace} "$R6" "/" "\" "+" $R6
; Copy the first 7 chars
StrCpy $R6 "$R5" 7
${If} "$R6" == "remove "
StrCpy $R7 "$R6" 7
${If} "$R7" == "remove "
; Copy the string starting after the 8th char
StrCpy $R5 "$R5" "" 8
StrCpy $R6 "$R6" "" 8
; Copy all but the last char to remove the double quote.
StrCpy $R5 "$R5" -1
${If} ${FileExists} "$INSTDIR\$R5"
StrCpy $R6 "$R6" -1
${If} ${FileExists} "$INSTDIR\$R6"
${Unless} "$R9" == "false"
IntOp $R9 $R9 + 2
${EndUnless}
${Unless} "$R8" == "false"
SendMessage $R8 ${PBM_STEPIT} 0 0
SendMessage $R8 ${PBM_STEPIT} 0 0
Call $R9
${EndUnless}
ClearErrors
Delete "$INSTDIR\$R5"
Delete "$INSTDIR\$R6"
${If} ${Errors}
GetTempFileName $R7 "$INSTDIR\${TO_BE_DELETED}"
Delete "$R7"
GetTempFileName $R8 "$INSTDIR\${TO_BE_DELETED}"
Delete "$R8"
ClearErrors
Rename "$INSTDIR\$R5" "$R7"
Rename "$INSTDIR\$R6" "$R8"
${Unless} ${Errors}
Delete /REBOOTOK "$R7"
Delete /REBOOTOK "$R8"
ClearErrors
${EndUnless}
!ifdef __UNINSTALL__
${If} ${Errors}
Delete /REBOOTOK "$INSTDIR\$R5"
StrCpy $R2 "true"
Delete /REBOOTOK "$INSTDIR\$R6"
StrCpy $R3 "true"
ClearErrors
${EndIf}
!endif
${EndIf}
${EndIf}
${ElseIf} "$R6" == "rmdir $\""
${ElseIf} "$R7" == "rmdir $\""
; Copy the string starting after the 7th char.
StrCpy $R5 "$R5" "" 7
StrCpy $R6 "$R6" "" 7
; Copy all but the last two chars to remove the slash and the double quote.
StrCpy $R5 "$R5" -2
${If} ${FileExists} "$INSTDIR\$R5"
StrCpy $R6 "$R6" -2
${If} ${FileExists} "$INSTDIR\$R6"
; Ignore directory removal errors
RmDir "$INSTDIR\$R5"
RmDir "$INSTDIR\$R6"
ClearErrors
${EndIf}
${EndIf}
${Loop}
FileClose $R4
FileClose $R5
; Delete the temporary precomplete file
Delete /REBOOTOK "$R3"
Delete /REBOOTOK "$R4"
RmDir /r /REBOOTOK "$INSTDIR\${TO_BE_DELETED}"
${If} ${RebootFlag}
${AndIf} "$R2" == "false"
${AndIf} "$R3" == "false"
; Clear the reboot flag if all files were deleted or moved to the
; tobedeleted directory.
SetRebootFlag false
@ -4465,14 +4456,12 @@
ClearErrors
Pop $R2
Pop $R3
Pop $R4
Pop $R5
Pop $R6
Pop $R7
Exch $R8
Exch 1
Pop $R8
Exch $R9
FunctionEnd
@ -4480,24 +4469,19 @@
!endif
!macroend
!macro RemovePrecompleteEntriesCall _PROGRESSBAR _INSTALL_STEP_COUNTER
!macro RemovePrecompleteEntriesCall _CALLBACK
!verbose push
Push "${_PROGRESSBAR}"
Push "${_INSTALL_STEP_COUNTER}"
Push "${_CALLBACK}"
!verbose ${_MOZFUNC_VERBOSE}
Call RemovePrecompleteEntries
Pop ${_INSTALL_STEP_COUNTER}
!verbose pop
!macroend
!macro un.RemovePrecompleteEntriesCall _PROGRESSBAR _INSTALL_STEP_COUNTER
!macro un.RemovePrecompleteEntriesCall _CALLBACK
!verbose push
!verbose ${_MOZFUNC_VERBOSE}
Push "${_PROGRESSBAR}"
Push "${_INSTALL_STEP_COUNTER}"
Push "${_CALLBACK}"
Call un.RemovePrecompleteEntries
Pop ${_INSTALL_STEP_COUNTER}
Pop $0
!verbose pop
!macroend
@ -7328,6 +7312,155 @@
!endif
!macroend
################################################################################
# Helpers for taskbar progress
!ifndef CLSCTX_INPROC_SERVER
!define CLSCTX_INPROC_SERVER 1
!endif
!define CLSID_ITaskbarList {56fdf344-fd6d-11d0-958a-006097c9a090}
!define IID_ITaskbarList3 {ea1afb91-9e28-4b86-90e9-9e9f8a5eefaf}
!define ITaskbarList3->SetProgressValue $ITaskbarList3->9
!define ITaskbarList3->SetProgressState $ITaskbarList3->10
/**
* Creates a single uninitialized object of the ITaskbarList class with a
* reference to the ITaskbarList3 interface. This object can be used to set
* progress and state on the installer's taskbar icon using the helper macros
* in this section.
*/
!macro ITBL3Create
!ifndef ${_MOZFUNC_UN}ITBL3Create
Var ITaskbarList3
!verbose push
!verbose ${_MOZFUNC_VERBOSE}
!define ${_MOZFUNC_UN}ITBL3Create "!insertmacro ${_MOZFUNC_UN}ITBL3CreateCall"
Function ${_MOZFUNC_UN}ITBL3Create
; Setting to 0 allows the helper macros to detect when the object was not
; created.
StrCpy $ITaskbarList3 0
; Don't create when running silently.
${Unless} ${Silent}
; This is only supported on Win 7 and above.
${If} ${AtLeastWin7}
System::Call "ole32::CoCreateInstance(g '${CLSID_ITaskbarList}', \
i 0, \
i ${CLSCTX_INPROC_SERVER}, \
g '${IID_ITaskbarList3}', \
*i .s)"
Pop $ITaskbarList3
${EndIf}
${EndUnless}
FunctionEnd
!verbose pop
!endif
!macroend
!macro ITBL3CreateCall
!verbose push
!verbose ${_MOZFUNC_VERBOSE}
Call ITBL3Create
!verbose pop
!macroend
!macro un.ITBL3CreateCall _PATH_TO_IMAGE
!verbose push
!verbose ${_MOZFUNC_VERBOSE}
Call un.ITBL3Create
!verbose pop
!macroend
!macro un.ITBL3Create
!ifndef un.ITBL3Create
!verbose push
!verbose ${_MOZFUNC_VERBOSE}
!undef _MOZFUNC_UN
!define _MOZFUNC_UN "un."
!insertmacro ITBL3Create
!undef _MOZFUNC_UN
!define _MOZFUNC_UN
!verbose pop
!endif
!macroend
/**
* Sets the percentage completed on the taskbar process icon progress indicator.
*
* @param _COMPLETED
* The proportion of the operation that has been completed in relation
* to _TOTAL.
* @param _TOTAL
* The value _COMPLETED will have when the operation has completed.
*
* $R8 = _COMPLETED
* $R9 = _TOTAL
*/
!macro ITBL3SetProgressValueCall _COMPLETED _TOTAL
Push ${_COMPLETED}
Push ${_TOTAL}
${CallArtificialFunction} ITBL3SetProgressValue_
!macroend
!define ITBL3SetProgressValue "!insertmacro ITBL3SetProgressValueCall"
!define un.ITBL3SetProgressValue "!insertmacro ITBL3SetProgressValueCall"
!macro ITBL3SetProgressValue_
Exch $R9
Exch 1
Exch $R8
${If} ${AtLeastWin7}
${AndIf} $ITaskbarList3 <> 0
System::Call "${ITaskbarList3->SetProgressValue}(i$HWNDPARENT, l$R8, l$R9)"
${EndIf}
Exch $R8
Exch 1
Exch $R9
!macroend
; Normal state / no progress bar
!define TBPF_NOPROGRESS 0x00000000
; Marquee style progress bar
!define TBPF_INDETERMINATE 0x00000001
; Standard progress bar
!define TBPF_NORMAL 0x00000002
; Red taskbar button to indicate an error occurred
!define TBPF_ERROR 0x00000004
; Yellow taskbar button to indicate user attention (input) is required to
; resume progress
!define TBPF_PAUSED 0x00000008
/**
* Sets the state on the taskbar process icon progress indicator.
*
* @param _STATE
* The state to set on the taskbar icon progress indicator. Only one of
* the states defined above should be specified.
*
* $R9 = _STATE
*/
!macro ITBL3SetProgressStateCall _STATE
Push ${_STATE}
${CallArtificialFunction} ITBL3SetProgressState_
!macroend
!define ITBL3SetProgressState "!insertmacro ITBL3SetProgressStateCall"
!define un.ITBL3SetProgressState "!insertmacro ITBL3SetProgressStateCall"
!macro ITBL3SetProgressState_
Exch $R9
${If} ${AtLeastWin7}
${AndIf} $ITaskbarList3 <> 0
System::Call "${ITaskbarList3->SetProgressState}(i$HWNDPARENT, i$R9)"
${EndIf}
Exch $R9
!macroend
################################################################################
# Helpers for the new user interface
@ -7430,7 +7563,7 @@
Exch $0
Pop ${HANDLE}
!macroend
!define SetStretchedTransparentImage `!insertmacro __SetStretchedTransparentImage`
!define SetStretchedTransparentImage "!insertmacro __SetStretchedTransparentImage"
/**
* Removes a single style from a control.