Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Send current synthDriver name and brailleDisplay name to update server for stats gathering. #8217

Merged
merged 10 commits into from Jun 17, 2018

Conversation

Projects
None yet
8 participants
@michaelDCurran
Copy link
Contributor

michaelDCurran commented May 1, 2018

Link to issue number:

None.

Summary of the issue:

Currently we have no idea what percentage of users use a particular synthDriver or brailleDisplay. This would be extremely useful data to better prioritize future work, including how much effort we put into eSpeak contributions for example.

Description of how this pull request fixes the issue:

Simply sends synthDriver name and brailleDisplay name as variables to the update server.
Eventually it would be nice if we could prepend the add-on name if there is one, but for now this at very least will give some much needed visibility for espeak usage.

Testing performed:

Instructed NVDA to check for update. Confirmed on the server that synthDriver name and brailleDisplay name were being gathered.

Known issues with pull request:

None.

Change log entry:

Changes:

  • When checking for updates, NVDA will now send the name of the current synth driver and braille display in use, to aide in better prioritization for future work on these drivers.

@michaelDCurran michaelDCurran requested a review from feerrenrut May 1, 2018

@michaelDCurran

This comment has been minimized.

Copy link
Contributor Author

michaelDCurran commented May 1, 2018

A reminder that users can uncheck automatically check for updates in the General Settings, if they are uncomfortable with this data going to NV Access. But again, this data will greatly help us understand what we need to work on. There is no point putting large amounts of effort into eSpeak say if it was found athat only 10% of users actually use it.

michaelDCurran added a commit that referenced this pull request May 1, 2018

@leonardder

This comment has been minimized.

Copy link
Collaborator

leonardder commented May 1, 2018

As discussed last week, how about adding the output braille table as well while at it? Cc @bramd

Also, I wonder whether there any privacy concerns. I don't care at all for myself, other's might.

@leonardder

This comment has been minimized.

Copy link
Collaborator

leonardder commented May 1, 2018

@michaelDCurran commented on 1 mei 2018 08:35 CEST:

A reminder that users can uncheck automatically check for updates in the General Settings, if they are uncomfortable with this data going to NV Access. But again, this data will greatly help us understand what we need to work on.

Would it help to have a section in the user guide that explicitly states what data is send to NV Access?

@Brian1Gaff

This comment has been minimized.

Copy link

Brian1Gaff commented May 1, 2018

@Brian1Gaff

This comment has been minimized.

Copy link

Brian1Gaff commented May 1, 2018

@PratikP1

This comment has been minimized.

Copy link

PratikP1 commented May 1, 2018

@bramd

This comment has been minimized.

Copy link
Contributor

bramd commented May 1, 2018

Sounds good to me. Braille output table is interesting as well, but only if we know the users' language/locale. So we should gather that as well if we don't already do that.

Regarding GDPR. I'm not a subject expert on the matter, but have lots of (government) clients who are really busy implementing GDPR measures right now, so I've heard a few examples there. Basically, it's best to ask consent for any data you want to gather and that could be qualified as personal data. Even an IP address seems to be classified as personal data as far as I know. Also, you need to be specific where the data is used for and it's not allowed to deny people functionality if they don't want to share their data. For example, if users don't agree to share their synth/braille display name, we might not ban them from getting updates automatically, since that data isn't strictly needed for the auto update function.

That being said, I don't know how it is if we aggregate the data directly after receiving it, so we can't see which specific person uses synth x. Since GDPR is a big issue in Europe right now it would be good to investigate if NVDA is GDPR compliant. That's outside the scope of this PR of course, but sooner or later European companies willing to use NVDA will request GDPR compliance.

@michaelDCurran

This comment has been minimized.

Copy link
Contributor Author

michaelDCurran commented May 1, 2018

@Brian1Gaff

This comment has been minimized.

Copy link

Brian1Gaff commented May 2, 2018

michaelDCurran added some commits May 2, 2018

