Repository: nvaccess/nvda

Issue:
Add a checkbox in NVDA prefferences to activate java access bridge for 32 and 64bit
### Steps to reproduce:


### Expected behavior:
In order to simplify the settings process to make NVDA work properly in as many applications as possible, NVDA should allow the user to easily activate both access bridge versions. In Window Eyes a short script was integrated which could activate both access bridge versions. This script is a .exe file and is still working even when the user is working on a client. So you don't need admin rights to run it. NVDA could activate the access bridge automatically at start, or manually through a checkbox in general settings.


### Actual behavior:
As of now, the user must activate both access bridge versions manually. In internet there are tutorials about how to do it in windows Powershell. But for beginners this is not very intuitive. Moreover, to access the powershell you often need admin rights, especially in professional environments. Additionally, on many clients the windows accessibility settings are blocked. A NVDA user cannot change them.


### System configuration:
NVDA version:
all


NVDA Installed or portable:
Both

Other information:


Windows version:
All

Name and version of other software in use when reproducing the issue:

### Other questions:

Does the issue still occur after restarting your PC?
Yes

Have you tried any other versions of NVDA?
n/a


Discussion:
If Access bridge cannot be activated, NVDA could display a short message which shows the most probable reasons (i.e. Java 32bit is missing, no Java installed etc.)
I agree this issue.
@Adriani90: You are stating that it is quite difficult to enable the Java Access Bridge, but I've always been able to do this reliably from the ease of access center in the control panel. For me, this is a viable solution.
Not if you are not admin.

Von meinem iPhone gesendet

> Am 05.02.2018 um 17:06 schrieb Leonard de Ruijter <notifications@github.com>:
> 
> @Adriani90: You are stating that it is quite difficult to enable the Java Access Bridge, but I've always been able to do this reliably from the ease of access center in the control panel. For me, this is a viable solution.
> 
> —
> You are receiving this because you were mentioned.
> Reply to this email directly, view it on GitHub, or mute the thread.
> 

I recall enabling the access bridge in an environment without administrative privileges.

> Op 5 feb. 2018 om 18:41 heeft Adriani90 <notifications@github.com> het volgende geschreven:
> 
> Not if you are not admin.
> 
> Von meinem iPhone gesendet
> 
> > Am 05.02.2018 um 17:06 schrieb Leonard de Ruijter <notifications@github.com>:
> > 
> > @Adriani90: You are stating that it is quite difficult to enable the Java Access Bridge, but I've always been able to do this reliably from the ease of access center in the control panel. For me, this is a viable solution.
> > 
> > —
> > You are receiving this because you were mentioned.
> > Reply to this email directly, view it on GitHub, or mute the thread.
> > 
> —
> You are receiving this because you commented.
> Reply to this email directly, view it on GitHub, or mute the thread.
> 

For example for me it is not possible to activate the access bridge at work because the accessibility settings are not displayed on my user account. So I am using the script from Window Eyes which activates both versions automatically. This is very important since for some reason the java access bridge is being disable after restarting the PC. It seems that Window Eyes had the access bridge installation integrated in it core. See this link:
https://www.gwmicro.com/Window-Eyes/Manual/Guides/Window-Eyes%20Installation%20Guide.txt

It would be a very nice feature since actually it is related to screen readers. I don't understand why the access bridge should not be automatically activated by the screen reader. At least providing a checkbox during the installation process or in the settings should be standard.
cc: @jcsteh is this something that you think could be implemented along with the bundling of Access Bridge dll? Or should we Close it? In my opinion this would bring benefits, especially for beginners.
Particularly given that some apps now bundle their own Java VM and given that many JREs don't provide an installer (official OpenJDK is just a zip file, for example), doing this from Ease of Access isn't possible for many users. I think NVDA should take care of this somehow, although the exact user experience is an open question.

I'm tempted to suggest that NVDA should just do this without asking the user, but when?

1. The intuitive answer is during installation, but JAB can't be activated system wide; it must be activated for each user. Since installation is system wide, that isn't an option.
2. There's no per-user installation after each update, so that isn't an option.
3. We could do it at startup, probably as part of JABHandler initialisation. The check and change isn't expensive. However, this doesn't help any Java apps that are already running.
4. We could add a configuration option. Users will probably end up wondering why it isn't just enabled by default, though. And if we do enable it by default, we'll have to check it and apply it at startup anyway, so we may as well just do 3).
5. We could add something in the Tools menu. This makes it explicit that it's a one-off task, not so much a configuration thing.

@MichaelDCurran, thoughts?

As to how you actually enable this, you just create a file called .accessibility.properties in the user profile directory (%userprofile%) with the following text:
```
assistive_technologies=com.sun.java.accessibility.AccessBridge
screen_magnifier_present=true
```
(This is what jabswitch does.)
I think doing it at NVDA start-up is the best solution.

Note this should only be done for installed copies, not appx or portable.




Resolving patch:
diff --git a/source/JABHandler.py b/source/JABHandler.py
--- a/source/JABHandler.py
+++ b/source/JABHandler.py
@@ -39,6 +39,17 @@
 import core
 import textUtils
 import NVDAHelper
+import config
+import globalVars
+
+#: The path to the user's .accessibility.properties file, used
+#: to enable JAB.
+A11Y_PROPS_PATH = os.path.expanduser(r"~\.accessibility.properties")
+#: The content of ".accessibility.properties" when JAB is enabled.
+A11Y_PROPS_CONTENT = (
+	"assistive_technologies=com.sun.java.accessibility.AccessBridge\n"
+	"screen_magnifier_present=true\n"
+)
 
 #Some utility functions to help with function defines
 
@@ -738,6 +749,24 @@ def isJavaWindow(hwnd):
 		return False
 	return bridgeDll.isJavaWindow(hwnd)
 
+
+def isBridgeEnabled():
+	try:
+		data = open(A11Y_PROPS_PATH, "rt").read()
+	except OSError:
+		return False
+	return data == A11Y_PROPS_CONTENT
+
+
+def enableBridge():
+	try:
+		props = open(A11Y_PROPS_PATH, "wt")
+		props.write(A11Y_PROPS_CONTENT)
+		log.info("Enabled Java Access Bridge for user")
+	except OSError:
+		log.warning("Couldn't enable Java Access Bridge for user", exc_info=True)
+
+
 def initialize():
 	global bridgeDll, isRunning
 	try:
@@ -746,6 +775,11 @@ def initialize():
 	except WindowsError:
 		raise NotImplementedError("dll not available")
 	_fixBridgeFuncs()
+	if (
+		not globalVars.appArgs.secure and config.isInstalledCopy()
+		and not isBridgeEnabled()
+	):
+		enableBridge()
 	# Accept wm_copydata and any wm_user messages from other processes even if running with higher privileges
 	if not windll.user32.ChangeWindowMessageFilter(winUser.WM_COPYDATA, 1):
 		raise WinError()


Test patch: