Bug 1376597 Part 1 - Wait for the browser to start before exiting the stub installer. r?agashlin draft
authorMatt Howell <mhowell@mozilla.com>
Mon, 07 Aug 2017 15:39:30 -0700
changeset 650501 18c3463f5057c5b8b1de590c714156cf56d3541f
parent 650074 a9d372645a32b8d23d44244f351639af9d73b96a
child 650502 ee1a898b40fb83c70be248368987ab1c804c22e4
push id75423
push usermhowell@mozilla.com
push dateTue, 22 Aug 2017 14:50:38 +0000
reviewersagashlin
bugs1376597
milestone57.0a1
Bug 1376597 Part 1 - Wait for the browser to start before exiting the stub installer. r?agashlin MozReview-Commit-ID: Hw76NPPvHnK
browser/installer/windows/nsis/defines.nsi.in
browser/installer/windows/nsis/stub.nsi
--- a/browser/installer/windows/nsis/defines.nsi.in
+++ b/browser/installer/windows/nsis/defines.nsi.in
@@ -23,16 +23,18 @@
 # These defines should match application.ini settings
 !define AppName               "Firefox"
 !define AppVersion            "@APP_VERSION@"
 !define GREVersion            @MOZILLA_VERSION@
 !define AB_CD                 "@AB_CD@"
 
 !define FileMainEXE           "@MOZ_APP_NAME@.exe"
 !define WindowClass           "FirefoxMessageWindow"
+!define MainWindowClass       "MozillaWindowClass"
+!define DialogWindowClass     "MozillaDialogClass"
 !define DDEApplication        "Firefox"
 !define AppRegName            "Firefox"
 
 !ifndef DEV_EDITION
 !define BrandShortName        "@MOZ_APP_DISPLAYNAME@"
 !endif
 !define BrandFullName         "${BrandFullNameInternal}"
 
--- a/browser/installer/windows/nsis/stub.nsi
+++ b/browser/installer/windows/nsis/stub.nsi
@@ -89,16 +89,18 @@ Var DownloadRetryCount
 Var OpenedDownloadPage
 Var DownloadServerIP
 Var PostSigningData
 Var PreviousInstallDir
 Var PreviousInstallArch
 Var ProfileCleanupPromptType
 Var ProfileCleanupHeaderString
 Var ProfileCleanupButtonString
+Var AppLaunchWaitTickCount
+Var AppLaunchWaitStepSize
 
 ; Uncomment the following to prevent pinging the metrics server when testing
 ; the stub installer
 ;!define STUB_DEBUG
 
 !define StubURLVersion "v8"
 
 ; Successful install exit code
@@ -177,16 +179,29 @@ Var ProfileCleanupButtonString
 ; as defined by InstallProgressFirstStep.
 !define /math InstallCleanTotalSteps ${InstallProgressFirstStep} + 1500
 
 ; Approximately 165 seconds (minus 0.2 seconds for each file that is removed)
 ; with a 100 millisecond timer and a first step of 20 as defined by
 ; InstallProgressFirstStep .
 !define /math InstallPaveOverTotalSteps ${InstallProgressFirstStep} + 1800
 
+; 5 more seconds at the end of the progress bar to wait for the app to launch.
+!define AppLaunchWaitSteps 500
+
+; Number of steps per interval to advance the progress bar. Calibrate this based
+; on how long the progress bar should spend filling up while awaiting app launch.
+!define AppLaunchWaitStepSizeMultiplier 20
+
+; Interval between checks for the application window and progress bar updates.
+!define AppLaunchWaitIntervalMS 100
+
+; Total time to wait for the application to start before just exiting.
+!define AppLaunchWaitTimeoutMS 10000
+
 ; Blurb duty cycle
 !define BlurbDisplayMS 19500
 !define BlurbBlankMS 500
 
 ; Amount of physical memory required for the 64-bit build to be selected (2 GB).
 ; Machines with this or less RAM get the 32-bit build, even with a 64-bit OS.
 !define RAM_NEEDED_FOR_64BIT 0x80000000
 
@@ -1004,20 +1019,25 @@ Function OnDownload
       Return
     ${EndIf}
 
     StrCpy $DownloadSizeBytes "$4"
     System::Int64Op $4 / 2
     Pop $HalfOfDownload
     System::Int64Op $HalfOfDownload / $InstallTotalSteps
     Pop $InstallStepSize
+    StrCpy $AppLaunchWaitStepSize $InstallStepSize
     SendMessage $Progressbar ${PBM_SETMARQUEE} 0 0 ; start=1|stop=0 interval(ms)=+N
     ${RemoveStyle} $Progressbar ${PBS_MARQUEE}
     System::Int64Op $HalfOfDownload + $DownloadSizeBytes
     Pop $ProgressTotal
+    System::Int64Op $AppLaunchWaitStepSize * ${AppLaunchWaitSteps}
+    Pop $R0
+    System::Int64Op $ProgressTotal + $R0
+    Pop $ProgressTotal
     StrCpy $ProgressCompleted 0
     SendMessage $Progressbar ${PBM_SETRANGE32} $ProgressCompleted $ProgressTotal
   ${EndIf}
 
   ; Don't update the status until after the download starts
   ${If} $2 != 0
   ${AndIf} "$4" == ""
     Return
