Bug 1448804 Part 2 - Offer an opt-in survey at the end of the Windows uninstaller. r?agashlin draft
authorMatt Howell <mhowell@mozilla.com>
Mon, 09 Jul 2018 10:54:05 -0700
changeset 817003 a1898d85ac0773472442715d973db95119c6e257
parent 817002 b883351b2924283396c8fd19be978b7bcd4ffcf4
push id115923
push usermhowell@mozilla.com
push dateWed, 11 Jul 2018 19:54:57 +0000
reviewersagashlin
bugs1448804
milestone63.0a1
Bug 1448804 Part 2 - Offer an opt-in survey at the end of the Windows uninstaller. r?agashlin MozReview-Commit-ID: 2yPAfY3S2Bl
browser/installer/windows/nsis/uninstaller.nsi
browser/locales/en-US/installer/custom.properties
toolkit/mozapps/installer/windows/nsis/makensis.mk
--- a/browser/installer/windows/nsis/uninstaller.nsi
+++ b/browser/installer/windows/nsis/uninstaller.nsi
@@ -32,16 +32,17 @@ ManifestDPIAware true
 ; prevents compiling of the reg write logging.
 !define NO_LOG
 
 !define MaintUninstallKey \
  "Software\Microsoft\Windows\CurrentVersion\Uninstall\MozillaMaintenanceService"
 
 Var TmpVal
 Var MaintCertKey
+Var ShouldOpenSurvey
 
 ; Other included files may depend upon these includes!
 ; The following includes are provided by NSIS.
 !include FileFunc.nsh
 !include LogicLib.nsh
 !include MUI.nsh
 !include WinMessages.nsh
 !include WinVer.nsh
@@ -119,16 +120,18 @@ Name "${BrandFullName}"
 OutFile "helper.exe"
 !ifdef HAVE_64BIT_BUILD
   InstallDir "$PROGRAMFILES64\${BrandFullName}\"
 !else
   InstallDir "$PROGRAMFILES32\${BrandFullName}\"
 !endif
 ShowUnInstDetails nevershow
 
+!define URLUninstallSurvey "https://qsurvey.mozilla.com/s3/FF-Desktop-Post-Uninstall?channel=${UpdateChannel}&version=${AppVersion}&osversion="
+
 ################################################################################
 # Modern User Interface - MUI
 
 !define MUI_ABORTWARNING
 !define MUI_ICON setup.ico
 !define MUI_UNICON setup.ico
 !define MUI_WELCOMEPAGE_TITLE_3LINES
 !define MUI_HEADERIMAGE
@@ -152,25 +155,38 @@ ShowUnInstDetails nevershow
 
 ; Custom Uninstall Confirm Page
 UninstPage custom un.preConfirm
 
 ; Remove Files Page
 !insertmacro MUI_UNPAGE_INSTFILES
 
 ; Finish Page
-
+!define MUI_FINISHPAGE_SHOWREADME
+!define MUI_FINISHPAGE_SHOWREADME_NOTCHECKED
+!define MUI_FINISHPAGE_SHOWREADME_TEXT $(UN_SURVEY_CHECKBOX_LABEL)
+!define MUI_FINISHPAGE_SHOWREADME_FUNCTION un.Survey
+!define MUI_PAGE_CUSTOMFUNCTION_PRE un.preFinish
 !insertmacro MUI_UNPAGE_FINISH
 
 ; Use the default dialog for IDD_VERIFY for a simple Banner
 ChangeUI IDD_VERIFY "${NSISDIR}\Contrib\UIs\default.exe"
 
 ################################################################################
 # Helper Functions
 
+Function un.Survey
+  ; We can't actually call ExecInExplorer here because it's going to have to
+  ; make some marshalled COM calls and those are not allowed from within a
+  ; synchronous message handler (where we currently are); we'll be thrown
+  ; RPC_E_CANTCALLOUT_ININPUTSYNCCALL if we try. So all we can do is record
+  ; that we need to make the call later, which we'll do from un.onGUIEnd.
+  StrCpy $ShouldOpenSurvey "1"
+FunctionEnd
+
 ; This function is used to uninstall the maintenance service if the
 ; application currently being uninstalled is the last application to use the
 ; maintenance service.
 Function un.UninstallServiceIfNotUsed
   ; $0 will store if a subkey exists
   ; $1 will store the first subkey if it exists or an empty string if it doesn't
   ; Backup the old values
   Push $0
@@ -582,16 +598,22 @@ Function un.preConfirm
   !insertmacro MUI_INSTALLOPTIONS_INITDIALOG "unconfirm.ini"
   GetDlgItem $0 $HWNDPARENT 1
   System::Call "user32::SetFocus(i r0, i 0x0007, i,i)i"
   ${MUI_INSTALLOPTIONS_READ} $1 "unconfirm.ini" "Field 2" "HWND"
   SendMessage $1 ${WM_SETTEXT} 0 "STR:$INSTDIR"
   !insertmacro MUI_INSTALLOPTIONS_SHOW
 FunctionEnd
 
+Function un.preFinish
+  ; Need to give the survey (readme) checkbox a few extra DU's of height
+  ; to accommodate a potentially multi-line label.
+  WriteINIStr "$PLUGINSDIR\ioSpecial.ini" "Field 4" Bottom "120"
+FunctionEnd
+
 ################################################################################
 # Initialization Functions
 
 Function .onInit
   ; Remove the current exe directory from the search order.
   ; This only effects LoadLibrary calls and not implicitly loaded DLLs.
   System::Call 'kernel32::SetDllDirectoryW(w "")'
 
@@ -600,21 +622,49 @@ Function .onInit
 FunctionEnd
 
 Function un.onInit
   ; Remove the current exe directory from the search order.
   ; This only effects LoadLibrary calls and not implicitly loaded DLLs.
   System::Call 'kernel32::SetDllDirectoryW(w "")'
 
   StrCpy $LANGUAGE 0
+  StrCpy $ShouldOpenSurvey "0"
 
   ${un.UninstallUnOnInitCommon}
 
   !insertmacro InitInstallOptionsFile "unconfirm.ini"
 FunctionEnd
 
 Function .onGUIEnd
   ${OnEndCommon}
 FunctionEnd
 
 Function un.onGUIEnd
   ${un.OnEndCommon}
+
+  ${If} $ShouldOpenSurvey == "1"
+    ; Though these values are sometimes incorrect due to bug 444664 it happens
+    ; so rarely it isn't worth working around it by reading the registry values.
+    ${WinVerGetMajor} $0
+    ${WinVerGetMinor} $1
+    ${WinVerGetBuild} $2
+    ${WinVerGetServicePackLevel} $3
+    StrCpy $R1 "${URLUninstallSurvey}$0.$1.$2.$3"
+
+    ; We can't just open the URL normally because we are most likely running
+    ; elevated without an unelevated process to redirect through, and we're
+    ; not going to go around starting elevated web browsers. But to start an
+    ; unelevated process directly from here we need a pretty nasty hack; see
+    ; the ExecInExplorer plugin code itself for the details.
+    ${If} ${AtLeastWin10}
+      ; If we were the default browser and we've now been uninstalled, we need
+      ; to take steps to make sure the user doesn't see an "open with" dialog;
+      ; they're helping us out by answering this survey, they don't need more
+      ; friction. Windows 7 and 8 automatically switch the default to IE, so
+      ; nothing to do for those, but 10 leaves the default empty and does show
+      ; the dialog, so we have to force Edge there.
+      ExecInExplorer::Exec "microsoft-edge:$R1"
+    ${Else}
+      ExecInExplorer::Exec "$R1"
+    ${EndIf}
+  ${EndIf}
 FunctionEnd
--- a/browser/locales/en-US/installer/custom.properties
+++ b/browser/locales/en-US/installer/custom.properties
@@ -63,16 +63,18 @@ UN_CONFIRM_CLICK=Click Uninstall to cont
 
 BANNER_CHECK_EXISTING=Checking existing installation…
 
 STATUS_INSTALL_APP=Installing $BrandShortName…
 STATUS_INSTALL_LANG=Installing Language Files (${AB_CD})…
 STATUS_UNINSTALL_MAIN=Uninstalling $BrandShortName…
 STATUS_CLEANUP=A Little Housekeeping…
 
+UN_SURVEY_CHECKBOX_LABEL=Tell Mozilla why you uninstalled $BrandShortName
+
 # _DESC strings support approximately 65 characters per line.
 # One line
 OPTIONS_SUMMARY=Choose the type of setup you prefer, then click Next.
 # One line
 OPTION_STANDARD_DESC=$BrandShortName will be installed with the most common options.
 OPTION_STANDARD_RADIO=&Standard
 # Two lines
 OPTION_CUSTOM_DESC=You may choose individual options to be installed. Recommended for experienced users.
--- a/toolkit/mozapps/installer/windows/nsis/makensis.mk
+++ b/toolkit/mozapps/installer/windows/nsis/makensis.mk
@@ -23,16 +23,17 @@ TOOLKIT_NSIS_FILES = \
 	$(NULL)
 
 CUSTOM_NSIS_PLUGINS = \
 	AccessControl.dll \
 	AppAssocReg.dll \
 	ApplicationID.dll \
 	CertCheck.dll \
 	CityHash.dll \
+	ExecInExplorer.dll \
 	InetBgDL.dll \
 	InvokeShellVerb.dll \
 	liteFirewallW.dll \
 	nsJSON.dll \
 	ServicesHelper.dll \
 	ShellLink.dll \
 	UAC.dll \
 	$(NULL)