When sending synth / braille driver names to the server for stats gat…
…hering, append either core, external or addon:addonName to better differentiate between the drivers.
Ask the user if they wish to allow sending usage data to NV Access. A…
…lso allow this to be configured from the General Settings tab. Document what data is sent in the userGuide. Also collect outputBrailleTable.
@@ -32,6 +32,16 @@
RPC_E_DISCONNECTED = -2147417848
LOAD_WITH_ALTERED_SEARCH_PATH=0x8

def isPathExternalToNVDA(path):
""" Checks if the given path is external to NVDA (I.e. not pointing to build-in code). """

This comment has been minimized.

@feerrenrut

feerrenrut May 7, 2018

Contributor

Typo: build-in should be built-in

"installed": config.isInstalledCopy(),
"synthDriver":getQualifiedDriverClassNameForStats(synthDriverClass) if synthDriverClass else None,
"brailleDisplay":getQualifiedDriverClassNameForStats(brailleDisplayClass) if brailleDisplayClass else None,
"outputBrailleTable":config.conf['braille']['translationTable'] if brailleDisplayClass else None,

This comment has been minimized.

@feerrenrut

feerrenrut May 7, 2018

Contributor

Might be worth while adding a comment here to say that any additions must be added to the userguide.

==== Allow the NVDA project to gather NVDA usage statistics ====[GeneralSettingsGatherUsageStats]
If this is enabled, NV Access will use the information from update checks in order to track the number of NVDA users including particular demographics such as Operating system and country of origin.
Note that although your IP address will be used to calculate your country during the update check, the IP address is never kept.
A part from the mandatory information required to check for updates, the following extra infomation is also currently sent:

This comment has been minimized.

@feerrenrut

feerrenrut May 7, 2018

Contributor

Typo: A part should be Apart

- Whether this copy of NVDA is portable or installed
- Name of the current speech synthesizer in use (including the name of the add-on the driver comes from)
- Name of the current Braille display in use (including the name of the add-on the driver comes from)
- The current output braille table (if Braille is in use)

This comment has been minimized.

@feerrenrut

feerrenrut May 7, 2018

Contributor

Capital letter b for first usage of Braille

- The current output braille table (if Braille is in use)


This information greatly aides NV Access to prioritize future development of NVDA.

This comment has been minimized.

@feerrenrut

feerrenrut May 7, 2018

Contributor

Typo: too many spaces between greatly and aides.

==== Allow the NVDA project to gather NVDA usage statistics ====[GeneralSettingsGatherUsageStats]
If this is enabled, NV Access will use the information from update checks in order to track the number of NVDA users including particular demographics such as Operating system and country of origin.
Note that although your IP address will be used to calculate your country during the update check, the IP address is never kept.
Apart from the mandatory information required to check for updates, the following extra infomation is also currently sent:

This comment has been minimized.

@leonardder

leonardder May 7, 2018

Collaborator

typo: infomation should be information

@michaelDCurran

This comment has been minimized.

Copy link
Contributor Author

michaelDCurran commented May 7, 2018

I'm wondering about the yes no dialog on start-up. Is it too easy to dismiss in the affirmative? Perhaps the focus should default to the No button? But then I feel that can heavily bias the question. I'd really prefer that the focus be on neither... like... a cancel button? Then they'd be asked again the next time?

@feerrenrut

This comment has been minimized.

Copy link
Contributor

feerrenrut commented May 7, 2018

I'd really prefer that the focus be on neither... like... a cancel button? Then they'd be asked again the next time?

Yes, but perhaps "Ask later" or similar, rather than "cancel".

I am also a little worried about introducing multiple dialogs on startup. It could complicate things, but perhaps combining this with the welcome dialog when the welcome dialog is going to be displayed, and showing this prompt independently when the welcome dialog is not shown?

@leonardder

This comment has been minimized.

Copy link
Collaborator

leonardder commented May 7, 2018

@feerrenrut commented on 7 mei 2018 08:45 CEST:

I am also a little worried about introducing multiple dialogs on startup. It could complicate things, but perhaps combining this with the welcome dialog when the welcome dialog is going to be displayed, and showing this prompt independently when the welcome dialog is not shown?

