diff --git a/build/common.gypi b/build/common.gypi index 8789ef12a55533..0879daca73c9af 100644 --- a/build/common.gypi +++ b/build/common.gypi @@ -1395,6 +1395,10 @@ 'ozone_platform_ozonex%': 0, 'ozone_platform_test%': 0, + # Chrome OS: whether to also build the upcoming version of + # ChromeVox, which can then be enabled via a command-line switch. + 'use_chromevox_next%': 0, + 'conditions': [ # Enable the Syzygy optimization step for the official builds. ['OS=="win" and buildtype=="Official" and syzyasan!=1', { diff --git a/chrome/browser/browser_resources.grd b/chrome/browser/browser_resources.grd index 346964c4ae167f..21f77c3ffe5718 100644 --- a/chrome/browser/browser_resources.grd +++ b/chrome/browser/browser_resources.grd @@ -297,6 +297,7 @@ + diff --git a/chrome/browser/extensions/component_loader.cc b/chrome/browser/extensions/component_loader.cc index facaf8eb7b9bba..99129d8cb5d646 100644 --- a/chrome/browser/extensions/component_loader.cc +++ b/chrome/browser/extensions/component_loader.cc @@ -330,6 +330,11 @@ std::string ComponentLoader::AddChromeVoxExtension() { const CommandLine* command_line = CommandLine::ForCurrentProcess(); int idr = command_line->HasSwitch(chromeos::switches::kGuestSession) ? IDR_CHROMEVOX_GUEST_MANIFEST : IDR_CHROMEVOX_MANIFEST; + + // TODO(dtseng): Guest mode manifest for ChromeVox Next pending work to + // generate manifests. + if (command_line->HasSwitch(chromeos::switches::kEnableChromeVoxNext)) + idr = IDR_CHROMEVOX2_MANIFEST; return Add(idr, base::FilePath(extension_misc::kChromeVoxExtensionPath)); } diff --git a/chrome/browser/resources/chromeos/chromevox2/OWNERS b/chrome/browser/resources/chromeos/chromevox2/OWNERS new file mode 100644 index 00000000000000..dfab84a016434b --- /dev/null +++ b/chrome/browser/resources/chromeos/chromevox2/OWNERS @@ -0,0 +1,4 @@ +aboxhall@chromium.org +dmazzoni@chromium.org +dtseng@chromium.org +plundblad@chromium.org diff --git a/chrome/browser/resources/chromeos/chromevox2/chromevox.gyp b/chrome/browser/resources/chromeos/chromevox2/chromevox.gyp new file mode 100644 index 00000000000000..5772ca077a0821 --- /dev/null +++ b/chrome/browser/resources/chromeos/chromevox2/chromevox.gyp @@ -0,0 +1,31 @@ +# Copyright 2014 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +{ + 'conditions': [ + ['chromeos==1 and disable_nacl==0 and disable_nacl_untrusted==0', { + 'targets': [ + { + 'target_name': 'chromevox2_resources', + 'type': 'none', + 'copies': [ + { + 'destination': '<(PRODUCT_DIR)/resources/chromeos/chromevox/cvox2/background', + 'files': [ + 'cvox2/background/background.html', + 'cvox2/background/background.js', + ], + }, + { + 'destination': '<(PRODUCT_DIR)/resources/chromeos/chromevox/cvox2/injected', + 'files': [ + 'cvox2/injected/injected.js', + ], + }, + ], + }, + ], + }], + ], +} diff --git a/chrome/browser/resources/chromeos/chromevox2/cvox2/background/background.html b/chrome/browser/resources/chromeos/chromevox2/cvox2/background/background.html new file mode 100644 index 00000000000000..429931d816d733 --- /dev/null +++ b/chrome/browser/resources/chromeos/chromevox2/cvox2/background/background.html @@ -0,0 +1,5 @@ + + + + + diff --git a/chrome/browser/resources/chromeos/chromevox2/cvox2/background/background.js b/chrome/browser/resources/chromeos/chromevox2/cvox2/background/background.js new file mode 100644 index 00000000000000..dcd93fbbd7323d --- /dev/null +++ b/chrome/browser/resources/chromeos/chromevox2/cvox2/background/background.js @@ -0,0 +1,93 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/** + * @fileoverview The entry point for all ChromeVox2 related code for the + * background page. + */ + +/** ChromeVox2 namespace */ +var cvox2 = function() {}; + +/** Namespace for global objects in the background page. */ +cvox2.global = function() {}; + +/** Classic Chrome accessibility API. */ +cvox2.global.accessibility = + chrome.accessibilityPrivate || chrome.experimental.accessibility; + +/** + * ChromeVox2 background page. + */ +cvox2.Background = function() { + // Only needed with unmerged ChromeVox classic loaded before. + cvox2.global.accessibility.setAccessibilityEnabled(false); + chrome.automation.getDesktop(this.onGotDesktop.bind(this)); +}; + +cvox2.Background.prototype = { + /** + * ID of the port used to communicate between content script and background + * page. + * @const {string} + */ + PORT_ID: 'chromevox2', + + /** + * Waits until a desktop automation tree becomes available. + * Thereafter, registers a simple exploration mode for the desktop tree. + * @param {AutomationTree} tree The desktop automation tree. + */ + onGotDesktop: function(tree) { + if (!tree.root) { + window.setTimeout(this.onGotDesktop, 500); + return; + } + chrome.extension.onConnect.addListener(function(port) { + if (port.name != this.PORT_ID) + return; + var cur = tree.root; + port.onMessage.addListener(function(message) { + switch (message.keydown) { + case 37: + cur = cur.previousSibling() || cur; + break; + case 38: + cur = cur.parent() || cur; + break; + case 39: + cur = cur.nextSibling() || cur; + break; + case 40: + cur = cur.firstChild() || cur; + break; + } + var index = 1; + if (cur.parent()) + index = cur.parent().children().indexOf(cur) + 1; + var name = ''; + if (cur.attributes && cur.attributes['ax_attr_name']) + name = cur.attributes['ax_attr_name']; + var utterance = index + ' ' + name + cur.role; + chrome.tts.speak(String(utterance), {lang: 'en-US'}); + }); + }.bind(this)); + + // Register all automation event listeners. + tree.root.addEventListener('focus', this.onDesktopEvent.bind(this), true); + }, + + /** + * A generic handler for all desktop automation events. + * @param {AutomationEvent} evt The event. + */ + onDesktopEvent: function(evt) { + var output = evt.target.attributes.name + ' ' + evt.target.role; + cvox.ChromeVox.tts.speak(output); + cvox.ChromeVox.braille.write(cvox.NavBraille.fromText(output)); + } +}; + +/** @type {cvox2.Background} */ +cvox2.global.backgroundObj = new cvox2.Background(); diff --git a/chrome/browser/resources/chromeos/chromevox2/cvox2/injected/injected.js b/chrome/browser/resources/chromeos/chromevox2/cvox2/injected/injected.js new file mode 100644 index 00000000000000..2174053ec910c1 --- /dev/null +++ b/chrome/browser/resources/chromeos/chromevox2/cvox2/injected/injected.js @@ -0,0 +1,19 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/** + * @fileoverview The entry point for all ChromeVox2 related code for the + * injected content script. + * This script will temporarily forward any events we need during the + * ChromeVox/ChromeVox2 timeframe where extension APIs do not exist (e.g. + * keyboard events). + */ + +/** namespace */ +var cvox2 = function() {}; + +var port = chrome.extension.connect({name: 'chromevox2'}); +document.body.addEventListener('keydown', function(evt) { + port.postMessage({keydown: evt.keyCode}); +}, true); diff --git a/chrome/browser/resources/chromeos/chromevox2/manifest.json b/chrome/browser/resources/chromeos/chromevox2/manifest.json new file mode 100644 index 00000000000000..259514eb386b7c --- /dev/null +++ b/chrome/browser/resources/chromeos/chromevox2/manifest.json @@ -0,0 +1,38 @@ +{ + "key": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDltVl1k15pjRzuZfMc3B69inxwm2bZeZ2O8/zFO+NluHnBm3GJ3fzdOoFGJd+M16I8p7zxxQyHeDMfWYASyCeB8XnUEDKjqNLQfCnncsANzHsYoEbYj2nEUML2P13b9q+AAvpCBpAJ4cZp81e9n1y/vbSXHE4385cgkKueItzikQIDAQAB", + "manifest_version": 2, + "name": "ChromeVox", + "version": "1.0", + "description": "ChromeVox - Giving Voice to Chrome.", + "background": { + "page": "cvox2/background/background.html" + }, + "content_scripts": [ + { + "matches": [ "" ], + "exclude_globs": [ "chrome-extension://mndnfokpggljbaajbnioimlmbfngpief/chromevox/background/background.html" ], + "all_frames": true, + "js": [ + "cvox2/injected/injected.js" + ] + } + ], + "permissions": [ + "accessibilityPrivate", + "automation", + "bookmarks", + "tabs", + "experimental", + "history", + "tts", + "systemPrivate", + "brailleDisplayPrivate", + "commandLinePrivate", + "" + ], + "automation": { + "desktop": true, + "interact": true + }, + "default_locale": "en" +} diff --git a/chrome/chrome_resources.gyp b/chrome/chrome_resources.gyp index b6e48ac7588dfa..630d9434862a43 100644 --- a/chrome/chrome_resources.gyp +++ b/chrome/chrome_resources.gyp @@ -114,6 +114,14 @@ ], }], ['chromeos==1 and disable_nacl==0 and disable_nacl_untrusted==0', { + 'conditions': [ + # TODO(dtseng): Remove use_chromevox_next once ChromeVox Next is ready for testing. + ['use_chromevox_next==1', { + 'dependencies': [ + 'browser/resources/chromeos/chromevox2/chromevox.gyp:chromevox2_resources', + ], + }], + ], 'copies' : [ { 'destination': '<(PRODUCT_DIR)/resources/chromeos/braille_ime', diff --git a/chromeos/chromeos_switches.cc b/chromeos/chromeos_switches.cc index 91c825f4d5c9ad..7b83453a39ab07 100644 --- a/chromeos/chromeos_switches.cc +++ b/chromeos/chromeos_switches.cc @@ -68,6 +68,10 @@ const char kEchoExtensionPath[] = "echo-ext-path"; // Enables switching between different cellular carriers from the UI. const char kEnableCarrierSwitching[] = "enable-carrier-switching"; +// Enables the next generation version of ChromeVox. Only valid with +// use_chromevox_next=1 within your GYP_DEFINES. +const char kEnableChromeVoxNext[] = "enable-chromevox-next"; + // Enables consumer management, which allows user to enroll, remotely lock and // locate the device. const char kEnableConsumerManagement[] = "enable-consumer-management"; diff --git a/chromeos/chromeos_switches.h b/chromeos/chromeos_switches.h index a2a12680236152..5db10832e5f4a7 100644 --- a/chromeos/chromeos_switches.h +++ b/chromeos/chromeos_switches.h @@ -38,6 +38,7 @@ CHROMEOS_EXPORT extern const char kDisableQuickofficeComponentApp[]; CHROMEOS_EXPORT extern const char kDisableVolumeAdjustSound[]; CHROMEOS_EXPORT extern const char kEchoExtensionPath[]; CHROMEOS_EXPORT extern const char kEnableCarrierSwitching[]; +CHROMEOS_EXPORT extern const char kEnableChromeVoxNext[]; CHROMEOS_EXPORT extern const char kEnableConsumerManagement[]; CHROMEOS_EXPORT extern const char kEnableFileManagerMTP[]; CHROMEOS_EXPORT extern const char kEnableRollbackOption[];