@@ -1181,17 +1201,20 @@ Function OnDownload
       StrCpy $DownloadedBytes "$3"
       StrCpy $ProgressCompleted "$DownloadedBytes"
       Call SetProgressBars
     ${EndIf}
   ${EndIf}
 FunctionEnd
 
 Function SendPing
+  ${NSD_KillTimer} NextBlurb
+  ${NSD_KillTimer} ClearBlurb
   HideWindow
+
   ${If} $CheckboxSendPing == 1
     ; Get the tick count for the completion of all phases.
     System::Call "kernel32::GetTickCount()l .s"
     Pop $EndFinishPhaseTickCount
 
     ; When the value of $IsDownloadFinished is false the download was started
     ; but didn't finish. In this case the tick count stored in
     ; $EndFinishPhaseTickCount is used to determine how long the download was
@@ -1505,19 +1528,16 @@ Function FinishInstall
     System::Int64Op $ProgressCompleted + $InstallStepSize
     Pop $ProgressCompleted
     Call SetProgressBars
     Return
   ${EndIf}
 
   ${NSD_KillTimer} FinishInstall
 
-  StrCpy $ProgressCompleted "$ProgressTotal"
-  Call SetProgressBars
-
   ${If} ${FileExists} "$INSTDIR\${FileMainEXE}.moz-upgrade"
     Delete "$INSTDIR\${FileMainEXE}"
     Rename "$INSTDIR\${FileMainEXE}.moz-upgrade" "$INSTDIR\${FileMainEXE}"
   ${EndIf}
 
   StrCpy $ExitCode "${ERR_SUCCESS}"
 
   StrCpy $InstallCounterStep 0
@@ -1532,17 +1552,16 @@ Function FinishProgressBar
   ${EndIf}
 
   ${NSD_KillTimer} FinishProgressBar
   ${NSD_KillTimer} NextBlurb
   ${NSD_KillTimer} ClearBlurb
 
   Call CopyPostSigningData
   Call LaunchApp
-  Call SendPing
 FunctionEnd
 
 Function RelativeGotoPage
   IntCmp $R9 0 0 Move Move
   StrCmp $R9 "X" 0 Move
   StrCpy $R9 "120"
 
   Move:
@@ -1651,28 +1670,60 @@ Function LaunchApp
     ${Else}
       Exec "$\"$INSTDIR\${FileMainEXE}$\""
     ${EndIf}
   ${Else}
     StrCpy $R1 $CheckboxCleanupProfile
     GetFunctionAddress $0 LaunchAppFromElevatedProcess
     UAC::ExecCodeSegment $0
   ${EndIf}
+
+  StrCpy $AppLaunchWaitTickCount 0
+  ${NSD_CreateTimer} WaitForAppLaunch ${AppLaunchWaitIntervalMS}
 FunctionEnd
 
 Function LaunchAppFromElevatedProcess
   ; Set the current working directory to the installation directory
   SetOutPath "$INSTDIR"
   ${If} $R1 == 1
     Exec "$\"$INSTDIR\${FileMainEXE}$\" -reset-profile -migration"
   ${Else}
     Exec "$\"$INSTDIR\${FileMainEXE}$\""
   ${EndIf}
 FunctionEnd
 
+Function WaitForAppLaunch
+  FindWindow $0 "${MainWindowClass}"
+  FindWindow $1 "${DialogWindowClass}"
+  ${If} $0 <> 0
+  ${OrIf} $1 <> 0
+    ${NSD_KillTimer} WaitForAppLaunch
+    StrCpy $ProgressCompleted "$ProgressTotal"
+    Call SetProgressBars
+    Call SendPing
+    Return
+  ${EndIf}
+
+  IntOp $AppLaunchWaitTickCount $AppLaunchWaitTickCount + 1
+  IntOp $0 $AppLaunchWaitTickCount * ${AppLaunchWaitIntervalMS}
+  ${If} $0 >= ${AppLaunchWaitTimeoutMS}
+    ; We've waited an unreasonably long time, so just exit.
+    ${NSD_KillTimer} WaitForAppLaunch
+    Call SendPing
+    Return
+  ${EndIf}
+
+  ${If} $AppLaunchWaitTickCount < ${AppLaunchWaitSteps}
+    IntOp $0 $AppLaunchWaitStepSize * ${AppLaunchWaitStepSizeMultiplier}
+    System::Int64Op $ProgressCompleted + $0
+    Pop $ProgressCompleted
+  ${EndIf}
+  Call SetProgressBars
+FunctionEnd
+
 Function CopyPostSigningData
   ${LineRead} "$EXEDIR\postSigningData" "1" $PostSigningData
   ${If} ${Errors}
     ClearErrors
     StrCpy $PostSigningData "0"
   ${Else}
     CreateDirectory "$LOCALAPPDATA\Mozilla\Firefox"
     CopyFiles /SILENT "$EXEDIR\postSigningData" "$LOCALAPPDATA\Mozilla\Firefox"