Hmm, I agree with having multiple prompts introducing more complexity, so I'd just add the prompt to the welcome dialog. We could use a config profile upgrade step to enforce the welcome dialog showing up again.

@michaelDCurran

This comment has been minimized.

Copy link
Contributor Author

michaelDCurran commented May 7, 2018

@leonardder

This comment has been minimized.

Copy link
Collaborator

leonardder commented May 7, 2018

Hmm, I think you have a valid point here.

Now, there are more things I could think of that at some point could end up in the welcome dialog, such as the possibility to enable or disable braille display auto detection. This might require the welcome dialog to become a multi step dialog and behave more like a wizard.

@feerrenrut

This comment has been minimized.

Copy link
Contributor

feerrenrut commented May 7, 2018

Trying to introduce this question into the welcome dialog also brings the danger that the question is hidden from the user. A user is unlikely to carefully inspect all options in the welcome dialog.

Mick, after considering this, I agree we should leave it as is.

@michaelDCurran

This comment has been minimized.

Copy link
Contributor Author

michaelDCurran commented May 7, 2018

@feerrenrut

This comment has been minimized.

Copy link
Contributor

feerrenrut commented May 7, 2018

Ahhh. Yes. Sorry, I must have been tired when I wrote that. I think it's important to be able to dismiss the dialog without making an explicit decision.

@michaelDCurran michaelDCurran requested a review from feerrenrut May 10, 2018

@@ -924,3 +924,64 @@ def shouldConfigProfileTriggersBeSuspended():

def _isDebug():
return config.conf["debugLog"]["gui"]

class AskAllowUsageStatsDialog(wx.Dialog):
"""A dialog asking if the user whishes to allow NVDA usage stats to be collected by NV Access."""

This comment has been minimized.

@feerrenrut

feerrenrut May 14, 2018

Contributor

Typo: 'wishes`


@classmethod
def run(self):
d=self(mainFrame)

This comment has been minimized.

@feerrenrut

feerrenrut May 14, 2018

Contributor

You might consider using def runScriptModalDialog in source/gui/__init__ See #6355 (comment)

def run(self):
d=self(mainFrame)
mainFrame.prePopup()
d.Show()

This comment has been minimized.

@feerrenrut

feerrenrut May 14, 2018

Contributor

I would expect this to a be a modal dialog, especially considering there is the option to dismiss it and be reminded later.


remindMeButtonID=wx.NewId()
# Translators: The label of a button to remind the user later about performing some action.
remindMeButton = bHelper.addButton(self, remindMeButtonID, label=_("Remind me &later"))

This comment has been minimized.

@feerrenrut

feerrenrut May 14, 2018

Contributor

I would expect the "remind me later" button to come last, in place of "cancel". Eg "Yes, No, Cancel" -> "Yes, No, Remind me later". Its fine for it to have focus.

To make it last, make it the last call to addButton

sHelper = guiHelper.BoxSizerHelper(self, orientation=wx.VERTICAL)

# Translators: A message asking the user if they want to allow usage stats gathering
message=_("In order to improve NVDA in the future, NV Access wishes to collect usage data from running copies of NVDA. "

This comment has been minimized.

@feerrenrut

feerrenrut May 14, 2018

Contributor

For better formatting, can you add \n\n to the end of this line.

# Translators: A message asking the user if they want to allow usage stats gathering
message=_("In order to improve NVDA in the future, NV Access wishes to collect usage data from running copies of NVDA. "
"Data includes Operating System version, NVDA version, language, country of origin, plus certain NVDA configuration such as current synthesizer, braille display and braille table. "
"No spoken or braille content will be ever sent to NV Access. Please refer to the User Guide for a current list of all data collected.\n"

This comment has been minimized.

@feerrenrut

feerrenrut May 14, 2018

Contributor

Can you also add a blank line here, so \n\n

"Data includes Operating System version, NVDA version, language, country of origin, plus certain NVDA configuration such as current synthesizer, braille display and braille table. "
"No spoken or braille content will be ever sent to NV Access. Please refer to the User Guide for a current list of all data collected.\n"
"Do you wish to allow NV Access to periodically collect this data in order to improve NVDA?")
sHelper.addItem(wx.StaticText(self, label=message))

This comment has been minimized.

@feerrenrut

feerrenrut May 14, 2018

Contributor

Currently this text causes the dialog to expand to the full width of the screen, I would suggest using something like the following so that the lines are wrapped when they hit some max length:

        sText = sHelper.addItem(wx.StaticText(self, label=message))
        # the wx.Window must be constructed before we can get the handle.
        import windowUtils
        self.scaleFactor = windowUtils.getWindowScalingFactor(self.GetHandle())
        sText.Wrap(self.scaleFactor*600) # 600 was fairly arbitrarily chosen by a visual user to look acceptable on their machine.
@@ -61,6 +61,8 @@ def doStartupDialogs():
gui.messageBox(_("Your gesture map file contains errors.\n"
"More details about the errors can be found in the log file."),
_("gesture map File Error"), wx.OK|wx.ICON_EXCLAMATION)
if not config.conf['update']['askedAllowUsageStats']:
gui.AskAllowUsageStatsDialog.run()

This comment has been minimized.

@feerrenrut

feerrenrut May 14, 2018

Contributor

This should probably only ask if updating is turned on? The check box is hidden in that case already right?

In fact, this should probably not be shown unless updating is possible. For instance, when run from the launcher or portable copies.


def onNoButton(self,evt):
log.debug("Usage stats gathering has been disallowed")
config.conf['update']['askedAllowUsageStats']=True
config.conf['update']['allowUsageStats']=False
self.Destroy()
self.EndModal(wx.ID_NO)

def onLaterButton(self,evt):
log.debug("Usage stats gathering question has been deferred")
evt.Skip()

This comment has been minimized.

@feerrenrut

feerrenrut May 14, 2018

Contributor

I'm surprised that you don't need to call EndModal here? Could it be because of the evt.Skip()?

This comment has been minimized.

@feerrenrut

feerrenrut May 14, 2018

Contributor

Why are you calling Skip() on this?

@michaelDCurran

This comment has been minimized.

Copy link
Contributor Author

michaelDCurran commented May 14, 2018

@feerrenrut

This comment has been minimized.

Copy link
Contributor

feerrenrut commented May 14, 2018

Ah yes, I see. I missed the id change for that button. Could you add comment to that effect to that line, just to make it clearer why there is inconsistency with the others. Something like: "evt.Skip() is called since wx.ID_CANCEL is used as the ID for the Ask Later button, wx automatically ends the modal itself."

@feerrenrut
Copy link
Contributor

feerrenrut left a comment

Looks good

michaelDCurran added a commit that referenced this pull request May 15, 2018

@@ -633,6 +633,12 @@ def makeSettings(self, settingsSizer):
if globalVars.appArgs.secure:
item.Disable()
settingsSizerHelper.addItem(item)
# Translators: The label of a checkbox in general settings to toggle allowing of usage stats gathering
item=self.allowUsageStatsCheckBox=wx.CheckBox(self,label=_("Allow the NVDA project to gather NVDA usage statistics"))

This comment has been minimized.

@leonardder

leonardder May 16, 2018

Collaborator

I actually think it makes sense to reposition this checkbox after the notifyForPendingUpdateCheckBox. The current order of check boxes is a bit arbitrary now.

@michaelDCurran michaelDCurran requested a review from leonardder May 16, 2018

@netblue44

This comment has been minimized.

Copy link

netblue44 commented May 18, 2018

@bramd

This comment has been minimized.

Copy link
Contributor

bramd commented May 18, 2018

@netblue44

This comment has been minimized.

Copy link

netblue44 commented May 18, 2018

leonardder added a commit that referenced this pull request May 21, 2018

Incubates #8217.
Merge remote-tracking branch 'origin/pr/8217' into next

@michaelDCurran michaelDCurran merged commit e791c8d into master Jun 17, 2018

1 check passed

continuous-integration/appveyor/pr AppVeyor build succeeded
Details

@nvaccessAuto nvaccessAuto added this to the 2018.3 milestone Jun 17, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.