Compare commits

..
359 Commits
Author SHA1 Message Date
Moonchild 2694995e52 Merge branch 'master' into 1210 2022-05-21 16:38:37 +00:00
FranklinDM 00c51f75fa No issue - Add null check to send packet function in the developer tools server
This resolves some of the useless log spam thrown in the browser console by the developer tools.
2022-05-21 16:37:38 +00:00
Moonchild addadda237 Merge pull request 'Implement nullish coalescing operator' (#1901) from FranklinDM/UXP-contrib:work_js-nullish-coalescing into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/1901
Reviewed-by: Moonchild <moonchild@palemoon.org>
2022-05-21 10:24:26 +00:00
Moonchild f532bbd7af Issue #1210 - Simplify the implementation of mozILocaleService.
Combine both GetAppLocale methods and Update
mozILocaleService.getAppLocales to avoid use of jsapi.
2022-05-21 09:18:08 +00:00
FranklinDM 0efc152b07 Issue #1894 - Part 7: Update tests
Based on https://bugzilla.mozilla.org/show_bug.cgi?id=1566141
2022-05-21 01:09:51 +08:00
FranklinDM 8618fcbe89 Issue #1894 - Part 6: Check for nullish values when folding coalesce nodes
This uses a different approach by modifying the `Boolish` function directly to act differently if we're checking for nullish values.

Partially based on:
Bug 1566141 - Implement the Nullish Coalescing operator (??) proposal
Bug 1599163 - Nullish coalescing operator returns undefined for void expressions
2022-05-21 01:02:24 +08:00
FranklinDM 20ee1ece01 Issue #1894 - Part 5: Implement bytecode for nullish coalescing
Based on https://bugzilla.mozilla.org/show_bug.cgi?id=1566141
2022-05-21 01:02:23 +08:00
FranklinDM bbe40dab58 Issue #1894 - Part 4: Implement IonMonkey support for nullish coalescing
Based on https://bugzilla.mozilla.org/show_bug.cgi?id=1566141
2022-05-21 01:02:22 +08:00
FranklinDM 5e500dc2b4 Issue #1894 - Part 3: Implement support for nullish coalescing in JS reflection
Partially based on:
Bug 1566141 - Implement the Nullish Coalescing operator (??) proposal
Bug 1593415 - Assertion failure: false, at js/src/builtin/ReflectParse.cpp:3092 with nullish coalescing
2022-05-21 01:02:22 +08:00
FranklinDM 5d6ae8b156 Issue #1894 - Part 2: Implement support for nullish coalescing in the JS parser
Based on https://bugzilla.mozilla.org/show_bug.cgi?id=1566141
2022-05-21 01:02:21 +08:00
FranklinDM 99f31e38ba Issue #1894 - Part 1: Implement coalesce JS opcode
Based on https://bugzilla.mozilla.org/show_bug.cgi?id=1566141
2022-05-21 01:02:16 +08:00
Moonchild e4bf79f912 Issue #1210 - Expose mozILocaleService Cc interface 2022-05-20 01:02:52 +00:00
Moonchild e1f95393a1 Issue #1210 - Expose getAppLocales() to Chrome and XBL
This allows JS to access the application locales.
2022-05-19 22:37:20 +00:00
Moonchild b2eff33c92 Issue #1210 - Introduce an internal API to get configured application locales.
en-US will always be added as a fallback, to make things simpler down the line
and avoid error checking all over the place.
2022-05-19 21:57:58 +00:00
Moonchild 51117c2b62 Bug 1679987 - Remove unused includes of nsCharSeparatedTokenizer.h. 2022-05-17 19:42:24 +00:00
Moonchild 991b053042 Merge pull request 'Add support for MP4 playback on Linux via FFmpeg 5.0' (#1900) from trav90/UXP-contrib:ffmpeg-work into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/1900
2022-05-17 19:22:18 +00:00
Moonchild 1bf41a59b9 Issue #1210 - Keep timepicker disabled for now.
This needs localization work before enabling.
2022-05-16 20:12:09 +00:00
Moonchild 86db73b5d1 Issue #1813 - Enable date and time picker by default.
Resolves #1813
2022-05-16 20:08:29 +00:00
trav90 f302cc1391 Issue #1893 - Part 3: Update audio & video decoders for FFmpeg 5.0
FFmpeg 5.0 removed some deprecated symbols so we need to update our decoding code to account for it.
2022-05-16 10:58:20 -05:00
trav90 cb0f8292a6 Issue #1893 - Part 2: Add support for libavcodec 59/FFmpeg 5.0 2022-05-16 10:55:57 -05:00
trav90 4e03bfdec8 Issue #1893 - Part 1: Import required FFmpeg 5.0 header files 2022-05-16 10:53:55 -05:00
FranklinDM bdfd859beb Issue #1898 - Make sure that the sanity test stops running if necessary
As part of telemetry removal, d60103257e removed the `reportResult` function which also handles the stopping of the sanity test. This also removes unused histogram enumeration values and revises/adds some comments.
2022-05-15 14:48:09 +00:00
Moonchild 5338dcd132 Issue #1899 - Make sure the test for it still works
Some hoops to make sure the test still works if the default value for the pref
is false, requiring setting and resetting it and making sure the observers have
time to react to these changes before testing.
2022-05-14 12:22:48 +00:00
Moonchild a9d3c2b52a Issue #1899 - Disable the (broken) MDN integration widget by default. 2022-05-14 11:06:02 +00:00
Moonchild 517aec3111 Issue #1509 - Invalidate previous result when datalist is changed.
Even if `<datalist>` is dynamically changed, the autocomplete controller still
uses the previous search result. If changed, we have to ignore the previous
result that may now be invalid.

Also, even if `<datalist>` is changed, we have to keep the selected index
(See Mozilla Bug 595069), so we cannot use `ResetInternalState` in this
situation because it resets the selected index.

This resolves #1509.
2022-05-10 21:03:53 +00:00
Moonchild 930ddd693b No Issue - Break overly long tooltips into multiple lines.
A very very old bug and annoyance: tooltips with very long content without
spaces (e.g. long URLs or gibberish data) would just cut off and leave an
un-styled right border going over the widget's constrained space.
Because of an additional bug (still unsolved), this was never properly
addressed because solutions attempted didn't work.
The workaround for the secondary bug allows for word-break to now work and this
primary problem to be resolved.
2022-05-08 21:07:03 +00:00
Moonchild 4cdd532738 Merge pull request 'Fix ASAN and clang crashes on Linux, BSD and MacOS.' (#1892) from dbsoft/UXP:fixxptcinvoke into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/1892
2022-05-08 11:52:32 +00:00
Moonchild 6f8d063b18 Issue #1895 - Implement queueMicroTask(callback()) 2022-05-07 14:39:41 +00:00
Brian Smith b1957eb7c9 Issue #1891 - Fix ASAN and clang crashes on Linux, BSD and MacOS.
Merge with the existing Solaris fix, by folding Solaris into the Linux/BSD section.
Add Apple Silicon (ARM64) support.
This should also address Issue #1884 by moving the offending code into assembly.
2022-05-05 15:53:25 -05:00
Moonchild a5b4a440d6 Update NSS to 3.52.5
- Default configure to enable dbm
- Remove a redundant check on ASN1 decoding (Bug 1753535)
2022-05-04 22:44:31 +00:00
Moonchild 9a84af4d5b Bug 1761981 2022-05-04 22:00:02 +00:00
Moonchild eecc234b44 No issue - Align our resource timing with the updated Fetch spec.
This makes FetchStart use StartTime() when the TAO check fails for
PerformanceResourceTiming

Given the recent Fetch spec updates, Step 8.1 in
https://fetch.spec.whatwg.org/#finalize-and-report-timing specifies that start
time(StartTime) and post-redirect start time(FetchStart) should be start time
when the TAO check fails.
2022-05-04 17:24:10 +00:00
Moonchild 2366accae5 Issue #1890 - Update libopus
This resolves #1890
2022-05-04 17:03:37 +00:00
Stephen A Pohl d01ae5cf25 [XPCOM] Improve the conversion of line breaks.
Fix an off-by-one error in CRLF checking.
2022-05-04 13:54:20 +00:00
Moonchild 92b3def6a8 Merge pull request 'Implement optional chaining' (#1889) from FranklinDM/UXP-contrib:work_js-optional-chaining into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/1889
2022-05-04 10:42:06 +00:00
FranklinDM 006b8f5c6e Issue #1658 - Part 8: Update tests 2022-05-04 14:57:19 +08:00
FranklinDM 152974a8fe Issue #1658 - Part 7: Implement support for optional chaining in console autocomplete
This works by stripping the optional chaining characters from the completion part variable, allowing the developer tools' parser to proceed as if it were a regular, non-optional expression.

Tests were partially based on: https://bugzilla.mozilla.org/show_bug.cgi?id=1594009

Tests for features that do not apply to our version of developer tools (e.g. autocomplete for integer literals, ignoring spaces between property accessors, etc) were excluded.
2022-05-04 14:57:19 +08:00
FranklinDM 6d480d82a5 Issue #1658 - Part 6: Break and return no control flow for jumps emitted by optional chains under IonBuilder
IIUC, we want to process the GOTO in the case of optional chains, and we do not satisfy the requirements mentioned in the comment of snoopControlFlow's caller. Optional chains are not loops, we (probably) don't have a loop in the instruction following the GOTO, and in the GOTO destination, we're either returning an undefined/null value or the actual value.
2022-05-04 14:57:18 +08:00
FranklinDM fa72aef363 Issue #1658 - Part 5: Add and initialize TDZ check to optional chaining emitter
Partially based on: https://bugzilla.mozilla.org/show_bug.cgi?id=1685260
2022-05-04 14:57:18 +08:00
FranklinDM 2ed7526705 Issue #1658 - Part 4: Fix optional chaining assertions and remove unreachable code
This includes the following:

Bug 1611777 - Part 1: Report syntax error for optional property access in self-hosting code. r=yulia!
Bug 1611777 - Part 2: Merge same blocks in emitDeleteOptionalChain(). r=yulia!
Bug 1611777 - Part 3: N/A
Bug 1611777 - Part 4: `super` can't occur on the left-hand side of an optional chain
Bug 1611777 - Part 5: Remove unnecessary super-handling in optional delete. r=yulia!
The child node of a DeleteOptionalChainExpr node can't be a super-property
accessor, so we can remove this code.

Bug 1611777 - Part 6: Crash for unexpected super-base in optional call. r=yulia!
Bug 1611777 - Part 7: Add missing entries to list of valid optional chain start expressions. r=yulia!
Bug 1611777 - Part 8: Add missing emitGet in emitOptionalElemExpression. r=yulia!
Aligns emitOptionalElemExpression() with emitOptionalDotExpression(), so it's
easier to compare both methods against each other.

Bug 1611777 - Part 9: Replace an if-statement with an assertion. r=yulia!
Bug 1611777 - Part 10: N/A
Bug 1611777 - Part 11: Support optional chaining in class heritage expression. r=yulia!
Bug 1611777 - Part 12: Use optionalExpr() for update expressions to match spec grammar. r=yulia!

Using optionalExpr matches the spec grammar more closely. This change also
modifies the reported error message. ++a?.b reported before this change
"unexpected token: '?.'", but now reports "invalid increment/decrement operand".

Bug 1611777 - Part 13: N/A
Bug 1611777 - Part 14: Simplify two lines in optionalExpr(). r=yulia!

We don't need to test for tt == TokenKind::Eof when we return for tt != TokenKind::OptionalChain anyway. Omit local variable for the result value and instead use a tail-call. This matches the local style in the parser more closely.

Bug 1611777 - Part 15: Support FunCall/FunApply optimisations for optional chaining. r=yulia!
Bug 1611777 - Part 16: Pass through ValueUsage in optional chains. r=yulia
2022-05-04 14:57:17 +08:00
FranklinDM 9ecfdbe358 Issue #1658 - Part 3: Implement support for optional chaining in JS reflection
Partially based on:
Bug 1610447 - Update Reflect to handle Optional Chaining operator
Bug 1657835 - Assertion failure: false, at js/src/builtin/ReflectParse.cpp:3168
2022-05-04 14:57:16 +08:00
FranklinDM 97dcd8009a Issue #1658 - Part 2: Implement bytecode for optional chaining
Partially based on:
Bug 1566143 - Implement the Optional Chaining operator (?.) proposal
Bug 1650340 - Fix deleteElementInOptionalChain
Bug 1644839 - Fix return value of emitOptionalChain on failure
2022-05-04 14:57:16 +08:00
FranklinDM e1fc99d6ef Issue #1658 - Part 1: Implement support for optional chaining in the JS Parser
Partially based on: https://bugzilla.mozilla.org/show_bug.cgi?id=1566143
2022-05-04 14:57:15 +08:00
athenian200 0de24cc207 Merge pull request 'Allow /bin/sh to be used as a fallback value when SHELL is not set.' (#1888) from athenian200/UXP:shell_detection into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/1888
2022-05-04 01:05:04 +00:00
Jeremy Andrews 28ad4a4b7c Issue #1887 - Allow /bin/sh to be used as a fallback value when SHELL is not set. 2022-05-03 20:01:09 -05:00
Moonchild f41a43acf2 Revert "No Issue - Make content-type on JAR channels behave the same as HTTP channels."
This reverts commit 425677ada7.
2022-05-03 17:37:28 +00:00
Moonchild 1dd2c05377 Update 7zSD for v31 2022-05-03 17:07:38 +02:00
Moonchild f48c32ebc1 New cycle master 2022-05-03 11:27:24 +00:00
FranklinDM b0b90b81f3 [Toolkit] Set an icon for the default handler 2022-05-03 11:15:20 +00:00
Moonchild 6f9c302a32 Issue #1860 - Back out the change to vector for DisplayLists
A safe implementation means significant performance loss, making this change
undesirable.
2022-05-03 11:10:30 +00:00
FranklinDM a3bee9a6a8 Issue #1860 - Follow-up: Prevent duplicate display items by checking for its existence in the vector first before adding items
Performance impact unknown, resolves crashes on some sites that encounter this scenario.
2022-05-03 09:18:48 +00:00
FranklinDM 26d1ff2bd6 Issue #21 - Remove run phase property and constants from XPIProvider.jsm
These were introduced in Bug 853388 for the sole purpose of tracking the current startup phase for telemetry
2022-05-03 09:15:47 +00:00
FranklinDM 825ae7cb05 Regenerate developer tools' static CSS properties database 2022-05-03 09:15:15 +00:00
FranklinDM 2302734e6f Fix property alias indentation 2022-05-03 09:15:05 +00:00
FranklinDM 40c0791320 Fix generation of developer tools' static CSS properties database
- Remove `resolve_path` method and use `mozpath` instead for path operations
- Store target developer tools path as an instance variable to avoid duplicate checks for path existence
2022-05-03 09:14:57 +00:00
FranklinDM ab0be54f2d Issue #1853 - Follow-up: Add missing end of array marker to scrollbar width keyword table
This prevents the parser from accepting values outside the keyword table.
2022-05-03 09:14:47 +00:00
Moonchild 6b4ef9af48 Merge branch 'vpx-format-update' 2022-05-02 00:16:10 +00:00
Moonchild 425677ada7 No Issue - Make content-type on JAR channels behave the same as HTTP channels.
That is, treat it as a hint if called before open, and as an override if called
after. Override the hint on open.
2022-05-01 12:15:08 +00:00
Moonchild 633728842e Merge branch 'master' into vpx-format-update 2022-05-01 09:28:43 +00:00
Moonchild bc2841f9f9 Merge pull request 'Restore Mac OS X code and buildability' (#1886) from dbsoft/UXP:1829 into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/1886
2022-04-29 07:20:46 +00:00
Brian Smith d78e03d528 Merge branch 'master' into 1829
* master:
  No issue - Update README and SECURITY
  Issue #1885 - Follow-up: Update error message if invalid rootMargin specified.
  Issue #1879 - Follow-up: Update config/external/nss/target to security/target.
  Issue #1885 - Allow unitless rootMargin entries for IntersectionObserver.
  Issue #1879 - Revert changes to cryptox.h
  Revert "Issue #1879 - spot-fix typo in cryptox.h"
  Issue #1879 - spot-fix typo in cryptox.h
  Issue #21 - Change MappedAttrParser to store its nsIPrincipal instead of nsSVGElement
  Issue #21 - Remove use counters telemetry
  Issue #1881 - Interpret empty or whitespace root margin string as zero length
  Issue #1877 - Resolve NIGHTLY_BUILD conditionals.
  Issue #1880 - Boot Comic Sans out of the font configuration.
2022-04-28 20:27:47 -05:00
Brian Smith bebeb4e26a Issue #1829 - Build system fixes.
Readd de-unified source changes that got clobbered by commit 378738aaa9.
Fix build issues using clang broken by commit 39f9ab375b.
2022-04-28 14:21:17 -05:00
Moonchild bf110158b9 Issue #1820 - Part 8: Check bit depth in PDM::Supports. 2022-04-27 16:08:36 +00:00
Moonchild 983a87a9d7 Issue #1820 - Part 7: Check bit depth in WebMDecoder to determine if we support HDR. 2022-04-27 12:34:59 +00:00
Moonchild bf8359c704 Issue #1820 - Part 6: Extract bit depth information from codec parameter string
into VideoInfo::mBitDepth.
2022-04-27 12:34:26 +00:00
Moonchild 4e5b100cca Issue #1820 - Part 5: Add mBitDepth field to VideoInfo. 2022-04-27 11:12:39 +00:00
Moonchild a874f27b5a Issue #1820 - Part 4: Add a gtest for testing the extraction function. 2022-04-27 11:03:38 +00:00
Moonchild 6b2f1524f8 Issue #1820 - Part 3: Use Codec detail extractor helper to tell if it's a new
style VP8/VP9 codec string.
2022-04-27 10:28:18 +00:00
Moonchild 93b170e629 Issue #1820 - Part 2: Add VP9-in-MP4 support to the decoder
This also adds support in StageFright for VP9.0 FourCCs and consolidates
individual string checks to helpers for WebM
2022-04-27 10:27:49 +00:00
Moonchild 33523f5d5e No issue - Update README and SECURITY
- thereisonlyxul is no longer a thing.
- minor wording update.
2022-04-27 00:14:54 +00:00
Brian Smith 1eaadfbc8d Issue #1829 - Readd code cleanup that is not Mac related that got clobbered by reverting Issue #1751 2022-04-26 15:57:19 -05:00
Brian Smith 0102047d68 Issue #1829 - Fix psutil python extension on MacOS and potentially FreeBSD
Compilation failed due to missing sys/ioctl.h header on MacOS and FreeBSD. Call to function ioctl() with no prototype.  This was non-fatal due to the psutil component being optional.
2022-04-26 13:26:41 -05:00
Brian Smith b07c898b06 Issue #1829 - Readd a fix for Big Sur not loading libraries such as OpenGL.
This fix was included earlier but got clobbered by a recent NSPR update.
2022-04-26 13:25:29 -05:00
Brian Smith 6dd43c3e2f Issue #1829 - Fix Mac breakage due to removal of Telemetry. 2022-04-26 13:24:10 -05:00
Moonchild b9b1abc871 Issue #1820 - Part 1 : Add an extraction function to parse the RFC-6381 VP9 codec string. 2022-04-26 17:32:29 +00:00
Brian Smith 768231cf6a Issue #1829 - Revert "Issue #1751 - Remove MacOS support from configure"
This reverts commit d3543ca2fe.
2022-04-26 11:34:08 -05:00
Brian Smith c82b759d56 Issue #1829 - Revert "Issue #1751 -- Remove XP_MACOSX conditionals from /dom"
This reverts commit 0dd3424f77.
2022-04-26 11:24:42 -05:00
Brian Smith 9e2a89c71d Issue #1829 - Revert "Issue #1751 -- Remove XP_DARWIN"
This reverts commit 3d671e4275.
2022-04-26 11:07:23 -05:00
Brian Smith 68d1c14bdf Issue #1829 - Revert "Issue #1751 -- Remove files unused without XP_DARWIN"
This reverts commit cd1f724135.
2022-04-26 11:01:55 -05:00
Brian Smith b73c17b7c6 Issue #1829 - Revert "Issue #1751 -- Remove XP_MACOSX conditionals and support files from /gfx"
This reverts commit 616b39413d.
2022-04-26 10:59:55 -05:00
Brian Smith 1a31160dde Issue #1829 - Revert "Issue #1751 -- Remove XP_MACOSX conditionals and support files from /xpcom"
This reverts commit 1bf0734a72.
2022-04-26 10:56:11 -05:00
Brian Smith e764f258e2 Issue #1829 - Revert "Issue #1751 -- Remove XP_MACOSX conditionals from /layout"
This reverts commit aa0fd3d68c.
2022-04-26 10:21:29 -05:00
Brian Smith 3daf711085 Issue #1829 - Revert “Issue #1751 -- Remove XP_MACOSX conditionals from the rest of the tree.”
This also removes some PP abuse and takes file entries out of PP when no longer
needed without XP_MACOSX conditionals.

This reverts commit 6f707bde95.
2022-04-26 10:19:04 -05:00
Brian Smith 7fe7026030 Issue #1829 - Revert "Issue #1751 -- fix up a few stray #ifs"
This reverts commit e7e63565ee.
2022-04-26 10:19:04 -05:00
Brian Smith 93407295fc Issue #1829 - Revert “Issue #1751 -- Remove cocoa support code from /dom”
This reverts commit ca35efb84e.
2022-04-26 10:19:03 -05:00
Brian Smith db8d2ef672 Issue #1829 - Revert "Issue #1751 -- Remove cocoa and uikit widget support code"
This reverts commit 08da125d9c.
2022-04-26 10:19:03 -05:00
Brian Smith f4f9b0cec7 Issue #1829 - Revert "Issue #1751 -- Update crashtests"
This reverts commit b5ece9f771.
2022-04-26 10:19:02 -05:00
Brian Smith adf51bc0f5 Issue #1829 - Revert "Issue #1751 -- Remove cocoa and uikit gfx and hal support code"
This reverts commit 1ee35eafa0.
2022-04-26 10:19:02 -05:00
Brian Smith 378738aaa9 Issue #1829 - Revert “Issue #1751 - Remove Mac code behind MOZ_WIDGET_TOOLKIT == 'cocoa’”
This reverts commit 1fe9c19305.
2022-04-26 10:19:00 -05:00
Moonchild c482078b09 Merge pull request 'Remove use counters telemetry' (#1883) from FranklinDM/UXP-contrib:work_telemetry-use-counters-removal into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/1883
2022-04-26 08:14:02 +00:00
Brian Smith 82f11ad8aa Issue #1829 - Revert "Issue #1751 - Remove Mac/ARM C fallback on gcc from pixman"
This reverts commit 2215d8467e.
2022-04-25 20:27:54 -05:00
Moonchild 72ff18e58e Issue #1885 - Follow-up: Update error message if invalid rootMargin specified. 2022-04-25 13:52:17 +00:00
Jeremy Andrews a0bdc21cf5 Issue #1879 - Follow-up: Update config/external/nss/target to security/target. 2022-04-24 15:03:59 -05:00
Moonchild 42ee994d99 Issue #1885 - Allow unitless rootMargin entries for IntersectionObserver.
I could have done this through a CSSLoader to allow all CSS unit quirks but
I wasn't planning to start passing around document and element references
everywhere, so instead just did it manually by accepting numbers/floats in
addition to pixel and percent.
2022-04-24 17:00:46 +00:00
Moonchild f25a45b9e6 Issue #1879 - Revert changes to cryptox.h
The error when removing this code was an #if vs #elif. But since we're planning
to restore MacOSX anyway, may as well rever the entire file here :)
2022-04-24 15:52:33 +00:00
Moonchild 677085e0c4 Revert "Issue #1879 - spot-fix typo in cryptox.h"
This reverts commit fbbcbffcc7.
2022-04-24 15:48:49 +00:00
Moonchild fbbcbffcc7 Issue #1879 - spot-fix typo in cryptox.h
Resolves #1879
2022-04-24 09:34:16 +00:00
Moonchild 5d5f72d4bc Merge pull request 'Interpret empty or whitespace root margin string as zero length for the IntersectionObserver' (#1882) from FranklinDM/UXP-contrib:work_inobsvr-empty-rootmargin-string into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/1882
2022-04-24 09:28:37 +00:00
FranklinDM c8b89feae8 Issue #21 - Change MappedAttrParser to store its nsIPrincipal instead of nsSVGElement
This reverts part 2 of Bug 968923 since this was only modified to accommodate use counters.
2022-04-24 00:09:21 +08:00
FranklinDM 17b2aa7650 Issue #21 - Remove use counters telemetry
This reverts Bug 968923 - Implement some equivalent of Chrome's use counters (on top of telemetry?)

For reference: https://bugzilla.mozilla.org/show_bug.cgi?id=968923
2022-04-24 00:02:42 +08:00
FranklinDM 6f685140aa Issue #1881 - Interpret empty or whitespace root margin string as zero length
This attempts to get the first non-whitespace token, which if exists, continues with previous behavior of parsing the margin string. Otherwise, if the specified margin string is empty or consists only of whitespace characters, is interpreted as zero length.

IntersectionObserver is the only consumer of the `ParseMarginString` method, as far as I can tell, so this should not affect anything else.

Note: For some reason, Firefox and Chrome treat the unitless zero length as invalid, while with this change, we do not change existing behavior in that regard and continue to accept that value.
2022-04-23 19:34:31 +08:00
Moonchild 5aa65d2aea Issue #1877 - Resolve NIGHTLY_BUILD conditionals. 2022-04-22 13:58:16 +00:00
Moonchild 712ca7303b Issue #1880 - Boot Comic Sans out of the font configuration.
Resolves #1880
2022-04-22 13:18:55 +00:00
Moonchild 8c824b8a75 Merge pull request 'Implement :host and :host-context' (#1878) from webcomps-wchen into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/1878
2022-04-20 19:33:34 +00:00
Jeremy Andrews 7aa445162e Issue #1593 - Part 5: Fix error that messes with event state detection.
Iterator changes between 42 and 52 were a bit confusing.
2022-04-19 21:48:36 +00:00
Jeremy Andrews 643e298a55 Issue #1593 - Part 4: Make :host pass DOM parsing test and basic specificity tests. 2022-04-19 21:45:51 +00:00
Jeremy Andrews f82c95d1eb Issue #1593 - Part 3: Add selector logic for :host and :host-context. 2022-04-19 21:44:23 +00:00
Jeremy Andrews 01747509f6 Issue #1593 - Part 2: Account for Shadow DOM v1 and iterator in nsBindingManager. 2022-04-19 21:43:21 +00:00
Jeremy Andrews 22b8e6b79f Issue #1593 - Part 1: Import William Chen's patches w/o selector implementation,
fixed up.
2022-04-19 21:42:11 +00:00
Moonchild f9b28d2006 Merge pull request 'Remove explicit SSL session cache cleanup' (#1875) from FranklinDM/UXP-contrib:work_nss-locks-assertion into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/1875
2022-04-19 20:10:21 +00:00
Moonchild 185a027640 Issue #1877 - Resolve RELEASE_OR_BETA conditionals. 2022-04-19 17:38:02 +00:00
Moonchild 99ec088ecf No issue - Use UXP generic credentials if no module.ver is present. 2022-04-19 16:47:11 +00:00
Moonchild 062a5085b1 Bump milestone 2022-04-19 01:29:44 +00:00
Moonchild 65ed8de1fa Merge pull request 'Ensure UndisplayedMap handling code consistently uses a normalized parent' (#1874) from FranklinDM/UXP-contrib:work_frames-undisplayedmap-nmparent into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/1874
2022-04-18 15:51:05 +00:00
Moonchild 2e34db5696 Merge pull request 'Bump minimum required GCC version in mfbt' (#1872) from trav90/UXP-contrib:compiler-hacks-cleanup into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/1872
2022-04-18 15:44:50 +00:00
FranklinDM 3a565183f0 Issue #738 - Follow-up: Remove explicit session cache cleanup routine from ShutdownNSS
This is no longer needed because the call to SSL_ConfigServerSessionIDCache on startup was already removed (see 1425f020c4), meaning LocksInitializedEarly does not become true and only causes an assertion on debug builds.

On the other hand, SSL_ClearSessionCache is already called on XPCOM shutdown and calling it again here is redundant.

Additional context: https://bugzilla.mozilla.org/show_bug.cgi?id=1485087#c5

Based on https://bugzilla.mozilla.org/show_bug.cgi?id=1485087
2022-04-18 23:44:27 +08:00
FranklinDM 7ed9c249be Issue #1873 - Part 3: Fix indentation 2022-04-18 23:22:04 +08:00
FranklinDM 37c86f2c07 Issue #1873 - Part 2: Ensure normalized parent is used for UndisplayedMap handling code
We have four entry points that deal with the parents of display:none/ display:contents content. These are the functions for setting, changing, getting and removing a style context. Or more specifically:

GetStyleContextInMap called by GetDisplay[None|Contents]StyleFor

SetStyleContextInMap called by RegisterDisplay[None|Contents]StyleFor

ChangeStyleContextInMap called by ChangeRegisteredDisplay[None|Contents]StyleFor

UnregisterDisplay[None|Contents]StyleFor okay, this is actually two functions, but they act as a pair

This change makes all these functions call GetApplicableParent up front and act on and pass around the parent that it returns. This is so that throughout the code we are always handling the parent that will be used as the key in the UndisplayedMap entry. This is necessary so that all the code that sets/gets the 'MayHaveChildrenWithLayoutBoxesDisabled' bit on/from an nsIContent object is using the same object, otherwise everything breaks down.

Partially based on part 2 of https://bugzilla.mozilla.org/show_bug.cgi?id=1367214
2022-04-18 23:21:58 +08:00
FranklinDM 8d8da66f94 Issue #1873 - Part 1: Introduce ParentForUndisplayedMap helper method
This introduces the `ParentForUndisplayedMap` helper method to reduce duplication in terms of getting the parent and asserting parent existence.

Partially based on parts of https://bugzilla.mozilla.org/show_bug.cgi?id=1341083
2022-04-18 23:21:22 +08:00
Moonchild 145947d86b Issue #1860 - Follow-up: Fix indentation. 2022-04-18 14:47:04 +02:00
Moonchild c2b4aa8cf2 Issue #1860 - Follow-up: Make sure we don't add duplicate frames
Changing to vector makes manipulating display list items more risky.
This is to make sure we don't inadvertently end up with duplicates in
the list of display items avoiding double-free scenarios.
2022-04-18 14:31:55 +02:00
Moonchild 129bb5568d Merge pull request 'Change LayerManagerData::mDisplayItems to a vector instead of hashtable' (#1866) from win7-7/UXP:pr-1860 into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/1866
2022-04-18 12:01:00 +00:00
win7-7 5b84c3e982 Merge branch 'master' into pr-1860 2022-04-18 13:15:28 +03:00
Moonchild 3abcec5d8b Merge branch 'lzma-updater' 2022-04-18 01:37:21 +02:00
Moonchild 6466bf6f5b Issue #1859 - Build xz-embedded lib when the updater is built. 2022-04-17 20:12:53 +02:00
Moonchild f4e8585e60 Merge pull request 'Follow-up: Prevent grid shorthand from resetting gutter properties' (#1871) from FranklinDM/UXP-contrib:work_css-grid-noreset-gutter-followup into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/1871
2022-04-17 17:31:01 +00:00
Moonchild cc231f0a26 Merge pull request 'Set canonical name for trimStart and trimEnd functions' (#1870) from FranklinDM/UXP-contrib:work_js-selfhosted-trim-assertion into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/1870
2022-04-17 17:29:58 +00:00
FranklinDM 86b17cfb4a Issue #1838 - Follow-up: Prevent grid shorthand from resetting gutter properties
This also fixes crashing when using the grid shorthand property.
2022-04-18 01:24:20 +08:00
Moonchild d2a4597cfc Issue #1859 - Part 6: Update mach mar to accept --bz2 for old style MAR
So we can build bzip2 MARs for selectively updating older versions of
the applications that don't understand xz.
2022-04-17 19:21:40 +02:00
Moonchild 43165d9edb Issue #1859 - Part 5: Add format detection to unwrap_full_update.pl 2022-04-17 19:21:30 +02:00
Moonchild 88624edc98 Issue #1859 - Part 4: Update mar file generation scripts for use of xz.
- Update packaging scripts to support both lzma and bzip2
- Update python script to support lzma
- Update test scripts to support lzma to be thorough

This all requires xz to be available in the path on the build system.
2022-04-17 19:21:20 +02:00
Moonchild c58e7c72b4 Issue #1859 - Part 3: Replace bzip2 handling in MAR files with xz.
Since there really is no need to add file detection logic to the updater
if updating through AUS is old->new only anyway, replacing bzip2
handling with xz handling is fine, instead of adding it.
Considering the far superior compression of LZMA and MAR not being
a common archive format anyway, let's just K.I.S.S. it :)
2022-04-17 19:21:09 +02:00
Moonchild 8bbfcc4c81 Issue #1859 - Part 2: xz-embedded build config changes
Always build as static lib for use in updater.
2022-04-17 19:20:59 +02:00
FranklinDM f2ad2ba0de Issue #1382 - Set canonical name for trimStart and trimEnd functions
This is needed to fix the assertion on debug builds that self-hosted functions must have consistent names, as these two functions are aliased to `trimLeft` and `trimRight`.
2022-04-18 01:12:25 +08:00
Moonchild 2af23767e1 Issue #1834 - Remove obvious entries for Binary Outcast code. 2022-04-17 11:21:48 +02:00
FranklinDM bb9700d982 Issue #1370 - Follow-up: Give table wrapper boxes a special case during flex base size resolution, so that percent main-sizes can be respected
This is a workaround, based on https://bugzilla.mozilla.org/show_bug.cgi?id=1455976
2022-04-17 11:03:22 +02:00
trav90 077b053ba4 Issue #1531 follow-up - Bump minimum required GCC version in mfbt 2022-04-16 21:12:11 -05:00
Moonchild 279ed4a9cf Merge pull request 'Fix building with GCC 11' (#1868) from trav90/UXP-contrib:gcc-work into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/1868
2022-04-17 01:16:32 +00:00
trav90 5f8057cbed Issue #1804 - Fix building with GCC 11 2022-04-16 19:15:44 -05:00
Moonchild 95cda916d1 Merge pull request 'Cache the most recent nsGenConNode to speed up future insertions' (#1867) from win7-7/UXP:pr-1861 into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/1867
2022-04-16 16:27:21 +00:00
Moonchild 08842d77ae Merge pull request 'Issue #1818 Cleanup some old GCC hacks' (#1865) from trav90/UXP-contrib:compiler-hacks-cleanup into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/1865
2022-04-16 16:23:23 +00:00
Moonchild 1191c9e371 Merge pull request 'Issue #1531 - Bump minimum required GCC version to 7.1' (#1858) from trav90/UXP-contrib:build-system-work into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/1858
2022-04-16 16:13:03 +00:00
win7-7 4ea9a83b75 Merge remote-tracking branch 'Upstream/master' into pr-1861 2022-04-15 21:42:20 +03:00
Moonchild 9a2da3012a Issue #1864 - Fix IonBuilder::maybeMarkEmpty.
Look at the instruction's operands instead of the instruction itself,
and take an early exit on empty types.
2022-04-15 20:22:02 +02:00
win7-7 022ed72339 Merge remote-tracking branch 'Upstream/master' into pr-1861 2022-04-15 20:17:27 +03:00
trav90 f5c363c01d Issue #1818 - Part 4: always use -pipe with GCC
Usable GCC versions have supported -pipe for a VERY long time. There's no need to keep checking if it is supported.
2022-04-15 08:30:32 -05:00
trav90 41fc1ccf4d Issue #1818 - Part 3: Remove more old gcc compiler hacks. 2022-04-15 08:30:25 -05:00
trav90 7abed0e352 Issue #1818 - Part 2: Remove code for implementation of atomics with __sync
All supported compilers support using C++11 <atomic> natively, so implementing
this using GCC's old __sync functions is no longer necessary.
2022-04-15 08:30:16 -05:00
trav90 d430c6398b Issue #1818 - Part 1: remove a number of old GCC hacks. 2022-04-15 08:30:05 -05:00
win7-7 e44c44b749 Issue #1861 - Cache the most recent nsGenConNode to speed up future insertions.
Cache the most recent nsGenConNode to speed up future insertions.
2022-04-15 13:43:24 +03:00
win7-7 d347a1e0c6 Issue #1860 - Change LayerManagerData::mDisplayItems to a vector instead of hashtable
This should improve cache locality and help speed up layer building.
2022-04-15 13:39:58 +03:00
Moonchild 39ba93e1d7 Merge branch 'restore-dual-guid' 2022-04-15 01:32:54 +02:00
Moonchild 5cecc096a3 Issue #1821 - Pre-process AddonRepository.jsm 2022-04-14 22:13:57 +02:00
Moonchild 8feed35c61 Issue #1821 - Restore "dot" indicators
This also removes orange compat warning styling and associated strings.

Reverses the entirety of #1445
2022-04-14 20:03:05 +02:00
Moonchild 7b706516bc Issue #1821 - Revert "Issue #1744 - Remove the ability to accept Firefox
GUIDS (remove the dual system)"

This reverts commit 3aa334d0b7.
2022-04-14 20:02:49 +02:00
Moonchild 144b3844da Merge branch 'master' of https://repo.palemoon.org/MoonchildProductions/UXP 2022-04-13 20:41:37 +02:00
Moonchild eb96f030b9 Issue #1859 - Part 1: Update xz-embedded library.
This also updates the script for updating and README.
2022-04-13 20:40:56 +02:00
Moonchild 981154dc48 [network] Add non-overrideable default MIME types for js, jsm and json.
This ensures the browser always recognizes these file type extensions
appropriately, even if not otherwise registered in the system.
2022-04-13 15:44:41 +02:00
Matt A. Tobin a0da6b5b68 No Issue - Update mach langpack with -v 2022-04-13 15:37:31 +02:00
trav90 bd99ce1461 Issue #1531 - Bump minimum required GCC version to 7.1 2022-04-12 10:06:02 -05:00
Moonchild bed3776982 Merge pull request 'Re-enable building of any XUL application via UXP toolkit' (#1856) from g4jc/UXP-contrib:build_blocker into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/1856
Reviewed-by: Moonchild <moonchild@palemoon.org>
2022-04-12 02:53:43 +00:00
Gaming4JC ef236bef4f Re-enable non-comm-style XUL application builds with a warning
A check was placed here to ensure the platform is built comm-style e.g. 'your-application/UXP'. There are packaging instances where old-style is still used. This re-enables the old-style with a visual warning indicating that any failure is the responsibility of the application maintainter as this style is not supported by the platform.
2022-04-11 21:57:22 -04:00
Moonchild d90ce1e30a Merge pull request 'Follow-up: Remove grid preference check from developer tools' (#1855) from FranklinDM/UXP-contrib:work_css-grid-pref-followup into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/1855
2022-04-09 15:49:48 +00:00
FranklinDM bee1a6fe1c Issue #1838 - Follow-up: Remove grid preference check from developer tools 2022-04-09 22:15:18 +08:00
Moonchild f9caae6cfd Fix Mesa check + whitespace 2022-04-09 01:59:40 +02:00
Moonchild e10f9df9df Fix typo 2022-04-09 01:59:02 +02:00
Moonchild 7d87b7a270 [devtools] Restrict sourcemap URLs 2022-04-09 01:25:04 +02:00
Moonchild 3d43617bc1 [xpcom] xpcom Threadpool cleanup
Make sure thread locks are in place to guard accesses.
2022-04-09 00:33:41 +02:00
Moonchild ac9fdbf123 [js] Fix AliasSet of MLoadTypedArrayElementHole 2022-04-09 00:31:18 +02:00
Moonchild e6101f7fa6 No issue - Avoid WebGL crash on Mesa
This prevents too high vert-count draws that Mesa doesn't handle.
2022-04-08 22:55:27 +02:00
Moonchild 52bcfa36bf [XPCOM] xpcom/threads misc cleanup 2022-04-08 21:54:05 +02:00
Moonchild 6d9b8e43bf [NSS] Update NSS to 3.52.4 2022-04-08 21:44:21 +02:00
Moonchild ae8cc0e398 Issue #1836 - Implement Selection.setBaseAndExtent() 2022-04-08 20:28:55 +02:00
Moonchild 7d49b154e2 Issue #1840 - Try to deal with bad website scripting loading/unloading modules.
Apparently Bing does rapid-fire loading/unloading of module scripts that
causes our attempts at resolving and initializing them to end up with
null fetched modules.
Returning null is probably a better way to handle this than crashing
on ms->ModuleRecord() ;-)
2022-04-08 20:23:10 +02:00
Moonchild d5ae68701b Merge pull request 'Implement 'content' keyword for 'flex-basis' property and address spec changes' (#1854) from FranklinDM/UXP-contrib:work_css-flex-basis-content into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/1854
2022-04-08 16:08:33 +00:00
Moonchild 330b866f46 Merge pull request 'Land final NSS-gyp work' (#1850) from nss-gyp-work into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/1850
2022-04-08 13:07:17 +00:00
Moonchild edcbb85f5e Update 7zSD. 2022-04-08 15:05:09 +02:00
Moonchild c683df5483 No issue - Always build MAR support.
Even when there is no updater.
2022-04-08 15:04:57 +02:00
Moonchild 8862a2ebf7 [NSS] check for missing signedData field and bump version 2022-04-08 15:04:27 +02:00
Moonchild 82fa1fbf14 [DOM IndexedDB] Increase intermediate byte storage maximum capacity. 2022-04-08 15:04:04 +02:00
Paul Adenot faec3f2140 [DOM media] Handle truncated ADTS and MP3 resources. 2022-04-08 15:03:54 +02:00
Moonchild ab5f44b61d [devtools] Escape backtick characters 2022-04-08 15:03:43 +02:00
Moonchild c332210793 [interface] Make Windows non-ePopupLevelTop popups respect owner z-order 2022-04-08 15:03:34 +02:00
Yaron Tausky 6709388785 Bug 1650214 - Cancel progress timer when shutting down FileReader
Not canceling the timer when run in a worker could lead to the timer firing
after the primary worker runnable finished running, leading to an assertion
failure in cycle collector code.
2022-04-08 15:03:24 +02:00
Moonchild 2829b9387b [interface] Hold a self-reference in nsDataObj. 2022-04-08 15:03:12 +02:00
Moonchild 1e1a1e5c71 [DOM] Stop treating XSLT meta refresh as a special snowflake thing.
It's just not healthy. It'll get delusions of self-importance and go rogue.
Next thing you know it'll start identifying as other elements.
2022-04-08 15:03:02 +02:00
Moonchild 55d1aa0748 [interface] Don't block size mode changes. 2022-04-08 15:02:54 +02:00
Moonchild 9fd02b65e1 [win system] Update the list of delayed-loaded dlls
Primarily for those who custom-install and somehow mess up directory permissions
exposing themselves to dll injection attacks.
2022-04-08 15:02:20 +02:00
Steve Fink e6a9d13e64 [js] Add dynamic check for valid serialized length 2022-04-08 15:00:02 +02:00
Matt A. Tobin 8832bfb62f No Issue - Don't build the layout recorder unless debug 2022-04-08 14:58:33 +02:00
Moonchild 44e35f67b4 Issue #1853 - Follow-up: extend attribution mapping to resize and corner
controls to allow themes to respond to scrollbar-width.

Also clean up the comments and whitespace a bit.
2022-04-08 00:57:11 +02:00
Moonchild 56d9003017 Issue #953 - Neuter the user-facing controls for e10s
This should prevent people using a massive footgun that would blow off
their entire legs. Requires appropriate FE changes.
2022-04-08 00:55:37 +02:00
Moonchild e49b80dba7 Issue #1853 - Map scrollbar-width to an element attribute.
By mapping this to an attribute, this allows browser themes to respond to
the various available scrollbar width settings in CSS.
2022-04-08 00:40:49 +02:00
Moonchild 834ded7d18 Issue #1852 - Undo Stylo nonsense that breaks body and frame margins.
This restores support for using HTML tag styling of margins on the body.
Reftests post bug still pass for dynamic changes, so does the newly-added
test for body margins and frames that tests the old styling method.
This also removes the reftest list for stylo testing for obvious reasons.
2022-04-08 00:27:44 +02:00
Moonchild c617545914 Issue #1822 - Follow-up: Remove reputation check leftovers from jsdownloads. 2022-04-08 00:23:23 +02:00
Moonchild ee4e449e04 Issue #21 - Remove MOZ_SERVICES_HEALTHREPORT from old-configure.
Also remove irrelevant references from build docs.
2022-04-08 00:10:55 +02:00
Moonchild fd51da7587 Issue #1851 - Update embedded emoji font to Twemoji 13.1 (TM 0.6.0) 2022-04-08 00:01:44 +02:00
Moonchild e1a982d677 No issue - Fix a potential autocomplete issue.
Account for the case where we don't have a tree view in selectedIndex
setter which may break future autocompletes.
2022-04-07 23:57:37 +02:00
Moonchild b76d12c2bd [XPCOM] Use swap in nsThread::SetObserver. 2022-04-07 23:56:24 +02:00
Moonchild 57dffbd698 [DOM] Align XHR requests with the spec. 2022-04-07 23:55:45 +02:00
Moonchild e0e12932bc [Docshell] Implement reload flood guard 2022-04-07 23:54:44 +02:00
Olli Pettay 9a1e152ba3 [Docshell] Close ContentViewer properly if initialization fails. 2022-04-07 23:53:44 +02:00
Moonchild a9046dcd55 [Network] Escape external protocol handler URLs 2022-04-07 23:52:40 +02:00
Olli Pettay c265d1cb7c [DOM] Don't try to create too large string buffers 2022-04-07 23:49:05 +02:00
Moonchild d61076d50e No issue - Minor performance improvement in BidiUtils 2022-04-07 23:48:24 +02:00
Moonchild 43bed4dad8 [DOM] Fix handling of text fragments 2022-04-07 23:47:40 +02:00
Moonchild 3a27ace545 No Issue - Further optimize MSVC linker configuration
Minor update to linker configuration to leverage optimal amount of
threads and folding for the linker for the build hardware used.
2022-04-07 23:43:06 +02:00
Moonchild d3cc8bc1ae Issue #21 - Remove calls to Services.telemetry and nsITelemetry
These calls would cause breakage without the supporting plumbing.
2022-04-07 23:35:02 +02:00
Moonchild 4f6406f033 Issue #1847 - Clean up gyp[_base].mozbuild for Android removal. 2022-04-07 15:50:39 +02:00
Moonchild ce1c300502 Issue #1847 - Fixes for SunOS 2022-04-07 15:45:41 +02:00
Matt A. Tobin 6a0d77b68c Issue #1847 - Update generate_certdata.py so it matches what this
version of NSS expects.
2022-04-07 15:45:01 +02:00
Matt A. Tobin 3ceb3ee7ef Issue #1847 - Get NSS gyp to understand disabling avx2 in freebl 2022-04-07 15:44:14 +02:00
Matt A. Tobin 3adf5e5d9c Issue #1847 - Transfer build configuration to gyp 2022-04-07 15:43:28 +02:00
Matt A. Tobin b2ad7e8ed9 Issue #1847 - Updates to handle NSS
Bug 1295937
2022-04-07 15:42:57 +02:00
Matt A. Tobin 3b48d984b2 Issue #1847 - Restore build/gyp.mozbuild to m-esr52 state.
To do: remove android stuff again at the end.
2022-04-07 15:42:13 +02:00
Moonchild 02afcba614 Merge pull request 'Use RTTI when building protobuf with GCC' (#1849) from trav90/UXP-contrib:build-system-work into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/1849
2022-04-07 13:38:57 +00:00
Travis W aed6c5eb62 Issue #1846 - Use RTTI when building protobuf with GCC 2022-04-07 13:15:18 +00:00
Moonchild 429a4cd9d7 Merge pull request 'Restore method that moves downloaded data's part file' (#1848) from FranklinDM/UXP-contrib:work_safebrowsing-removal-followup into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/1848
2022-04-07 10:37:33 +00:00
FranklinDM acf30bc5f4 Issue #1370 - Part 6: Update tests 2022-04-07 18:35:51 +08:00
FranklinDM ca38eaca70 Issue #1370 - Part 5: Regenerate developer tools' static CSS properties database 2022-04-07 18:35:51 +08:00
FranklinDM 567ba7ede6 Issue #1370 - Part 4: Treat flex-basis: content as max-content
This uses a different approach and builds upon the refactoring made in the 576eb6ee01fb9ee3669cad634b26473c2886cab1.

Partially based on https://bugzilla.mozilla.org/show_bug.cgi?id=1374540
2022-04-07 18:35:50 +08:00
FranklinDM 79b640795a Issue #1370 - Part 3: Implement content keyword for flex-basis property
Partially based on https://bugzilla.mozilla.org/show_bug.cgi?id=1105111
2022-04-07 18:35:49 +08:00
FranklinDM 0b75a2a787 Issue #1370 - Part 2: Remove redundant special-case code for treating flex-basis enum values as 'auto' in vertical axis
Based on https://bugzilla.mozilla.org/show_bug.cgi?id=1436881
2022-04-07 18:35:48 +08:00
FranklinDM b8d18bace6 Issue #1370 - Part 1: Refactor nsFrame to use a separate function for handling flex-basis
This removes the need to keep the `flex-basis` handling code of the ComputeSize* functions in sync since they both call the same function now for this purpose.
2022-04-07 18:35:42 +08:00
FranklinDM ecbe89cd7d Issue #1822 - Follow-up: Restore method that moves downloaded data's part file
This commit fixes the issue where all downloaded files are empty/zero-byte by creating a new `_move` method, which is called in place of the removed `_checkReputationAndMove` method.

In 6042fdd44c the reputation check for downloads was removed but that same method is also being used for moving the part file of completed downloads, which consequently broke all downloads except those without a part file, and made them empty since the actual downloaded file isn't being moved.
2022-04-07 18:18:52 +08:00
Jeremy Andrews a7bb296293 Issue #1824 - Use Bash to check if config.status is up-to-date on SunOS.
The Python script here claims it can handle any Bourne-compatible shell, but the detection logic here really only works with GNU Bash. Not that there are that many Bourne-compatible shell implementations to compare against...
2022-04-06 23:51:45 +02:00
Moonchild 7da587d0aa Issue #21 - Remove unused telemetry build variables.
Hard-code the values in AppConstants.jsm for compatibility, even if
nobody should actually be using this in extensions or what not.
2022-04-06 23:48:37 +02:00
Matt A. Tobin ac50292859 Issue #1845 - Remove Marionette from toolkit.mozbuild
It even seems this was always forced enabled. :?
2022-04-06 23:42:28 +02:00
Matt A. Tobin 633a742916 Issue #1845 - Remove Marionette from mach_bootstrap.py 2022-04-06 23:29:58 +02:00
Moonchild 63b8aaa495 Issue #1845 - Remove Marionette files 2022-04-06 23:28:22 +02:00
Moonchild 4897e3653a Issue #184 - Get rid of embedding/ios 2022-04-06 23:19:49 +02:00
Moonchild af32d0b7d1 Issue #1843 - Expand on WindowsVersion.h to add later versions.
Needs future cleanup because of way too many named individual functions
and redundancy.
2022-04-06 22:56:00 +02:00
Jeremy Andrews e6c662b5c6 Issue # 1824 - Restore NSDISTMODE, and have SunOS use it by default.
To make a long story short, there's an old flag called NSDISTMODE that
was never added to old-configure so it could be passed down through the
build system to all the places it needs to go nowadays if used in your
.mozconfig, but which still sort of works when set as an environment
variable. If you leave it unset, it uses relative symlinks. However, it
has two other modes. One of them is "copy" and the other is
"absolute_symlink." Copy simply copies the files into the directory, and
absolute_symlink attempts to use absolute symlinks instead of relative
ones.

I've been wondering for a while now if there was a way to make the
shared library files in `dist/bin` that we use `./mach run` against
*not* be relative symlinks, and this seems to be that elusive technique.

It seems to be a part of the institutional memory that was all but lost
shortly after Netscape went under. You mostly see a few references to it
in NSS, NSPR, and the Makefiles in the `config` directory. And also
there is one reference in a Makefile in the application directory, which
seems to explains why application executables themselves usually aren't
symlinks:

/platform/libs/nspr/src/pr/src/md/unix/Makefile.in#76
/platform/libs/nss/src/coreconf/UNIX.mk#34
/palemoon/app/Makefile.in#30
/platform/config/config.mk#396

My patch essentially revives NSDISTMODE and makes it work as intended
again, more or less. Some parts of the work are loosely inspired by this
bug that was never finished upstream, showing that Mozilla only
rediscovered it earlier this year while trying to disable symlinks in
dist/bin for WSL, as far as I can tell.

https://bugzilla.mozilla.org/show_bug.cgi?id=1699855
2022-04-06 00:04:36 +02:00
Moonchild 6abe7e7914 Issue #1795 - Don't try to pass a dash array of > 16 elements to ExtCreatePen.
According to MSDN documentation, the count of the style array passed to
ExtCreatePen is limited to 16. When we call ExtCreatePen with cStyle=17 or more,
it simply returns an error and the cairo surface used for printing is getting
into an error state, after which nothing further gets printed.
Instead of erroring out, this code change returns an unsupported status so that
cairo will provide fallback handling for it.
2022-04-05 19:42:46 +02:00
David Major 7ab66b1c6a Issue #1795 - Reapply bug 624198 fix that got lost in an upstream update. 2022-04-05 19:41:10 +02:00
Moonchild df3eed4ef9 Issue #1795 - Increase the MAX_FONT_SIZE limit applied in cairo_ft_font
to match the Thebes gfxFont size limit.

Also adds synching comments just to be sure.
2022-04-05 19:39:53 +02:00
Moonchild 804d0f6604 Issue #1795 - Add closure point to bounds calculation.
This addition of a closure point (explicitly completing the closed shape) isn't
strictly needed in our current cairo version as it works perfectly fine without,
but if our clipping extents code changes then this might cause problems if the
extra point isn't added (in case of 0-length paths).
2022-04-05 19:25:09 +02:00
Moonchild 327f5499ca Issue #1795 - Extend cairo API with an explicit font_get_hint_metrics function.
This extension allows us to get font hint metrics without having to create and
destroy cairo font options structs. Since this is used in loops, this will
improve performance, especially in documents which have many text segments.
2022-04-05 19:23:28 +02:00
Moonchild 97f911427a Issue #1795 - Remove support for building without DirectWrite. 2022-04-05 19:21:29 +02:00
Moonchild 3b575dfced Revert "Merge pull request 'Update libcubeb to latest version' (#1812) from athenian200/UXP:libcubeb_final into master"
This reverts commit 0bc66e3b04, reversing
changes made to 6e6b5d8996.
2022-04-05 17:00:28 +02:00
athenian200 0bc66e3b04 Merge pull request 'Update libcubeb to latest version' (#1812) from athenian200/UXP:libcubeb_final into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/1812
2022-04-05 13:35:47 +00:00
Moonchild 6e6b5d8996 Issue #1795 - Update libpixman 2022-04-05 14:51:06 +02:00
Moonchild 12635c1c22 Merge branch 'master' of https://repo.palemoon.org/MoonchildProductions/UXP 2022-04-04 22:27:31 +02:00
Moonchild 4c0d99d173 Issue #457 - Silence warnings in libcairo and libpixman.
We know these issues exist due to it being old 3rd party code.
2022-04-04 22:22:24 +02:00
Moonchild 8399d85036 Issue #1841 - Part 3: Remove the Direct3D9 compositor. 2022-04-04 22:16:37 +02:00
Moonchild ef5083db5f Issue #1841 - Part 2: Remove D3D9 layer compositor references and
layer fallback code.
2022-04-04 22:15:34 +02:00
Moonchild cff9ef7fb8 Issue #1841 - Part 1: Ignore the values for D3D9 preferences, forcing
them to their current default, in preparation for the removal.
2022-04-04 22:14:00 +02:00
Moonchild 124a5a8eb7 Issue #457 - Fix double -> float warning in gfxUtils. 2022-04-04 22:08:36 +02:00
Moonchild a9376e01cb [layout] Hold strong references to delayed menu command events. 2022-04-04 22:07:00 +02:00
Moonchild 8884db9790 [DOM/XSLT] Pass sandbox flags from source doc. 2022-04-04 22:06:43 +02:00
Moonchild 28a69cf1e2 Use brace initialization for Atomics.
Remind me to always build BEFORE committing :P
2022-04-04 22:06:25 +02:00
Moonchild bdfc1adbd2 [network] Make several variables atomic in nsSocketTransport2.
Fixes potential thread races between:
- nsSocketTransport::OnInputClosed and nsSocketTransport::OpenInputStream.
- nsSocketTransport::OnOutputClosed and nsSocketTransport::OpenOutputStream.
- nsSocketTransport::Close and nsSocketTransport::RecoverFromError called from
  OnSocketDetached.
2022-04-04 22:06:07 +02:00
Moonchild f990d9a46a [network] Use a COM pointer instead of NS_ADDREF in nsSocketTransport2.cpp 2022-04-04 22:05:50 +02:00
Moonchild 497e453fe7 [network] Align IDN normalization with the current spec. 2022-04-04 22:05:33 +02:00
Moonchild 7dec0edf50 [network] Tighten checks for ACE (punycode) encoding. 2022-04-04 22:05:15 +02:00
Moonchild 97ee3ee428 [network] Clean up IDN logic and add some corner case use. 2022-04-04 22:04:54 +02:00
Moonchild 18cfe514ab Merge branch 'master' of https://repo.palemoon.org/MoonchildProductions/UXP 2022-04-04 17:34:00 +02:00
Moonchild 15aafa8a46 Revert "Issue #1806 - Part 1: Update cubeb"
This reverts commit 711e049432.
2022-04-04 17:33:26 +02:00
Moonchild 757a30f720 Revert "Issue #1806 - Part 2: Adjust the platform for lib changes"
This reverts commit 3635039d2b.
2022-04-04 17:33:15 +02:00
Moonchild 78d1f68932 Merge pull request 'Support updated box alignment spec on gap properties' (#1839) from FranklinDM/UXP-contrib:work_css-boxalign-gap into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/1839
2022-04-04 01:47:29 +00:00
FranklinDM b226f8942d Issue #1838 - Part 7: Update tests 2022-04-02 23:14:36 +08:00
FranklinDM f1c2ba75d1 Issue #1838 - Part 6: Re-resolve row-gap against the sum of row track sizes for auto-sized grid containers
Based on https://bugzilla.mozilla.org/show_bug.cgi?id=1458902
2022-04-02 23:14:30 +08:00
FranklinDM f3707e0637 Issue #1838 - Part 5: Address follow-up issues to initial flexbox layout for (column|row)-gap properties
Notes:
* Bug 1473044 - Make flexbox cross size take row/column gap into account
https://bugzilla.mozilla.org/show_bug.cgi?id=1473044
* Bug 1473047 - Re-resolve row-gap percentages after intrinsic block size calculated
https://bugzilla.mozilla.org/show_bug.cgi?id=1473047
* Bug 1612401 - Prevent absolute-positioned children from contributing gap size to flexbox's inline-size
https://bugzilla.mozilla.org/show_bug.cgi?id=1612401
* Bug 1639627 - Make flex-container percent 'row-gap' values resolve to 0, when they're resolved against an indefinite block-size (essentially reverts Bug 1473047)
2022-04-02 23:14:25 +08:00
FranklinDM ed8d7f1391 Issue #1838 - Part 4: Implement flexbox layout for (column|row)-gap properties
This implements flexbox layout for the gap properties without the refactoring work performed on `nsFlexContainerFrame`.

Partially based on https://bugzilla.mozilla.org/show_bug.cgi?id=1398483 and https://bugzilla.mozilla.org/show_bug.cgi?id=1454822

This excludes the second part of bug 1454822, the width caching implementation, because it is out of scope and currently causes unstable layout with `writing-mode: vertical-lr` (see bug 1709937).
2022-04-02 23:14:18 +08:00
FranklinDM 7e975c2c5b Issue #1838 - Part 3: Regenerate developer tools' static CSS properties database 2022-04-02 23:14:09 +08:00
FranklinDM 4608ae53aa Issue #1838 - Part 2: Remove grid- prefix from grid-(column|row)-gap properties
This removes the `grid` prefix from the gap-related properties of grid since they are now part of the box alignment specification. Former grid-gap* properties were aliased to the unprefixed properties to maintain compatibility.

The previously multi-column layout only `column-gap` property has been modified to apply to the Grid layout (and Flexbox in a following commit), moving the `mColumnGap` member variable from `nsStyleColumn` to `nsStylePosition`.

Notes:
* Bug 1398537 - support for percent values in column-gap for multi-column layout landed as part of Issue #1230. However, it was incomplete because it did not update `nsRuleNode` to allow transformation of percentage values for `column-gap`. This was consequently fixed as part of this commit.
* Bug 1456166 - this might not apply because we don't have that devtools test in UXP
* `nsRuleNode`, `nsCSSParser`, `Declaration`, and other related classes were merged into Stylo. These should be taken into consideration when porting patches from Mozilla.

Partially based on https://bugzilla.mozilla.org/show_bug.cgi?id=1398482
2022-04-02 23:14:04 +08:00
FranklinDM 121ee9438c Issue #1838 - Part 1: Remove CSS grid preference
Based on https://bugzilla.mozilla.org/show_bug.cgi?id=1398492
2022-04-02 23:13:54 +08:00
Moonchild ba4eba034f Issue #21 - Remove telemetry from PopupNotifications.jsm. 2022-04-02 14:51:59 +02:00
Moonchild 534de5cc5b Issue #21 - Remove remaining telemetry structs, callers and flags. 2022-04-02 14:49:45 +02:00
Moonchild 023a71c6f2 Issue #21 - Remove Telemetry from Accessibility, EME and WebRTC. 2022-04-02 14:48:02 +02:00
Moonchild c83282fd4d Issue #21 - Remove Telemetry from Push and devtools. 2022-04-02 14:45:36 +02:00
Moonchild d60103257e Issue #21 - Remove Telemetry accumulation/structures from toolkit js.
This fixes toolkit modules and prevents toolkit component breakage.
Also removes about:telemetry
2022-04-02 14:42:57 +02:00
Moonchild ee86d3eb9c Issue #21 - Remove Telemetry plumbing and fix build.
Note this won't give working applications. Requires FE changes and
additional js module changes (next part).
2022-04-02 14:39:54 +02:00
Moonchild d0acadd727 Issue #1806 - Follow-up: Fix WebRTC issues with cubeb update. 2022-04-02 14:36:54 +02:00
Matt A. Tobin 9a811901ef No Issue - Make building the backend fun again! 2022-04-02 14:27:46 +02:00
Matt A. Tobin 4a7af0d90f Issue #1835 - Part 2: Remove config and most mentions of XULRunner
Resolves #1835
2022-04-01 17:33:23 +02:00
Matt A. Tobin 0f52679d2e Issue #1835 - Part 1: Remove /xulrunner application dir. 2022-04-01 17:27:20 +02:00
Moonchild e00bc543ad [No issue] Don't rely on nsCRT from jsdate. 2022-04-01 17:19:24 +02:00
Jeremy Andrews 1e8c040307 No Issue - Clean-up stray right parenthesis 2022-04-01 17:17:29 +02:00
Moonchild 7c90c0205c Issue #1822 - Part 4: Remove URL classifier and internal blocklist errors.
This removes NS_ERROR_{TRACKING|MALWARE|PHISHING|UNWANTED|BLOCKED}_URI
that are no longer in use.
2022-04-01 16:05:02 +02:00
Moonchild a95439db61 Issue #1822 - Part 3: Remove LOAD_CLASSIFIER_URI and various
helper functions.
2022-04-01 16:03:01 +02:00
Andrea Marchesini f5fcb8a32c Issue #1833 - Get rid of ArchiveReader API 2022-04-01 15:53:22 +02:00
Moonchild ce0cefe053 Issue #1053 - Second pass remove android defines and build system stuff.
Mostly IPC, tools and mozbuild.
2022-04-01 15:47:43 +02:00
Matt A. Tobin 35e7103093 No Issue - Remove Mozilla source tree bootstrapping python module
Part of Mozilla's DaaS, "bootstrapping" the tree is heavily dependent on
Mozilla infrastructure, m-c structure and dependencies, libs, toolchain,
etc. and would never work for us. Sweeping some clutter, in other words.

This copies in a function that was imported from mozboot to satisfy deps.
2022-04-01 15:35:04 +02:00
Moonchild 426a9755d9 Issue #1053 - Remove Android systrace, more build system removals.
Also updates more comments.
2022-04-01 15:28:15 +02:00
Moonchild c14bb310ce Issue #1053 - Clean up docs and some code comments.
Polish only, no code changes.
2022-04-01 15:26:49 +02:00
Moonchild ccee5c781b Issue #1053 - Remove android-ndk from mozconfigure. 2022-04-01 15:25:14 +02:00
Moonchild d5934d65de Issue #1053 - Remove some Android compiler/runtime bug workarounds. 2022-04-01 15:23:31 +02:00
Moonchild 39f9ab375b Issue #1053 - Remove /dom/system/android and dependent modules,
as well as robocop.
2022-04-01 15:22:15 +02:00
Moonchild 28a3cd1028 Issue #1053 - First pass Android defines and remove Android Annotation
processors, some Andoid packaging stuff, Eclipse IDE support et al.
2022-04-01 15:17:54 +02:00
Moonchild f987138760 Issue #1053 - Remove Android WebGL/EGL extensions. 2022-04-01 15:16:42 +02:00
Moonchild 1803c596dc Issue #1822 - Part 2: Remove Google API key parsing in URLS. 2022-04-01 15:12:20 +02:00
Moonchild 6042fdd44c Issue #1822 - Part 1: Remove Google Safebrowsing plumbing
This removes support for querying Google services for reputation data
for sites and downloads.
2022-04-01 15:10:04 +02:00
Jeremy Andrews c56023163b Issue #1832 - Account for shadow boundaries in nsFrameManager.
Resolves #1832
2022-04-01 15:00:11 +02:00
Moonchild 1caa678592 Issue #1831 - Add an option to enable TLS 1.3 "compatibility" mode.
Critical note: this potentially reduces the strength of TLS 1.3 and
should only be enabled if absolutely necessary to access a site.
A browser restart is required for the pref change to take effect as it
is set on NSS initialization.

Resolves #1831
2022-04-01 14:52:46 +02:00
Moonchild ddaee7c1be Issue #1830 - Remove --disable-xul config and conditionals. 2022-04-01 14:47:16 +02:00
Moonchild c030a50228 Issue #1721 - Implement GlobalPrivacyControl
(and get rid of failed DoNotTrack)
2022-04-01 14:41:51 +02:00
Moonchild e4c6db86b8 [WebRTC] Clean up encode callback during GMP release. 2022-04-01 14:40:31 +02:00
Moonchild a7b63631b0 No issue - Clean up some obsolete/archaic code paths. 2022-04-01 14:38:31 +02:00
Matt A. Tobin cdff23ad0b Bug 1340030 - Remove necko_standalone lib
The only users of this library were removed by Bug 1239866 and Bug 1239870 as part of the larger removal of libxpcomrt in Bug 1237409.

This was done before our fork point..
2022-04-01 14:32:45 +02:00
Matt A. Tobin 3635039d2b Issue #1806 - Part 2: Adjust the platform for lib changes 2022-04-01 14:31:39 +02:00
Matt A. Tobin 711e049432 Issue #1806 - Part 1: Update cubeb 2022-04-01 14:29:58 +02:00
Moonchild 57c4f24573 [Autocomplete] Add styling for Pale Moon's private-* implementation of AC popups 2022-04-01 14:28:46 +02:00
Moonchild 808f96cc8f Increase MAX_ICON_SIZE to account for more common use of HiDPI icons.
This change was unintentionally reverted when importing gecko/44 search service
code.
2022-04-01 14:28:27 +02:00
Olli Pettay 2a9d0cc5af [XPCOM] be more precise when counting the number of allocator users
This patch is based on code inspection.
One could also move sAllocatorUsers to Free(), but it shouldn't matter
in practice.
2022-04-01 14:28:04 +02:00
Moonchild 1fa4cfb004 [Network] Block mk: protocol to work around MSIE vulnerability. 2022-04-01 14:27:48 +02:00
Moonchild 44d2b36eff [DOM] Use RefPtr in ContentChild::RecvGetFilesResponse. 2022-04-01 14:27:25 +02:00
Jeremy Andrews bb830b178a Issue #1806 - Convert DOS line endings to Unix line endings.
When redoing my work and creating a new file on Windows, I forgot to ensure it didn't have CRLF line endings.
2021-08-27 14:24:40 -05:00
Matt A. Tobin c6b1b30bb5 Issue #1751 - Fix preprocessor typo to restore ARM Linux buildability 2021-08-25 18:47:59 -04:00
Jeremy Andrews 5f1430b0bd Issue #1806 - Part 8: Fix Linux and SunOS build again.
The patches didn't reapply for some reason, so this restores the working state.
2021-08-24 17:52:06 -05:00
Jeremy Andrews b818d43967 Issue #1806 - Part 7: Fix up weird issue introduced when redoing branch.
Apparently this time I accentally pulled a random + and - sign into a couple files because I wasn't careful to look at the raw versions on Bugzilla.
2021-08-24 17:19:47 -05:00
Jeremy Andrews a21085b86b Issue #1806 - Part 6: Make it build on Windows.
Without this change, you get an error about external linkage or something. These files are now used outside of WebRTC.
2021-08-24 16:15:22 -05:00
Jeremy Andrews 89c3761e5c Issue #1806 - Part 5: Add multichannel audio capability.
I'm positive this works on Windows at the very least. Cubeb added proper channel map support at some point, and this allows us to take advantage of that.

Ref: BZ 1431221, BZ 1432779
2021-08-24 16:07:22 -05:00
Jeremy Andrews 893fc90379 Issue #1806 - Part 4: Add more audio troubleshooting information.
This should help us troubleshoot audio issues better in the future in general, since we'll know more about the hardware involved, etc.
2021-08-24 14:35:49 -05:00
Jeremy Andrews 41b1b3947c Issue #1806 - Part 3: Allow forcing a particular libcubeb backend.
This streamlines troubleshooting in situations where multiple audio backends are compiled into the binary. Now testing different audio backends is as simple as restarting the browser and changing a pref rather than requiring a full recompile.
2021-08-24 13:42:09 -05:00
Jeremy Andrews c23dab7adc Issue #1806 - Part 2: Move AudioConfig stuff from MediaInfo.h to MediaData.h.
This avoids circular dependencies, because otherwise the two headers would try to include each other.
2021-08-24 13:12:43 -05:00
Jeremy Andrews cc75c6a6e9 Issue #1806 - Part 1: Restore libcubeb update.
Restore the proper working environment for libcubeb work after reversion.
2021-08-24 10:38:44 -05:00
Moonchild ee49838173 Revert "Issue #1806 - Update libcubeb"
This reverts commit 741fd8b61c.
2021-08-22 17:39:55 +00:00
Moonchild a725c0fe3d Revert "Issue #1806 - Follow-up: New libcubeb uses incorrect audio backend for Oracle Solaris."
This reverts commit 9d4f14582b.
2021-08-22 17:39:42 +00:00
Moonchild 5d09ddb574 Revert "Issue #1806 - Follow-up: Restore PulseAudio support in libcubeb."
This reverts commit 0c2a0f45ec.
2021-08-22 17:39:29 +00:00
Moonchild 0c2a0f45ec Issue #1806 - Follow-up: Restore PulseAudio support in libcubeb.
This was incorrectly removed because we aren't using a Rustified abstraction.
2021-08-21 08:10:13 +00:00
Coordinator Tobin 4ac28d1d48 Merge pull request 'Follow-up: New libcubeb uses incorrect audio backend for Oracle Solaris.' (#1809) from athenian200/UXP:use_sun_audio into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/1809
2021-08-19 02:37:04 +00:00
Jeremy Andrews 9d4f14582b Issue #1806 - Follow-up: New libcubeb uses incorrect audio backend for Oracle Solaris.
Mozilla picked up a change to libcubeb moz.build file from the FreeBSD project. Using OSS directly works fine in Illumos, but Oracle Solaris still has to use a Sun-specific API for sound to work, even though it also uses OSS under the hood. No code changes are needed here, the build configuration is just not what Solaris needs even though it's fine for Illumos. The Sun-specific API works for both, though, and should thus be preferred.
2021-08-18 17:24:13 -05:00
Moonchild a5a14974a1 Issue #1797 - Implement WindowOrWorkerGlobalScope.origin
Resolves #1797
2021-08-15 11:45:53 +00:00
Moonchild 9baa17379e Bump platform version. 2021-08-13 09:43:04 +00:00
Moonchild 225b5e5e5a [db] Update SQLite to 3.36.0 2021-08-13 09:41:57 +00:00
Moonchild 741fd8b61c Issue #1806 - Update libcubeb
This is a full lib update, changing callers where needed.
This also moves GertCubeMSGLatencyInFrames to CubebUtils.{cpp|h} where it
belongs.
2021-08-12 14:14:18 +00:00
Jens Stutte fe2ea0ce88 [DOM] Be more explicit about the WorkerPrivate self-reference. 2021-08-12 11:39:07 +00:00
Moonchild fa49002626 [MFBT] Convert debug asserts to early returns for situations that should
never occur.
2021-08-12 11:30:26 +00:00
Moonchild ca1a84cb93 [DOM/NPAPI] Defer loading object when setting attribute. 2021-08-12 00:27:34 +00:00
Moonchild 61a3331fe2 [network] Use a proof of lock everywhere in cache v2. 2021-08-11 23:49:44 +00:00
Moonchild 4932924d67 Issue #1675 - Move regexp to new-regexp to make bz porting simpler. 2021-07-30 11:24:18 +00:00
Moonchild 66cd46d9bc Issue #1679 - Part4: Clean up commented-out/WIP code. 2021-07-30 09:58:15 +00:00
Moonchild 979c60bc7c Issue #1679 - Part 3: Make everything build on supported compilers. 2021-07-30 09:43:28 +00:00
Moonchild 6203743160 Issue #1781 - Follow-up: fix debug assert in MergeMultiplicativeR() 2021-07-24 06:42:30 +00:00
Moonchild 738448aa0d [no issue] Replace PurpleBlock with SegmentedVector to reduce indirect memory
accesses when calling suspect

Improves overall memory performance.
Also prerequisite for further work on #1677.
2021-07-23 15:29:24 +00:00
Moonchild 74989fb284 Merge pull request 'Implement Promise.allSettled()' (#1796) from athenian200/UXP:Promise-allSettled into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/1796
2021-07-18 17:03:03 +00:00
athenian200 22377b86a3 Merge branch 'master' into Promise-allSettled 2021-07-15 16:21:00 +02:00
Jeremy Andrews 5764d0c28d Issue #1725 - Fix logic in PerformPromiseAllSettled.
This function essentially appears to work as written, there was an issue with it returning false too early in some situations that prevented it from working properly.
2021-07-15 03:08:11 -05:00
Moonchild c198ef11b9 [layout] Ensure we set the primary frame for native anon content where needed. 2021-07-15 04:11:48 +00:00
Moonchild caf98496b7 Revert "[accessibility] Remove selection listeners from shutting down PresShell."
This reverts commit 684000d9a5.
2021-07-14 17:30:58 +00:00
Eitan Isaacson 684000d9a5 [accessibility] Remove selection listeners from shutting down PresShell. 2021-07-14 16:40:33 +00:00
Moonchild 00f9e24368 [gfx] Hard-block old mesa/nouveau versions 2021-07-14 15:15:14 +00:00
Dana Keeler 361743b222 [NSPR] Lock access to PRCallOnceType members in PR_CallOnce* for thread safety.
Cherry-picked upstream fix from 4.31
2021-07-14 14:42:24 +00:00
Moonchild ce2938d274 [ANGLE] Cherry-pick upstream fix 2021-07-14 13:51:11 +00:00
Valentin Gosu 6fe78cec8a [network] Make CacheIOThread::ThreadFunc hold reference to thread. 2021-07-14 13:27:14 +00:00
Moonchild 8cc2f6ba9b [network] Add some sanity checks to deserialized nsStandardURLs
Note: C++ lambda expressions are actually useful for once.
2021-07-14 13:20:09 +00:00
Moonchild 8ea119da4a [network] Stop blocking 10080
Port 10080 is shared by too many devices and services that do need http(s)
access, so this port should not be blacklisted by default.
2021-07-14 01:51:13 +00:00
Moonchild f864b515d9 WIP: Base implementation 2021-07-13 20:09:21 +00:00
Matt A. Tobin 3003f52e1d Issue #1793 - Only use Glass on the Toolkit Download Manager on Windows 7 2021-07-12 13:11:40 -04:00
Matt A. Tobin cc934f8264 Issue #1793 - Only use proper Aero Styling in the Toolkit Error Console on Windows 7 2021-07-12 13:00:51 -04:00
Matt A. Tobin 1327910cda Issue #1793 - Add a border-bottom to treecols header 2021-07-12 12:58:30 -04:00
Matt A. Tobin 3b7f2ddd3c Issue #1793 - Add a border-bottom to toolbox
Follow-up to e8be661944
2021-07-12 12:57:39 -04:00
Moonchild 82b1fdca1f Issue #1792 - Part 4: Implement constructors for the EventTarget interface. 2021-07-12 03:06:58 +00:00
Moonchild 1b86eb76fc Issue #1792 - Part 3: Add ConstructibleEventTarget helper class.
Of course it couldn't be trivial :P
wrapObject is a pure virtual function which prevents an abstract constructor
from being used.
So, we need to extend DOMEventTargetHelper (applicable acronym: DETH :D) with
a wrapObject implementation - in a derivative class is the clearest way to do
this, as opposed to making DETH more complex.
2021-07-12 03:04:29 +00:00
Moonchild ea0e4de698 Issue #1792 - Part 2: Move GetParentObject() to EventTarget.h for re-use. 2021-07-12 02:56:48 +00:00
Moonchild 6e7adbe74d Issue #1792 - Part 1: Remove superfluous check for abstract ancestors.
This removes some restrictions on whether an interface that implements
QueryInterface can have a non-abstract ancestor.

This restriction was put in place back when we automatically added
QueryInterface to all rootmost non-abstract interfaces (~Pale Moon 24).
At the time, we needed to make sure it did NOT end up on EventTarget, because
back then WebIDL quickstubs would replace the QI implementation on non-WebIDL
EventTargets with the WebIDL one, which would not work for them.

Since then, we have removed WebIDL quickstubs and we now explicitly list which
interfaces get QueryInterface, so this check is no longer needed.
2021-07-12 02:54:51 +00:00
Moonchild a58b35c01b Issue #1757 - Follow-up: Remove some stray WPT leftovers.
These were re-introduced when reverting the <details> element pref changes.
2021-07-12 02:50:57 +00:00
Moonchild 5e6305573f [network] Stop treating http and https as different for encoding schemes.
There is no reason to treat available encoding schemes for these protocols
differently.
2021-07-10 13:00:14 +00:00
3160 changed files with 156761 additions and 239383 deletions

No files matched your search

-5
View File
@@ -36,11 +36,6 @@ def FlagsForFile(filename):
flag_list = shlex.split(out.getvalue())
# This flag is added by Fennec for android build and causes ycmd to fail to parse the file.
# Removing this flag is a workaround until ycmd starts to handle this flag properly.
# https://github.com/Valloric/YouCompleteMe/issues/1490
final_flags = [x for x in flag_list if not x.startswith('-march=armv')]
return {
'flags': final_flags,
'do_cache': True
+1 -1
View File
@@ -22,4 +22,4 @@
# changes to stick? As of bug 928195, this shouldn't be necessary! Please
# don't change CLOBBER for WebIDL changes any more.
Clobber for NSS update
Clobber for NSS update
+1 -3
View File
@@ -9,8 +9,6 @@ selective cherry-picking of directly-applicable patches, this repository has its
own development and holds the base for a maintained platform to be used by XUL
applications.
For a list of active projects making use of the Unified XUL Platform, checkout http://thereisonlyxul.org/.
## Additional documentation
Additional documentation relevant to this source code can be found in the `/docs`
@@ -23,7 +21,7 @@ You are also always welcome to get in touch with our community on the [Pale Moon
### A note about trademarks and branding
Although this repository is licensed under Mozilla Public License v2.0, the
Although this repository is primarily licensed under Mozilla Public License v2.0, the
trademarks and brands contained herein remain the property of their respective
owners. For more details, please see the notifications in the respective directories.
+2 -3
View File
@@ -15,14 +15,14 @@ What should be considered vulnerabilities or security hazards by default:
Generally not security vulnerabilities:
- Null dereferencing crashes;
- Malware extensions (but please do report those on the forum in the extensions board!);
- Malware extensions (but please do report those on the forum in the add-ons board!);
- Denial-of-service (AKA "evil trap sites")
- Browser hangs
- Issues with non-standard manual configuration (either at build time or by manipulating about:config directly)
## Reporting a Vulnerability
If you find an issue in UXP or the applications it builds on that could impact the security or safety of users please **do not**
If you find an issue in UXP, or the applications building on it, that could impact the security or safety of users please **do not**
make an issue on Gitea about it. Gitea does not support restricted viewability for security sensitive bugs.
If you want to report a security-sensitive issue then please go to the [forum](https://forum.palemoon.org) and report the issue
@@ -33,4 +33,3 @@ except the recipient (not even moderators!).
You will be informed via private message if the vulnerability report is accepted or declined, with reasoning.
Security updates occur regularly and are given priority over most other development tasks. In general, they can be solved
relatively quickly and will be included in the next point release (third digit if not rolled into a more major one).
-2
View File
@@ -5,9 +5,7 @@
#include "AccIterator.h"
#include "AccGroupInfo.h"
#ifdef MOZ_XUL
#include "XULTreeAccessible.h"
#endif
#include "mozilla/dom/HTMLLabelElement.h"
-2
View File
@@ -341,8 +341,6 @@ LogRequest(nsIRequest* aRequest)
printf("targeted; ");
if (loadFlags & nsIChannel::LOAD_CALL_CONTENT_SNIFFERS)
printf("call content sniffers; ");
if (loadFlags & nsIChannel::LOAD_CLASSIFY_URI)
printf("classify uri; ");
} else {
printf(" no request");
}
@@ -13,7 +13,6 @@
#include "mozilla/dom/TabChild.h"
#include "mozilla/dom/Element.h"
#include "mozilla/Telemetry.h"
using namespace mozilla;
using namespace mozilla::a11y;
+2 -2
View File
@@ -35,10 +35,10 @@ EPlatformDisabledState PlatformDisabledState();
void PreInit();
#endif
#if defined(MOZ_ACCESSIBILITY_ATK)
#if defined(MOZ_ACCESSIBILITY_ATK) || defined(XP_MACOSX)
/**
* Is platform accessibility enabled.
* Only used on linux with atk.
* Only used on linux with atk and MacOS for now.
*/
bool ShouldA11yBeEnabled();
#endif
+4
View File
@@ -96,6 +96,10 @@ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
'/accessible/windows/ia2',
'/accessible/windows/msaa',
]
elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
LOCAL_INCLUDES += [
'/accessible/mac',
]
else:
LOCAL_INCLUDES += [
'/accessible/other',
@@ -68,7 +68,6 @@
#include "mozilla/Services.h"
#include "nsDeckFrame.h"
#ifdef MOZ_XUL
#include "XULAlertAccessible.h"
#include "XULColorPickerAccessible.h"
#include "XULComboboxAccessible.h"
@@ -79,7 +78,6 @@
#include "XULSliderAccessible.h"
#include "XULTabAccessible.h"
#include "XULTreeGridAccessibleWrap.h"
#endif
#if defined(XP_WIN) || defined(MOZ_ACCESSIBILITY_ATK)
#include "nsNPAPIPluginInstance.h"
@@ -1356,7 +1354,6 @@ nsAccessibilityService::CreateAccessibleByType(nsIContent* aContent,
}
RefPtr<Accessible> accessible;
#ifdef MOZ_XUL
// XUL controls
if (role.EqualsLiteral("xul:alert")) {
accessible = new XULAlertAccessible(aContent, aDoc);
@@ -1515,7 +1512,6 @@ nsAccessibilityService::CreateAccessibleByType(nsIContent* aContent,
accessible = new XULToolbarButtonAccessible(aContent, aDoc);
}
#endif // MOZ_XUL
return accessible.forget();
}
@@ -1739,7 +1735,6 @@ nsAccessibilityService::HasAccessible(nsIDOMNode* aDOMNode)
////////////////////////////////////////////////////////////////////////////////
// nsAccessibilityService private (DON'T put methods here)
#ifdef MOZ_XUL
already_AddRefed<Accessible>
nsAccessibilityService::CreateAccessibleForXULTree(nsIContent* aContent,
DocAccessible* aDoc)
@@ -1769,7 +1764,6 @@ nsAccessibilityService::CreateAccessibleForXULTree(nsIContent* aContent,
new XULTreeGridAccessibleWrap(aContent, aDoc, treeFrame);
return accessible.forget();
}
#endif
nsAccessibilityService*
GetOrCreateAccService(uint32_t aNewConsumer)
-2
View File
@@ -274,13 +274,11 @@ private:
CreateAccessibleByFrameType(nsIFrame* aFrame, nsIContent* aContent,
Accessible* aContext);
#ifdef MOZ_XUL
/**
* Create accessible for XUL tree element.
*/
already_AddRefed<Accessible>
CreateAccessibleForXULTree(nsIContent* aContent, DocAccessible* aDoc);
#endif
/**
* Reference for accessibility service instance.
-6
View File
@@ -48,9 +48,7 @@
#include "mozilla/dom/DocumentType.h"
#include "mozilla/dom/Element.h"
#ifdef MOZ_XUL
#include "nsIXULDocument.h"
#endif
using namespace mozilla;
using namespace mozilla::a11y;
@@ -210,11 +208,9 @@ DocAccessible::NativeRole()
return roles::CHROME_WINDOW;
if (itemType == nsIDocShellTreeItem::typeContent) {
#ifdef MOZ_XUL
nsCOMPtr<nsIXULDocument> xulDoc(do_QueryInterface(mDocumentNode));
if (xulDoc)
return roles::APPLICATION;
#endif
return roles::DOCUMENT;
}
}
@@ -387,13 +383,11 @@ DocAccessible::URL(nsAString& aURL) const
void
DocAccessible::DocType(nsAString& aType) const
{
#ifdef MOZ_XUL
nsCOMPtr<nsIXULDocument> xulDoc(do_QueryInterface(mDocumentNode));
if (xulDoc) {
aType.AssignLiteral("window"); // doctype not implemented for XUL at time of writing - causes assertion
return;
}
#endif
dom::DocumentType* docType = mDocumentNode->GetDoctype();
if (docType)
docType->GetPublicId(aType);
+8 -31
View File
@@ -19,9 +19,7 @@
#include "Relation.h"
#include "Role.h"
#include "States.h"
#ifdef MOZ_XUL
#include "XULTreeAccessible.h"
#endif
#include "mozilla/dom/Element.h"
@@ -43,10 +41,8 @@
#include "nsFocusManager.h"
#include "nsGlobalWindow.h"
#ifdef MOZ_XUL
#include "nsIXULDocument.h"
#include "nsIXULWindow.h"
#endif
using namespace mozilla;
using namespace mozilla::a11y;
@@ -102,7 +98,6 @@ RootAccessible::NativeRole()
}
// RootAccessible protected member
#ifdef MOZ_XUL
uint32_t
RootAccessible::GetChromeFlags()
{
@@ -122,7 +117,6 @@ RootAccessible::GetChromeFlags()
xulWin->GetChromeFlags(&chromeFlags);
return chromeFlags;
}
#endif
uint64_t
RootAccessible::NativeState()
@@ -131,7 +125,6 @@ RootAccessible::NativeState()
if (state & states::DEFUNCT)
return state;
#ifdef MOZ_XUL
uint32_t chromeFlags = GetChromeFlags();
if (chromeFlags & nsIWebBrowserChrome::CHROME_WINDOW_RESIZE)
state |= states::SIZEABLE;
@@ -142,7 +135,6 @@ RootAccessible::NativeState()
state |= states::MOVEABLE;
if (chromeFlags & nsIWebBrowserChrome::CHROME_MODAL)
state |= states::MODAL;
#endif
nsFocusManager* fm = nsFocusManager::GetFocusManager();
if (fm && fm->GetActiveWindow() == mDocumentNode->GetWindow())
@@ -292,7 +284,6 @@ RootAccessible::ProcessDOMEvent(nsIDOMEvent* aDOMEvent)
if (!accessible)
return;
#ifdef MOZ_XUL
XULTreeAccessible* treeAcc = accessible->AsXULTree();
if (treeAcc) {
if (eventType.EqualsLiteral("TreeRowCountChanged")) {
@@ -305,7 +296,6 @@ RootAccessible::ProcessDOMEvent(nsIDOMEvent* aDOMEvent)
return;
}
}
#endif
if (eventType.EqualsLiteral("RadioStateChange")) {
uint64_t state = accessible->State();
@@ -341,7 +331,6 @@ RootAccessible::ProcessDOMEvent(nsIDOMEvent* aDOMEvent)
}
Accessible* treeItemAcc = nullptr;
#ifdef MOZ_XUL
// If it's a tree element, need the currently selected item.
if (treeAcc) {
treeItemAcc = accessible->CurrentItem();
@@ -385,29 +374,22 @@ RootAccessible::ProcessDOMEvent(nsIDOMEvent* aDOMEvent)
nsEventShell::FireEvent(selChangeEvent);
return;
}
}
else
#endif
if (eventType.EqualsLiteral("AlertActive")) {
} else if (eventType.EqualsLiteral("AlertActive")) {
nsEventShell::FireEvent(nsIAccessibleEvent::EVENT_ALERT, accessible);
}
else if (eventType.EqualsLiteral("popupshown")) {
} else if (eventType.EqualsLiteral("popupshown")) {
HandlePopupShownEvent(accessible);
}
else if (eventType.EqualsLiteral("DOMMenuInactive")) {
} else if (eventType.EqualsLiteral("DOMMenuInactive")) {
if (accessible->Role() == roles::MENUPOPUP) {
nsEventShell::FireEvent(nsIAccessibleEvent::EVENT_MENUPOPUP_END,
accessible);
}
}
else if (eventType.EqualsLiteral("DOMMenuItemActive")) {
} else if (eventType.EqualsLiteral("DOMMenuItemActive")) {
FocusMgr()->ActiveItemChanged(accessible);
#ifdef A11Y_LOG
if (logging::IsEnabled(logging::eFocus))
logging::ActiveItemChangeCausedBy("DOMMenuItemActive", accessible);
#endif
}
else if (eventType.EqualsLiteral("DOMMenuItemInactive")) {
} else if (eventType.EqualsLiteral("DOMMenuItemInactive")) {
// Process DOMMenuItemInactive event for autocomplete only because this is
// unique widget that may acquire focus from autocomplete popup while popup
// stays open and has no active item. In case of XUL tree autocomplete
@@ -421,8 +403,7 @@ RootAccessible::ProcessDOMEvent(nsIDOMEvent* aDOMEvent)
logging::ActiveItemChangeCausedBy("DOMMenuItemInactive", accessible);
#endif
}
}
else if (eventType.EqualsLiteral("DOMMenuBarActive")) { // Always from user input
} else if (eventType.EqualsLiteral("DOMMenuBarActive")) { // Always from user input
nsEventShell::FireEvent(nsIAccessibleEvent::EVENT_MENU_START,
accessible, eFromUserInput);
@@ -440,8 +421,7 @@ RootAccessible::ProcessDOMEvent(nsIDOMEvent* aDOMEvent)
logging::ActiveItemChangeCausedBy("DOMMenuBarActive", accessible);
#endif
}
}
else if (eventType.EqualsLiteral("DOMMenuBarInactive")) { // Always from user input
} else if (eventType.EqualsLiteral("DOMMenuBarInactive")) { // Always from user input
nsEventShell::FireEvent(nsIAccessibleEvent::EVENT_MENU_END,
accessible, eFromUserInput);
@@ -450,8 +430,7 @@ RootAccessible::ProcessDOMEvent(nsIDOMEvent* aDOMEvent)
if (logging::IsEnabled(logging::eFocus))
logging::ActiveItemChangeCausedBy("DOMMenuBarInactive", accessible);
#endif
}
else if (accessible->NeedsDOMUIEvent() &&
} else if (accessible->NeedsDOMUIEvent() &&
eventType.EqualsLiteral("ValueChange")) {
uint32_t event = accessible->HasNumericValue()
? nsIAccessibleEvent::EVENT_VALUE_CHANGE
@@ -650,7 +629,6 @@ RootAccessible::HandlePopupHidingEvent(nsINode* aPopupNode)
}
}
#ifdef MOZ_XUL
void
RootAccessible::HandleTreeRowCountChangedEvent(nsIDOMEvent* aEvent,
XULTreeAccessible* aAccessible)
@@ -714,7 +692,6 @@ RootAccessible::HandleTreeInvalidatedEvent(nsIDOMEvent* aEvent,
aAccessible->TreeViewInvalidated(startRow, endRow, startCol, endCol);
}
#endif
ProxyAccessible*
RootAccessible::GetPrimaryRemoteTopLevelContentDoc() const
+5 -7
View File
@@ -70,14 +70,12 @@ protected:
*/
void HandlePopupHidingEvent(nsINode* aNode);
#ifdef MOZ_XUL
void HandleTreeRowCountChangedEvent(nsIDOMEvent* aEvent,
XULTreeAccessible* aAccessible);
void HandleTreeInvalidatedEvent(nsIDOMEvent* aEvent,
XULTreeAccessible* aAccessible);
void HandleTreeRowCountChangedEvent(nsIDOMEvent* aEvent,
XULTreeAccessible* aAccessible);
void HandleTreeInvalidatedEvent(nsIDOMEvent* aEvent,
XULTreeAccessible* aAccessible);
uint32_t GetChromeFlags();
#endif
uint32_t GetChromeFlags();
};
inline RootAccessible*
+4
View File
@@ -52,6 +52,10 @@ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
'/accessible/windows/ia2',
'/accessible/windows/msaa',
]
elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
LOCAL_INCLUDES += [
'/accessible/mac',
]
else:
LOCAL_INCLUDES += [
'/accessible/other',
+4
View File
@@ -32,6 +32,10 @@ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
'/accessible/windows/ia2',
'/accessible/windows/msaa',
]
elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
LOCAL_INCLUDES += [
'/accessible/mac',
]
else:
LOCAL_INCLUDES += [
'/accessible/other',
+4
View File
@@ -19,6 +19,10 @@ else:
LOCAL_INCLUDES += [
'/accessible/atk',
]
elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
LOCAL_INCLUDES += [
'/accessible/mac',
]
else:
LOCAL_INCLUDES += [
'/accessible/other',
+4
View File
@@ -28,6 +28,10 @@ if CONFIG['ACCESSIBILITY']:
LOCAL_INCLUDES += [
'/accessible/atk',
]
elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
LOCAL_INCLUDES += [
'/accessible/mac',
]
else:
LOCAL_INCLUDES += [
'/accessible/other',
+1 -1
View File
@@ -786,7 +786,7 @@ this.UtteranceGenerator = { // jshint ignore:line
// This is because we expose the checked information on the node itself.
// XXX: this means the checked state is always appended to the end,
// regardless of the utterance ordering preference.
if ((Utils.AndroidSdkVersion < 16 || Utils.MozBuildApp === 'browser') &&
if (Utils.MozBuildApp === 'browser' &&
aState.contains(States.CHECKABLE)) {
let checked = aState.contains(States.CHECKED);
let statetr;
-12
View File
@@ -39,13 +39,6 @@ var PointerRelay = { // jshint ignore:line
delete this._eventsOfInterest;
switch (Utils.widgetToolkit) {
case 'android':
this._eventsOfInterest = {
'touchstart' : true,
'touchmove' : true,
'touchend' : true };
break;
default:
// Desktop.
this._eventsOfInterest = {
@@ -110,11 +103,6 @@ var PointerRelay = { // jshint ignore:line
target: aEvent.target
}];
if (Utils.widgetToolkit === 'android' &&
changedTouches.length === 1 && changedTouches[0].identifier === 1) {
return;
}
if (changedTouches.length === 1 &&
changedTouches[0].identifier === SYNTH_ID) {
return;
+17 -29
View File
@@ -257,11 +257,8 @@ AndroidPresenter.prototype.pivotChanged =
let androidEvents = [];
let isExploreByTouch = (aReason == Ci.nsIAccessiblePivot.REASON_POINT &&
Utils.AndroidSdkVersion >= 14);
let focusEventType = (Utils.AndroidSdkVersion >= 16) ?
this.ANDROID_VIEW_ACCESSIBILITY_FOCUSED :
this.ANDROID_VIEW_FOCUSED;
let isExploreByTouch = (aReason == Ci.nsIAccessiblePivot.REASON_POINT);
let focusEventType = this.ANDROID_VIEW_ACCESSIBILITY_FOCUSED;
if (isExploreByTouch) {
// This isn't really used by TalkBack so this is a half-hearted attempt
@@ -270,25 +267,21 @@ AndroidPresenter.prototype.pivotChanged =
}
let brailleOutput = {};
if (Utils.AndroidSdkVersion >= 16) {
if (!this._braillePresenter) {
this._braillePresenter = new BraillePresenter();
}
brailleOutput = this._braillePresenter.pivotChanged(aContext, aReason).
details;
if (!this._braillePresenter) {
this._braillePresenter = new BraillePresenter();
}
brailleOutput = this._braillePresenter.pivotChanged(aContext, aReason).
details;
if (aReason === Ci.nsIAccessiblePivot.REASON_TEXT) {
if (Utils.AndroidSdkVersion >= 16) {
let adjustedText = aContext.textAndAdjustedOffsets;
let adjustedText = aContext.textAndAdjustedOffsets;
androidEvents.push({
eventType: this.ANDROID_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY,
text: [adjustedText.text],
fromIndex: adjustedText.startOffset,
toIndex: adjustedText.endOffset
});
}
androidEvents.push({
eventType: this.ANDROID_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY,
text: [adjustedText.text],
fromIndex: adjustedText.startOffset,
toIndex: adjustedText.endOffset
});
} else {
let state = Utils.getState(aContext.accessible);
androidEvents.push({eventType: (isExploreByTouch) ?
@@ -371,7 +364,7 @@ AndroidPresenter.prototype.textSelectionChanged =
aOldEnd, aIsFromUserInput) {
let androidEvents = [];
if (Utils.AndroidSdkVersion >= 14 && !aIsFromUserInput) {
if (!aIsFromUserInput) {
if (!this._braillePresenter) {
this._braillePresenter = new BraillePresenter();
}
@@ -388,7 +381,7 @@ AndroidPresenter.prototype.textSelectionChanged =
});
}
if (Utils.AndroidSdkVersion >= 16 && aIsFromUserInput) {
if (aIsFromUserInput) {
let [from, to] = aOldStart < aStart ?
[aOldStart, aStart] : [aStart, aOldStart];
androidEvents.push({
@@ -407,10 +400,6 @@ AndroidPresenter.prototype.textSelectionChanged =
AndroidPresenter.prototype.viewportChanged =
function AndroidPresenter_viewportChanged(aWindow, aCurrentContext) {
if (Utils.AndroidSdkVersion < 14) {
return null;
}
let events = [{
eventType: this.ANDROID_VIEW_SCROLLED,
text: [],
@@ -420,7 +409,7 @@ AndroidPresenter.prototype.viewportChanged =
maxScrollY: aWindow.scrollMaxY
}];
if (Utils.AndroidSdkVersion >= 16 && aCurrentContext) {
if (aCurrentContext) {
let currentAcc = aCurrentContext.accessibleForBounds;
if (Utils.isAliveAndVisible(currentAcc)) {
events.push({
@@ -447,8 +436,7 @@ AndroidPresenter.prototype.announce =
return {
type: this.type,
details: [{
eventType: (Utils.AndroidSdkVersion >= 16) ?
this.ANDROID_ANNOUNCEMENT : this.ANDROID_VIEW_TEXT_CHANGED,
eventType: this.ANDROID_ANNOUNCEMENT,
text: [localizedAnnouncement],
addedCount: localizedAnnouncement.length,
removedCount: 0,
-25
View File
@@ -109,35 +109,13 @@ this.Utils = { // jshint ignore:line
return this._ScriptName;
},
get AndroidSdkVersion() {
if (!this._AndroidSdkVersion) {
if (Services.appinfo.OS == 'Android') {
this._AndroidSdkVersion = Services.sysinfo.getPropertyAsInt32(
'version');
} else {
// Most useful in desktop debugging.
this._AndroidSdkVersion = 16;
}
}
return this._AndroidSdkVersion;
},
set AndroidSdkVersion(value) {
// When we want to mimic another version.
this._AndroidSdkVersion = value;
},
get BrowserApp() {
if (!this.win) {
return null;
}
switch (this.MozBuildApp) {
case 'mobile/android':
return this.win.BrowserApp;
case 'browser':
return this.win.gBrowser;
case 'b2g':
return this.win.shell;
default:
return null;
}
@@ -147,9 +125,6 @@ this.Utils = { // jshint ignore:line
if (!this.BrowserApp) {
return null;
}
if (this.MozBuildApp == 'b2g') {
return this.BrowserApp.contentBrowser;
}
return this.BrowserApp.selectedBrowser;
},
+22
View File
@@ -0,0 +1,22 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:expandtab:shiftwidth=2:tabstop=2:
*/
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef MOZILLA_A11Y_ARIAGRIDACCESSIBLEWRAP_H
#define MOZILLA_A11Y_ARIAGRIDACCESSIBLEWRAP_H
#include "ARIAGridAccessible.h"
namespace mozilla {
namespace a11y {
typedef class ARIAGridAccessible ARIAGridAccessibleWrap;
typedef class ARIAGridCellAccessible ARIAGridCellAccessibleWrap;
} // namespace a11y
} // namespace mozilla
#endif
+103
View File
@@ -0,0 +1,103 @@
/* -*- Mode: Objective-C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/* For documentation of the accessibility architecture,
* see http://lxr.mozilla.org/seamonkey/source/accessible/accessible-docs.html
*/
#ifndef _AccessibleWrap_H_
#define _AccessibleWrap_H_
#include <objc/objc.h>
#include "Accessible.h"
#include "States.h"
#include "nsCOMPtr.h"
#include "nsTArray.h"
#if defined(__OBJC__)
@class mozAccessible;
#endif
namespace mozilla {
namespace a11y {
class AccessibleWrap : public Accessible
{
public: // construction, destruction
AccessibleWrap(nsIContent* aContent, DocAccessible* aDoc);
virtual ~AccessibleWrap();
/**
* Get the native Obj-C object (mozAccessible).
*/
virtual void GetNativeInterface(void** aOutAccessible) override;
/**
* The objective-c |Class| type that this accessible's native object
* should be instantied with. used on runtime to determine the
* right type for this accessible's associated native object.
*/
virtual Class GetNativeType ();
virtual void Shutdown () override;
virtual bool InsertChildAt(uint32_t aIdx, Accessible* aChild) override;
virtual bool RemoveChild(Accessible* aAccessible) override;
virtual nsresult HandleAccEvent(AccEvent* aEvent) override;
protected:
/**
* Return true if the parent doesn't have children to expose to AT.
*/
bool AncestorIsFlat();
/**
* Get the native object. Create it if needed.
*/
#if defined(__OBJC__)
mozAccessible* GetNativeObject();
#else
id GetNativeObject();
#endif
private:
/**
* Our native object. Private because its creation is done lazily.
* Don't access it directly. Ever. Unless you are GetNativeObject() or
* Shutdown()
*/
#if defined(__OBJC__)
// if we are in Objective-C, we use the actual Obj-C class.
mozAccessible* mNativeObject;
#else
id mNativeObject;
#endif
/**
* We have created our native. This does not mean there is one.
* This can never go back to false.
* We need it because checking whether we need a native object cost time.
*/
bool mNativeInited;
};
#if defined(__OBJC__)
void FireNativeEvent(mozAccessible* aNativeAcc, uint32_t aEventType);
#else
void FireNativeEvent(id aNativeAcc, uint32_t aEventType);
#endif
Class GetTypeFromRole(roles::Role aRole);
} // namespace a11y
} // namespace mozilla
#endif
+256
View File
@@ -0,0 +1,256 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "DocAccessible.h"
#include "nsObjCExceptions.h"
#include "Accessible-inl.h"
#include "nsAccUtils.h"
#include "Role.h"
#import "mozAccessible.h"
#import "mozActionElements.h"
#import "mozHTMLAccessible.h"
#import "mozTableAccessible.h"
#import "mozTextAccessible.h"
using namespace mozilla;
using namespace mozilla::a11y;
AccessibleWrap::
AccessibleWrap(nsIContent* aContent, DocAccessible* aDoc) :
Accessible(aContent, aDoc), mNativeObject(nil),
mNativeInited(false)
{
}
AccessibleWrap::~AccessibleWrap()
{
}
mozAccessible*
AccessibleWrap::GetNativeObject()
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
if (!mNativeInited && !mNativeObject && !IsDefunct() && !AncestorIsFlat()) {
uintptr_t accWrap = reinterpret_cast<uintptr_t>(this);
mNativeObject = [[GetNativeType() alloc] initWithAccessible:accWrap];
}
mNativeInited = true;
return mNativeObject;
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
}
void
AccessibleWrap::GetNativeInterface(void** aOutInterface)
{
*aOutInterface = static_cast<void*>(GetNativeObject());
}
// overridden in subclasses to create the right kind of object. by default we create a generic
// 'mozAccessible' node.
Class
AccessibleWrap::GetNativeType ()
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
if (IsXULTabpanels())
return [mozPaneAccessible class];
if (IsTable())
return [mozTableAccessible class];
if (IsTableRow())
return [mozTableRowAccessible class];
if (IsTableCell())
return [mozTableCellAccessible class];
return GetTypeFromRole(Role());
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
}
// this method is very important. it is fired when an accessible object "dies". after this point
// the object might still be around (because some 3rd party still has a ref to it), but it is
// in fact 'dead'.
void
AccessibleWrap::Shutdown ()
{
// this ensure we will not try to re-create the native object.
mNativeInited = true;
// we really intend to access the member directly.
if (mNativeObject) {
[mNativeObject expire];
[mNativeObject release];
mNativeObject = nil;
}
Accessible::Shutdown();
}
nsresult
AccessibleWrap::HandleAccEvent(AccEvent* aEvent)
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
nsresult rv = Accessible::HandleAccEvent(aEvent);
NS_ENSURE_SUCCESS(rv, rv);
if (IPCAccessibilityActive()) {
return NS_OK;
}
uint32_t eventType = aEvent->GetEventType();
// ignore everything but focus-changed, value-changed, caret, selection
// and document load complete events for now.
if (eventType != nsIAccessibleEvent::EVENT_FOCUS &&
eventType != nsIAccessibleEvent::EVENT_VALUE_CHANGE &&
eventType != nsIAccessibleEvent::EVENT_TEXT_VALUE_CHANGE &&
eventType != nsIAccessibleEvent::EVENT_TEXT_CARET_MOVED &&
eventType != nsIAccessibleEvent::EVENT_TEXT_SELECTION_CHANGED &&
eventType != nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_COMPLETE)
return NS_OK;
Accessible* accessible = aEvent->GetAccessible();
NS_ENSURE_STATE(accessible);
mozAccessible *nativeAcc = nil;
accessible->GetNativeInterface((void**)&nativeAcc);
if (!nativeAcc)
return NS_ERROR_FAILURE;
FireNativeEvent(nativeAcc, eventType);
return NS_OK;
NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
}
bool
AccessibleWrap::InsertChildAt(uint32_t aIdx, Accessible* aAccessible)
{
bool inserted = Accessible::InsertChildAt(aIdx, aAccessible);
if (inserted && mNativeObject)
[mNativeObject appendChild:aAccessible];
return inserted;
}
bool
AccessibleWrap::RemoveChild(Accessible* aAccessible)
{
bool removed = Accessible::RemoveChild(aAccessible);
if (removed && mNativeObject)
[mNativeObject invalidateChildren];
return removed;
}
////////////////////////////////////////////////////////////////////////////////
// AccessibleWrap protected
bool
AccessibleWrap::AncestorIsFlat()
{
// We don't create a native object if we're child of a "flat" accessible;
// for example, on OS X buttons shouldn't have any children, because that
// makes the OS confused.
//
// To maintain a scripting environment where the XPCOM accessible hierarchy
// look the same on all platforms, we still let the C++ objects be created
// though.
Accessible* parent = Parent();
while (parent) {
if (nsAccUtils::MustPrune(parent))
return true;
parent = parent->Parent();
}
// no parent was flat
return false;
}
void
a11y::FireNativeEvent(mozAccessible* aNativeAcc, uint32_t aEventType)
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
switch (aEventType) {
case nsIAccessibleEvent::EVENT_FOCUS:
[aNativeAcc didReceiveFocus];
break;
case nsIAccessibleEvent::EVENT_VALUE_CHANGE:
case nsIAccessibleEvent::EVENT_TEXT_VALUE_CHANGE:
[aNativeAcc valueDidChange];
break;
case nsIAccessibleEvent::EVENT_TEXT_CARET_MOVED:
case nsIAccessibleEvent::EVENT_TEXT_SELECTION_CHANGED:
[aNativeAcc selectedTextDidChange];
break;
case nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_COMPLETE:
[aNativeAcc documentLoadComplete];
break;
}
NS_OBJC_END_TRY_ABORT_BLOCK;
}
Class
a11y::GetTypeFromRole(roles::Role aRole)
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
switch (aRole) {
case roles::COMBOBOX:
case roles::PUSHBUTTON:
case roles::SPLITBUTTON:
case roles::TOGGLE_BUTTON:
{
return [mozButtonAccessible class];
}
case roles::PAGETAB:
return [mozButtonAccessible class];
case roles::CHECKBUTTON:
return [mozCheckboxAccessible class];
case roles::HEADING:
return [mozHeadingAccessible class];
case roles::PAGETABLIST:
return [mozTabsAccessible class];
case roles::ENTRY:
case roles::STATICTEXT:
case roles::CAPTION:
case roles::ACCEL_LABEL:
case roles::PASSWORD_TEXT:
// normal textfield (static or editable)
return [mozTextAccessible class];
case roles::TEXT_LEAF:
return [mozTextLeafAccessible class];
case roles::LINK:
return [mozLinkAccessible class];
default:
return [mozAccessible class];
}
return nil;
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
}
@@ -0,0 +1,22 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* vim:expandtab:shiftwidth=4:tabstop=4:
*/
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_a11y_ApplicationAccessibleWrap_h__
#define mozilla_a11y_ApplicationAccessibleWrap_h__
#include "ApplicationAccessible.h"
namespace mozilla {
namespace a11y {
typedef ApplicationAccessible ApplicationAccessibleWrap;
} // namespace a11y
} // namespace mozilla
#endif
+25
View File
@@ -0,0 +1,25 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_a11y_DocAccessibleWrap_h__
#define mozilla_a11y_DocAccessibleWrap_h__
#include "DocAccessible.h"
namespace mozilla {
namespace a11y {
class DocAccessibleWrap : public DocAccessible
{
public:
DocAccessibleWrap(nsIDocument* aDocument, nsIPresShell* aPresShell);
virtual ~DocAccessibleWrap();
};
} // namespace a11y
} // namespace mozilla
#endif
+21
View File
@@ -0,0 +1,21 @@
/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "DocAccessibleWrap.h"
#import "mozAccessible.h"
using namespace mozilla::a11y;
DocAccessibleWrap::
DocAccessibleWrap(nsIDocument* aDocument, nsIPresShell* aPresShell) :
DocAccessible(aDocument, aPresShell)
{
}
DocAccessibleWrap::~DocAccessibleWrap()
{
}
+24
View File
@@ -0,0 +1,24 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:expandtab:shiftwidth=2:tabstop=2:
*/
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_a11y_HTMLTableAccessibleWrap_h__
#define mozilla_a11y_HTMLTableAccessibleWrap_h__
#include "HTMLTableAccessible.h"
namespace mozilla {
namespace a11y {
typedef class HTMLTableAccessible HTMLTableAccessibleWrap;
typedef class HTMLTableCellAccessible HTMLTableCellAccessibleWrap;
typedef class HTMLTableHeaderCellAccessible HTMLTableHeaderCellAccessibleWrap;
} // namespace a11y
} // namespace mozilla
#endif
+20
View File
@@ -0,0 +1,20 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_a11y_HyperTextAccessibleWrap_h__
#define mozilla_a11y_HyperTextAccessibleWrap_h__
#include "HyperTextAccessible.h"
namespace mozilla {
namespace a11y {
typedef class HyperTextAccessible HyperTextAccessibleWrap;
} // namespace a11y
} // namespace mozilla
#endif
+22
View File
@@ -0,0 +1,22 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:expandtab:shiftwidth=2:tabstop=2:
*/
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_a11y_ImageAccessibleWrap_h__
#define mozilla_a11y_ImageAccessibleWrap_h__
#include "ImageAccessible.h"
namespace mozilla {
namespace a11y {
typedef class ImageAccessible ImageAccessibleWrap;
} // namespace a11y
} // namespace mozilla
#endif
+26
View File
@@ -0,0 +1,26 @@
/* -*- Mode: Objective-C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef _MacUtils_H_
#define _MacUtils_H_
@class NSString;
class nsString;
namespace mozilla {
namespace a11y {
namespace utils {
/**
* Get a localized string from the string bundle.
* Return nil if not found.
*/
NSString* LocalizedString(const nsString& aString);
}
}
}
#endif
+32
View File
@@ -0,0 +1,32 @@
/* -*- Mode: Objective-C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#import "MacUtils.h"
#include "Accessible.h"
#include "nsCocoaUtils.h"
namespace mozilla {
namespace a11y {
namespace utils {
/**
* Get a localized string from the a11y string bundle.
* Return nil if not found.
*/
NSString*
LocalizedString(const nsString& aString)
{
nsString text;
Accessible::TranslateString(aString, text);
return text.IsEmpty() ? nil : nsCocoaUtils::ToNSString(text);
}
}
}
}
+174
View File
@@ -0,0 +1,174 @@
/* -*- Mode: Objective-C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#import <Cocoa/Cocoa.h>
#include "Platform.h"
#include "ProxyAccessible.h"
#include "DocAccessibleParent.h"
#include "mozTableAccessible.h"
#include "nsAppShell.h"
namespace mozilla {
namespace a11y {
// Mac a11y whitelisting
static bool sA11yShouldBeEnabled = false;
bool
ShouldA11yBeEnabled()
{
EPlatformDisabledState disabledState = PlatformDisabledState();
return (disabledState == ePlatformIsForceEnabled) || ((disabledState == ePlatformIsEnabled) && sA11yShouldBeEnabled);
}
void
PlatformInit()
{
}
void
PlatformShutdown()
{
}
void
ProxyCreated(ProxyAccessible* aProxy, uint32_t)
{
// Pass in dummy state for now as retrieving proxy state requires IPC.
// Note that we can use ProxyAccessible::IsTable* functions here because they
// do not use IPC calls but that might change after bug 1210477.
Class type;
if (aProxy->IsTable())
type = [mozTableAccessible class];
else if (aProxy->IsTableRow())
type = [mozTableRowAccessible class];
else if (aProxy->IsTableCell())
type = [mozTableCellAccessible class];
else
type = GetTypeFromRole(aProxy->Role());
uintptr_t accWrap = reinterpret_cast<uintptr_t>(aProxy) | IS_PROXY;
mozAccessible* mozWrapper = [[type alloc] initWithAccessible:accWrap];
aProxy->SetWrapper(reinterpret_cast<uintptr_t>(mozWrapper));
mozAccessible* nativeParent = nullptr;
if (aProxy->IsDoc() && aProxy->AsDoc()->IsTopLevel()) {
// If proxy is top level, the parent we need to invalidate the children of
// will be a non-remote accessible.
Accessible* outerDoc = aProxy->OuterDocOfRemoteBrowser();
if (outerDoc) {
nativeParent = GetNativeFromGeckoAccessible(outerDoc);
}
} else {
// Non-top level proxies need proxy parents' children invalidated.
ProxyAccessible* parent = aProxy->Parent();
nativeParent = GetNativeFromProxy(parent);
NS_ASSERTION(parent, "a non-top-level proxy is missing a parent?");
}
if (nativeParent) {
[nativeParent invalidateChildren];
}
}
void
ProxyDestroyed(ProxyAccessible* aProxy)
{
mozAccessible* nativeParent = nil;
if (aProxy->IsDoc() && aProxy->AsDoc()->IsTopLevel()) {
// Invalidate native parent in parent process's children on proxy destruction
Accessible* outerDoc = aProxy->OuterDocOfRemoteBrowser();
if (outerDoc) {
nativeParent = GetNativeFromGeckoAccessible(outerDoc);
}
} else {
if (!aProxy->Document()->IsShutdown()) {
// Only do if the document has not been shut down, else parent will return
// garbage since we don't shut down children from top down.
ProxyAccessible* parent = aProxy->Parent();
// Invalidate proxy parent's children.
if (parent) {
nativeParent = GetNativeFromProxy(parent);
}
}
}
mozAccessible* wrapper = GetNativeFromProxy(aProxy);
[wrapper expire];
[wrapper release];
aProxy->SetWrapper(0);
if (nativeParent) {
[nativeParent invalidateChildren];
}
}
void
ProxyEvent(ProxyAccessible* aProxy, uint32_t aEventType)
{
// ignore everything but focus-changed, value-changed, caret and selection
// events for now.
if (aEventType != nsIAccessibleEvent::EVENT_FOCUS &&
aEventType != nsIAccessibleEvent::EVENT_VALUE_CHANGE &&
aEventType != nsIAccessibleEvent::EVENT_TEXT_VALUE_CHANGE &&
aEventType != nsIAccessibleEvent::EVENT_TEXT_CARET_MOVED &&
aEventType != nsIAccessibleEvent::EVENT_TEXT_SELECTION_CHANGED)
return;
mozAccessible* wrapper = GetNativeFromProxy(aProxy);
if (wrapper)
FireNativeEvent(wrapper, aEventType);
}
void
ProxyStateChangeEvent(ProxyAccessible* aProxy, uint64_t, bool)
{
// mac doesn't care about state change events
}
void
ProxyCaretMoveEvent(ProxyAccessible* aTarget, int32_t aOffset)
{
mozAccessible* wrapper = GetNativeFromProxy(aTarget);
if (wrapper)
[wrapper selectedTextDidChange];
}
void
ProxyTextChangeEvent(ProxyAccessible*, const nsString&, int32_t, uint32_t,
bool, bool)
{
}
void
ProxyShowHideEvent(ProxyAccessible*, ProxyAccessible*, bool, bool)
{
}
void
ProxySelectionEvent(ProxyAccessible*, ProxyAccessible*, uint32_t)
{
}
} // namespace a11y
} // namespace mozilla
@interface GeckoNSApplication(a11y)
-(void)accessibilitySetValue:(id)value forAttribute:(NSString*)attribute;
@end
@implementation GeckoNSApplication(a11y)
-(void)accessibilitySetValue:(id)value forAttribute:(NSString*)attribute
{
if ([attribute isEqualToString:@"AXEnhancedUserInterface"])
mozilla::a11y::sA11yShouldBeEnabled = ([value intValue] == 1);
return [super accessibilitySetValue:value forAttribute:attribute];
}
@end
+34
View File
@@ -0,0 +1,34 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/* For documentation of the accessibility architecture,
* see http://lxr.mozilla.org/seamonkey/source/accessible/accessible-docs.html
*/
#ifndef mozilla_a11y_RootAccessibleWrap_h__
#define mozilla_a11y_RootAccessibleWrap_h__
#include "RootAccessible.h"
namespace mozilla {
namespace a11y {
class RootAccessibleWrap : public RootAccessible
{
public:
RootAccessibleWrap(nsIDocument* aDocument, nsIPresShell* aPresShell);
virtual ~RootAccessibleWrap();
Class GetNativeType ();
// let's our native accessible get in touch with the
// native cocoa view that is our accessible parent.
void GetNativeWidget (void **aOutView);
};
} // namespace a11y
} // namespace mozilla
#endif
+53
View File
@@ -0,0 +1,53 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "RootAccessibleWrap.h"
#include "mozDocAccessible.h"
#include "nsCOMPtr.h"
#include "nsObjCExceptions.h"
#include "nsIFrame.h"
#include "nsView.h"
#include "nsIWidget.h"
using namespace mozilla::a11y;
RootAccessibleWrap::
RootAccessibleWrap(nsIDocument* aDocument, nsIPresShell* aPresShell) :
RootAccessible(aDocument, aPresShell)
{
}
RootAccessibleWrap::~RootAccessibleWrap()
{
}
Class
RootAccessibleWrap::GetNativeType()
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
return [mozRootAccessible class];
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
}
void
RootAccessibleWrap::GetNativeWidget(void** aOutView)
{
nsIFrame *frame = GetFrame();
if (frame) {
nsView *view = frame->GetView();
if (view) {
nsIWidget *widget = view->GetWidget();
if (widget) {
*aOutView = (void**)widget->GetNativeData (NS_NATIVE_WIDGET);
NS_ASSERTION (*aOutView,
"Couldn't get the native NSView parent we need to connect the accessibility hierarchy!");
}
}
}
}
+19
View File
@@ -0,0 +1,19 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_a11y_TextLeafAccessibleWrap_h__
#define mozilla_a11y_TextLeafAccessibleWrap_h__
#include "TextLeafAccessible.h"
namespace mozilla {
namespace a11y {
typedef class TextLeafAccessible TextLeafAccessibleWrap;
} // namespace a11y
} // namespace mozilla
#endif
+20
View File
@@ -0,0 +1,20 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_a11y_XULListboxAccessibleWrap_h__
#define mozilla_a11y_XULListboxAccessibleWrap_h__
#include "XULListboxAccessible.h"
namespace mozilla {
namespace a11y {
typedef class XULListboxAccessible XULListboxAccessibleWrap;
typedef class XULListCellAccessible XULListCellAccessibleWrap;
} // namespace a11y
} // namespace mozilla
#endif
+19
View File
@@ -0,0 +1,19 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_a11y_XULMenuAccessibleWrap_h__
#define mozilla_a11y_XULMenuAccessibleWrap_h__
#include "XULMenuAccessible.h"
namespace mozilla {
namespace a11y {
typedef class XULMenuitemAccessible XULMenuitemAccessibleWrap;
} // namespace a11y
} // namespace mozilla
#endif
@@ -0,0 +1,20 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_a11y_XULTreeGridAccessibleWrap_h__
#define mozilla_a11y_XULTreeGridAccessibleWrap_h__
#include "XULTreeGridAccessible.h"
namespace mozilla {
namespace a11y {
typedef class XULTreeGridAccessible XULTreeGridAccessibleWrap;
typedef class XULTreeGridCellAccessible XULTreeGridCellAccessibleWrap;
} // namespace a11y
} // namespace mozilla
#endif
+44
View File
@@ -0,0 +1,44 @@
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
EXPORTS += [
'mozAccessibleProtocol.h',
]
EXPORTS.mozilla.a11y += [
'AccessibleWrap.h',
'HyperTextAccessibleWrap.h',
]
SOURCES += [
'AccessibleWrap.mm',
'DocAccessibleWrap.mm',
'MacUtils.mm',
'mozAccessible.mm',
'mozActionElements.mm',
'mozDocAccessible.mm',
'mozHTMLAccessible.mm',
'mozTableAccessible.mm',
'mozTextAccessible.mm',
'Platform.mm',
'RootAccessibleWrap.mm',
]
LOCAL_INCLUDES += [
'/accessible/base',
'/accessible/generic',
'/accessible/html',
'/accessible/ipc',
'/accessible/ipc/other',
'/accessible/xul',
'/layout/generic',
'/layout/xul',
'/widget',
'/widget/cocoa',
]
FINAL_LIBRARY = 'xul'
include('/ipc/chromium/chromium-config.mozbuild')
+181
View File
@@ -0,0 +1,181 @@
/* -*- Mode: Objective-C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "AccessibleWrap.h"
#include "ProxyAccessible.h"
#import <Cocoa/Cocoa.h>
#import "mozAccessibleProtocol.h"
@class mozRootAccessible;
/**
* All mozAccessibles are either abstract objects (that correspond to XUL
* widgets, HTML frames, etc) or are attached to a certain view; for example
* a document view. When we hand an object off to an AT, we always want
* to give it the represented view, in the latter case.
*/
namespace mozilla {
namespace a11y {
inline id <mozAccessible>
GetObjectOrRepresentedView(id <mozAccessible> aObject)
{
return [aObject hasRepresentedView] ? [aObject representedView] : aObject;
}
inline mozAccessible*
GetNativeFromGeckoAccessible(Accessible* aAccessible)
{
mozAccessible* native = nil;
aAccessible->GetNativeInterface((void**)&native);
return native;
}
inline mozAccessible*
GetNativeFromProxy(const ProxyAccessible* aProxy)
{
return reinterpret_cast<mozAccessible*>(aProxy->GetWrapper());
}
} // a11y
} // mozilla
// This is OR'd with the Accessible owner to indicate the wrap-ee is a proxy.
static const uintptr_t IS_PROXY = 1;
@interface mozAccessible : NSObject <mozAccessible>
{
/**
* Weak reference; it owns us.
*/
uintptr_t mGeckoAccessible;
/**
* Strong ref to array of children
*/
NSMutableArray* mChildren;
/**
* Weak reference to the parent
*/
mozAccessible* mParent;
/**
* The role of our gecko accessible.
*/
mozilla::a11y::role mRole;
}
// return the Accessible for this mozAccessible if it exists.
- (mozilla::a11y::AccessibleWrap*)getGeckoAccessible;
// return the ProxyAccessible for this mozAccessible if it exists.
- (mozilla::a11y::ProxyAccessible*)getProxyAccessible;
// inits with the gecko owner.
- (id)initWithAccessible:(uintptr_t)aGeckoObj;
// our accessible parent (AXParent)
- (id <mozAccessible>)parent;
// a lazy cache of our accessible children (AXChildren). updated
- (NSArray*)children;
// returns the size of this accessible.
- (NSValue*)size;
// returns the position, in cocoa coordinates.
- (NSValue*)position;
// can be overridden to report another role name.
- (NSString*)role;
// a subrole is a more specialized variant of the role. for example,
// the role might be "textfield", while the subrole is "password textfield".
- (NSString*)subrole;
// Return the role description, as there are a few exceptions.
- (NSString*)roleDescription;
// returns the native window we're inside.
- (NSWindow*)window;
// the value of this element.
- (id)value;
// name that is associated with this accessible (for buttons, etc)
- (NSString*)title;
// the accessible description (help text) of this particular instance.
- (NSString*)help;
- (BOOL)isEnabled;
// information about focus.
- (BOOL)isFocused;
- (BOOL)canBeFocused;
// returns NO if for some reason we were unable to focus the element.
- (BOOL)focus;
// notifications sent out to listening accessible providers.
- (void)didReceiveFocus;
- (void)valueDidChange;
- (void)selectedTextDidChange;
- (void)documentLoadComplete;
// internal method to retrieve a child at a given index.
- (id)childAt:(uint32_t)i;
#pragma mark -
// invalidates and removes all our children from our cached array.
- (void)invalidateChildren;
/**
* Append a child if they are already cached.
*/
- (void)appendChild:(mozilla::a11y::Accessible*)aAccessible;
// makes ourselves "expired". after this point, we might be around if someone
// has retained us (e.g., a third-party), but we really contain no information.
- (void)expire;
- (BOOL)isExpired;
#ifdef DEBUG
- (void)printHierarchy;
- (void)printHierarchyWithLevel:(unsigned)numSpaces;
- (void)sanityCheckChildren;
- (void)sanityCheckChildren:(NSArray*)theChildren;
#endif
// ---- NSAccessibility methods ---- //
// whether to skip this element when traversing the accessibility
// hierarchy.
- (BOOL)accessibilityIsIgnored;
// called by third-parties to determine the deepest child element under the mouse
- (id)accessibilityHitTest:(NSPoint)point;
// returns the deepest unignored focused accessible element
- (id)accessibilityFocusedUIElement;
// a mozAccessible needs to at least provide links to its parent and
// children.
- (NSArray*)accessibilityAttributeNames;
// value for the specified attribute
- (id)accessibilityAttributeValue:(NSString*)attribute;
- (BOOL)accessibilityIsAttributeSettable:(NSString*)attribute;
- (void)accessibilitySetValue:(id)value forAttribute:(NSString*)attribute;
@end
File diff suppressed because it is too large. Load diff
+69
View File
@@ -0,0 +1,69 @@
/* -*- Mode: Objective-C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#import <Cocoa/Cocoa.h>
#import "mozView.h"
/* This protocol's primary use is so widget/cocoa can talk back to us
properly.
ChildView owns the topmost mozRootAccessible, and needs to take care of setting up
that parent/child relationship.
This protocol is thus used to make sure it knows it's talking to us, and not
just some random |id|.
*/
@protocol mozAccessible
// returns whether this accessible is the root accessible. there is one
// root accessible per window.
- (BOOL)isRoot;
// some mozAccessibles implement accessibility support in place of another object. for example,
// ChildView gets its support from us.
//
// instead of returning a mozAccessible to the OS when it wants an object, we need to pass the view we represent, so the
// OS doesn't get confused and think we return some random object.
- (BOOL)hasRepresentedView;
- (id)representedView;
#ifdef DEBUG
// debug utility that will print the native accessibility tree, starting
// at this node.
- (void)printHierarchy;
#endif
/*** general ***/
// returns the accessible at the specified point.
- (id)accessibilityHitTest:(NSPoint)point;
// whether this element is flagged as ignored.
- (BOOL)accessibilityIsIgnored;
// currently focused UI element (possibly a child accessible)
- (id)accessibilityFocusedUIElement;
/*** attributes ***/
// all supported attributes
- (NSArray*)accessibilityAttributeNames;
// value for given attribute.
- (id)accessibilityAttributeValue:(NSString*)attribute;
// whether a particular attribute can be modified
- (BOOL)accessibilityIsAttributeSettable:(NSString*)attribute;
/*** actions ***/
- (NSArray*)accessibilityActionNames;
- (NSString*)accessibilityActionDescription:(NSString*)action;
- (void)accessibilityPerformAction:(NSString*)action;
@end
+37
View File
@@ -0,0 +1,37 @@
/* -*- Mode: Objective-C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#import <Cocoa/Cocoa.h>
#import "mozAccessible.h"
/* Simple subclasses for things like checkboxes, buttons, etc. */
@interface mozButtonAccessible : mozAccessible
{
}
- (BOOL)hasPopup;
- (void)click;
- (BOOL)isTab;
@end
@interface mozCheckboxAccessible : mozButtonAccessible
// returns one of the constants defined in CheckboxValue
- (int)isChecked;
@end
/* Class for tabs - not individual tabs */
@interface mozTabsAccessible : mozAccessible
{
NSMutableArray* mTabs;
}
-(id)tabs;
@end
/**
* Accessible for a PANE
*/
@interface mozPaneAccessible : mozAccessible
@end
+340
View File
@@ -0,0 +1,340 @@
/* -*- Mode: Objective-C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#import "mozActionElements.h"
#import "MacUtils.h"
#include "Accessible-inl.h"
#include "DocAccessible.h"
#include "XULTabAccessible.h"
#include "nsDeckFrame.h"
#include "nsObjCExceptions.h"
using namespace mozilla::a11y;
enum CheckboxValue {
// these constants correspond to the values in the OS
kUnchecked = 0,
kChecked = 1,
kMixed = 2
};
@implementation mozButtonAccessible
- (NSArray*)accessibilityAttributeNames
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
static NSArray *attributes = nil;
if (!attributes) {
attributes = [[NSArray alloc] initWithObjects:NSAccessibilityParentAttribute, // required
NSAccessibilityRoleAttribute, // required
NSAccessibilityRoleDescriptionAttribute,
NSAccessibilityPositionAttribute, // required
NSAccessibilitySizeAttribute, // required
NSAccessibilityWindowAttribute, // required
NSAccessibilityPositionAttribute, // required
NSAccessibilityTopLevelUIElementAttribute, // required
NSAccessibilityHelpAttribute,
NSAccessibilityEnabledAttribute, // required
NSAccessibilityFocusedAttribute, // required
NSAccessibilityTitleAttribute, // required
NSAccessibilityChildrenAttribute,
NSAccessibilityDescriptionAttribute,
#if DEBUG
@"AXMozDescription",
#endif
nil];
}
return attributes;
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
}
- (id)accessibilityAttributeValue:(NSString *)attribute
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
if ([attribute isEqualToString:NSAccessibilityChildrenAttribute]) {
if ([self hasPopup])
return [self children];
return nil;
}
if ([attribute isEqualToString:NSAccessibilityRoleDescriptionAttribute]) {
if ([self isTab])
return utils::LocalizedString(NS_LITERAL_STRING("tab"));
return NSAccessibilityRoleDescription([self role], nil);
}
return [super accessibilityAttributeValue:attribute];
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
}
- (BOOL)accessibilityIsIgnored
{
return ![self getGeckoAccessible] && ![self getProxyAccessible];
}
- (NSArray*)accessibilityActionNames
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
if ([self isEnabled]) {
if ([self hasPopup])
return [NSArray arrayWithObjects:NSAccessibilityPressAction,
NSAccessibilityShowMenuAction,
nil];
return [NSArray arrayWithObject:NSAccessibilityPressAction];
}
return nil;
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
}
- (NSString*)accessibilityActionDescription:(NSString*)action
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
if ([action isEqualToString:NSAccessibilityPressAction]) {
if ([self isTab])
return utils::LocalizedString(NS_LITERAL_STRING("switch"));
return @"press button"; // XXX: localize this later?
}
if ([self hasPopup]) {
if ([action isEqualToString:NSAccessibilityShowMenuAction])
return @"show menu";
}
return nil;
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
}
- (void)accessibilityPerformAction:(NSString*)action
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
if ([self isEnabled] && [action isEqualToString:NSAccessibilityPressAction]) {
// TODO: this should bring up the menu, but currently doesn't.
// once msaa and atk have merged better, they will implement
// the action needed to show the menu.
[self click];
}
NS_OBJC_END_TRY_ABORT_BLOCK;
}
- (void)click
{
// both buttons and checkboxes have only one action. we should really stop using arbitrary
// arrays with actions, and define constants for these actions.
if (AccessibleWrap* accWrap = [self getGeckoAccessible])
accWrap->DoAction(0);
else if (ProxyAccessible* proxy = [self getProxyAccessible])
proxy->DoAction(0);
}
- (BOOL)isTab
{
if (AccessibleWrap* accWrap = [self getGeckoAccessible])
return accWrap->Role() == roles::PAGETAB;
if (ProxyAccessible* proxy = [self getProxyAccessible])
return proxy->Role() == roles::PAGETAB;
return false;
}
- (BOOL)hasPopup
{
if (AccessibleWrap* accWrap = [self getGeckoAccessible])
return accWrap->NativeState() & states::HASPOPUP;
if (ProxyAccessible* proxy = [self getProxyAccessible])
return proxy->NativeState() & states::HASPOPUP;
return false;
}
@end
@implementation mozCheckboxAccessible
- (NSString*)accessibilityActionDescription:(NSString*)action
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
if ([action isEqualToString:NSAccessibilityPressAction]) {
if ([self isChecked] != kUnchecked)
return @"uncheck checkbox"; // XXX: localize this later?
return @"check checkbox"; // XXX: localize this later?
}
return nil;
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
}
- (int)isChecked
{
uint64_t state = 0;
if (AccessibleWrap* accWrap = [self getGeckoAccessible])
state = accWrap->NativeState();
else if (ProxyAccessible* proxy = [self getProxyAccessible])
state = proxy->NativeState();
// check if we're checked or in a mixed state
if (state & states::CHECKED) {
return (state & states::MIXED) ? kMixed : kChecked;
}
return kUnchecked;
}
- (id)value
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
return [NSNumber numberWithInt:[self isChecked]];
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
}
@end
@implementation mozTabsAccessible
- (void)dealloc
{
[mTabs release];
[super dealloc];
}
- (NSArray*)accessibilityAttributeNames
{
// standard attributes that are shared and supported by root accessible (AXMain) elements.
static NSMutableArray* attributes = nil;
if (!attributes) {
attributes = [[super accessibilityAttributeNames] mutableCopy];
[attributes addObject:NSAccessibilityContentsAttribute];
[attributes addObject:NSAccessibilityTabsAttribute];
}
return attributes;
}
- (id)accessibilityAttributeValue:(NSString *)attribute
{
if ([attribute isEqualToString:NSAccessibilityContentsAttribute])
return [super children];
if ([attribute isEqualToString:NSAccessibilityTabsAttribute])
return [self tabs];
return [super accessibilityAttributeValue:attribute];
}
/**
* Returns the selected tab (the mozAccessible)
*/
- (id)value
{
mozAccessible* nativeAcc = nil;
if (AccessibleWrap* accWrap = [self getGeckoAccessible]) {
if (Accessible* accTab = accWrap->GetSelectedItem(0)) {
accTab->GetNativeInterface((void**)&nativeAcc);
}
} else if (ProxyAccessible* proxy = [self getProxyAccessible]) {
if (ProxyAccessible* proxyTab = proxy->GetSelectedItem(0)) {
nativeAcc = GetNativeFromProxy(proxyTab);
}
}
return nativeAcc;
}
/**
* Return the mozAccessibles that are the tabs.
*/
- (id)tabs
{
if (mTabs)
return mTabs;
NSArray* children = [self children];
NSEnumerator* enumerator = [children objectEnumerator];
mTabs = [[NSMutableArray alloc] init];
id obj;
while ((obj = [enumerator nextObject]))
if ([obj isTab])
[mTabs addObject:obj];
return mTabs;
}
- (void)invalidateChildren
{
[super invalidateChildren];
[mTabs release];
mTabs = nil;
}
@end
@implementation mozPaneAccessible
- (NSUInteger)accessibilityArrayAttributeCount:(NSString*)attribute
{
AccessibleWrap* accWrap = [self getGeckoAccessible];
ProxyAccessible* proxy = [self getProxyAccessible];
if (!accWrap && !proxy)
return 0;
// By default this calls -[[mozAccessible children] count].
// Since we don't cache mChildren. This is faster.
if ([attribute isEqualToString:NSAccessibilityChildrenAttribute]) {
if (accWrap)
return accWrap->ChildCount() ? 1 : 0;
return proxy->ChildrenCount() ? 1 : 0;
}
return [super accessibilityArrayAttributeCount:attribute];
}
- (NSArray*)children
{
if (![self getGeckoAccessible])
return nil;
nsDeckFrame* deckFrame = do_QueryFrame([self getGeckoAccessible]->GetFrame());
nsIFrame* selectedFrame = deckFrame ? deckFrame->GetSelectedBox() : nullptr;
Accessible* selectedAcc = nullptr;
if (selectedFrame) {
nsINode* node = selectedFrame->GetContent();
selectedAcc = [self getGeckoAccessible]->Document()->GetAccessible(node);
}
if (selectedAcc) {
mozAccessible *curNative = GetNativeFromGeckoAccessible(selectedAcc);
if (curNative)
return [NSArray arrayWithObjects:GetObjectOrRepresentedView(curNative), nil];
}
return nil;
}
@end
+31
View File
@@ -0,0 +1,31 @@
/* -*- Mode: Objective-C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#import <Cocoa/Cocoa.h>
#import "mozAccessible.h"
// our protocol that we implement (so cocoa widgets can talk to us)
#import "mozAccessibleProtocol.h"
/*
The root accessible. There is one per window.
Created by the RootAccessibleWrap.
*/
@interface mozRootAccessible : mozAccessible
{
// the mozView that we're representing.
// all outside communication goes through the mozView.
// in reality, it's just piping all calls to us, and we're
// doing its dirty work!
//
// whenever someone asks who we are (e.g., a child asking
// for its parent, or our parent asking for its child), we'll
// respond the mozView. it is absolutely necessary for third-
// party tools that we do this!
//
// /hwaara
id <mozView, mozAccessible> mParallelView; // weak ref
}
@end
+111
View File
@@ -0,0 +1,111 @@
/* -*- Mode: Objective-C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "RootAccessibleWrap.h"
#import "mozDocAccessible.h"
#import "mozView.h"
// This must be included last:
#include "nsObjCExceptions.h"
using namespace mozilla::a11y;
static id <mozAccessible, mozView>
getNativeViewFromRootAccessible(Accessible* aAccessible)
{
RootAccessibleWrap* root =
static_cast<RootAccessibleWrap*>(aAccessible->AsRoot());
id <mozAccessible, mozView> nativeView = nil;
root->GetNativeWidget ((void**)&nativeView);
return nativeView;
}
#pragma mark -
@implementation mozRootAccessible
- (NSArray*)accessibilityAttributeNames
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
// if we're expired, we don't support any attributes.
if (![self getGeckoAccessible])
return [NSArray array];
// standard attributes that are shared and supported by root accessible (AXMain) elements.
static NSMutableArray* attributes = nil;
if (!attributes) {
attributes = [[super accessibilityAttributeNames] mutableCopy];
[attributes addObject:NSAccessibilityMainAttribute];
[attributes addObject:NSAccessibilityMinimizedAttribute];
}
return attributes;
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
}
- (id)accessibilityAttributeValue:(NSString *)attribute
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
if ([attribute isEqualToString:NSAccessibilityMainAttribute])
return [NSNumber numberWithBool:[[self window] isMainWindow]];
if ([attribute isEqualToString:NSAccessibilityMinimizedAttribute])
return [NSNumber numberWithBool:[[self window] isMiniaturized]];
return [super accessibilityAttributeValue:attribute];
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
}
// return the AXParent that our parallell NSView tells us about.
- (id)parent
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
if (!mParallelView)
mParallelView = (id<mozView, mozAccessible>)[self representedView];
if (mParallelView)
return [mParallelView accessibilityAttributeValue:NSAccessibilityParentAttribute];
NSAssert(mParallelView, @"we're a root accessible w/o native view?");
return [super parent];
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
}
- (BOOL)hasRepresentedView
{
return YES;
}
// this will return our parallell NSView. see mozDocAccessible.h
- (id)representedView
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
if (mParallelView)
return (id)mParallelView;
mParallelView = getNativeViewFromRootAccessible ([self getGeckoAccessible]);
NSAssert(mParallelView, @"can't return root accessible's native parallel view.");
return mParallelView;
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
}
- (BOOL)isRoot
{
return YES;
}
@end
+16
View File
@@ -0,0 +1,16 @@
/* -*- Mode: Objective-C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:expandtab:shiftwidth=2:tabstop=2:
*/
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#import "mozAccessible.h"
@interface mozHeadingAccessible : mozAccessible
@end
@interface mozLinkAccessible : mozAccessible
@end
+141
View File
@@ -0,0 +1,141 @@
/* -*- Mode: Objective-C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:expandtab:shiftwidth=2:tabstop=2:
*/
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#import "mozHTMLAccessible.h"
#import "Accessible-inl.h"
#import "HyperTextAccessible.h"
#import "nsCocoaUtils.h"
using namespace mozilla::a11y;
@implementation mozHeadingAccessible
- (NSString*)title
{
nsAutoString title;
if (AccessibleWrap* accWrap = [self getGeckoAccessible]) {
mozilla::ErrorResult rv;
// XXX use the flattening API when there are available
// see bug 768298
accWrap->GetContent()->GetTextContent(title, rv);
} else if (ProxyAccessible* proxy = [self getProxyAccessible]) {
proxy->Title(title);
}
return nsCocoaUtils::ToNSString(title);
}
- (id)value
{
uint32_t level = 0;
if (AccessibleWrap* accWrap = [self getGeckoAccessible]) {
level = accWrap->GetLevelInternal();
} else if (ProxyAccessible* proxy = [self getProxyAccessible]) {
level = proxy->GetLevelInternal();
}
return [NSNumber numberWithInt:level];
}
@end
@interface mozLinkAccessible ()
-(NSURL*)url;
@end
@implementation mozLinkAccessible
- (NSArray*)accessibilityAttributeNames
{
// if we're expired, we don't support any attributes.
if (![self getGeckoAccessible] && ![self getProxyAccessible])
return [NSArray array];
static NSMutableArray* attributes = nil;
if (!attributes) {
attributes = [[super accessibilityAttributeNames] mutableCopy];
[attributes addObject:NSAccessibilityURLAttribute];
}
return attributes;
}
- (id)accessibilityAttributeValue:(NSString *)attribute
{
if ([attribute isEqualToString:NSAccessibilityURLAttribute])
return [self url];
return [super accessibilityAttributeValue:attribute];
}
- (NSArray*)accessibilityActionNames
{
// if we're expired, we don't support any attributes.
if (![self getGeckoAccessible] && ![self getProxyAccessible])
return [NSArray array];
static NSArray* actionNames = nil;
if (!actionNames) {
actionNames = [[NSArray alloc] initWithObjects:NSAccessibilityPressAction,
nil];
}
return actionNames;
}
- (void)accessibilityPerformAction:(NSString*)action
{
AccessibleWrap* accWrap = [self getGeckoAccessible];
ProxyAccessible* proxy = [self getProxyAccessible];
if (!accWrap && !proxy) {
return;
}
if ([action isEqualToString:NSAccessibilityPressAction]) {
if (accWrap) {
accWrap->DoAction(0);
} else if (proxy) {
proxy->DoAction(0);
}
return;
}
[super accessibilityPerformAction:action];
}
- (NSString*)customDescription
{
return @"";
}
- (NSString*)value
{
return @"";
}
- (NSURL*)url
{
nsAutoString value;
if (AccessibleWrap* accWrap = [self getGeckoAccessible]) {
accWrap->Value(value);
} else if (ProxyAccessible* proxy = [self getProxyAccessible]) {
proxy->Value(value);
}
NSString* urlString = value.IsEmpty() ? nil : nsCocoaUtils::ToNSString(value);
if (!urlString)
return nil;
return [NSURL URLWithString:urlString];
}
@end
+28
View File
@@ -0,0 +1,28 @@
/* -*- Mode: Objective-C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:expandtab:shiftwidth=2:tabstop=2:
*/
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#import "mozAccessible.h"
@interface mozTablePartAccessible : mozAccessible
- (BOOL)isLayoutTablePart;
- (NSString*)role;
@end
@interface mozTableAccessible : mozTablePartAccessible
- (NSArray*)additionalAccessibilityAttributeNames;
- (id)accessibilityAttributeValue:(NSString*)attribute;
@end
@interface mozTableRowAccessible : mozTablePartAccessible
- (NSArray*)additionalAccessibilityAttributeNames;
- (id)accessibilityAttributeValue:(NSString*)attribute;
@end
@interface mozTableCellAccessible : mozTablePartAccessible
- (NSArray*)additionalAccessibilityAttributeNames;
- (id)accessibilityAttributeValue:(NSString*)attribute;
@end
+281
View File
@@ -0,0 +1,281 @@
/* -*- Mode: Objective-C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:expandtab:shiftwidth=2:tabstop=2:
*/
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#import "Accessible-inl.h"
#import "mozTableAccessible.h"
#import "TableAccessible.h"
#import "TableCellAccessible.h"
#import "nsCocoaUtils.h"
using namespace mozilla::a11y;
// convert an array of Gecko accessibles to an NSArray of native accessibles
static inline NSMutableArray*
ConvertToNSArray(nsTArray<Accessible*>& aArray)
{
NSMutableArray* nativeArray = [[NSMutableArray alloc] init];
// iterate through the list, and get each native accessible.
size_t totalCount = aArray.Length();
for (size_t i = 0; i < totalCount; i++) {
Accessible* curAccessible = aArray.ElementAt(i);
mozAccessible* curNative = GetNativeFromGeckoAccessible(curAccessible);
if (curNative)
[nativeArray addObject:GetObjectOrRepresentedView(curNative)];
}
return nativeArray;
}
// convert an array of Gecko proxy accessibles to an NSArray of native accessibles
static inline NSMutableArray*
ConvertToNSArray(nsTArray<ProxyAccessible*>& aArray)
{
NSMutableArray* nativeArray = [[NSMutableArray alloc] init];
// iterate through the list, and get each native accessible.
size_t totalCount = aArray.Length();
for (size_t i = 0; i < totalCount; i++) {
ProxyAccessible* curAccessible = aArray.ElementAt(i);
mozAccessible* curNative = GetNativeFromProxy(curAccessible);
if (curNative)
[nativeArray addObject:GetObjectOrRepresentedView(curNative)];
}
return nativeArray;
}
@implementation mozTablePartAccessible
- (BOOL)isLayoutTablePart;
{
if (Accessible* accWrap = [self getGeckoAccessible]) {
while (accWrap) {
if (accWrap->IsTable()) {
return accWrap->AsTable()->IsProbablyLayoutTable();
}
accWrap = accWrap->Parent();
}
return false;
}
if (ProxyAccessible* proxy = [self getProxyAccessible]) {
while (proxy) {
if (proxy->IsTable()) {
return proxy->TableIsProbablyForLayout();
}
proxy = proxy->Parent();
}
}
return false;
}
- (NSString*)role
{
return [self isLayoutTablePart] ? NSAccessibilityGroupRole : [super role];
}
@end
@implementation mozTableAccessible
- (NSArray*)additionalAccessibilityAttributeNames
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
NSArray* additionalAttributes = [super additionalAccessibilityAttributeNames];
if ([self isLayoutTablePart]) {
return additionalAttributes;
}
static NSArray* tableAttrs = nil;
if (!tableAttrs) {
NSMutableArray* tempArray = [NSMutableArray new];
[tempArray addObject:NSAccessibilityRowCountAttribute];
[tempArray addObject:NSAccessibilityColumnCountAttribute];
[tempArray addObject:NSAccessibilityRowsAttribute];
tableAttrs = [[NSArray alloc] initWithArray:tempArray];
[tempArray release];
}
return [additionalAttributes arrayByAddingObjectsFromArray:tableAttrs];
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
}
- (id)accessibilityAttributeValue:(NSString*)attribute
{
if (AccessibleWrap* accWrap = [self getGeckoAccessible]) {
TableAccessible* table = accWrap->AsTable();
if ([attribute isEqualToString:NSAccessibilityRowCountAttribute])
return @(table->RowCount());
if ([attribute isEqualToString:NSAccessibilityColumnCountAttribute])
return @(table->ColCount());
if ([attribute isEqualToString:NSAccessibilityRowsAttribute]) {
// Create a new array with the list of table rows.
NSMutableArray* nativeArray = [[NSMutableArray alloc] init];
uint32_t totalCount = accWrap->ChildCount();
for (uint32_t i = 0; i < totalCount; i++) {
if (accWrap->GetChildAt(i)->IsTableRow()) {
mozAccessible* curNative =
GetNativeFromGeckoAccessible(accWrap->GetChildAt(i));
if (curNative)
[nativeArray addObject:GetObjectOrRepresentedView(curNative)];
}
}
return nativeArray;
}
} else if (ProxyAccessible* proxy = [self getProxyAccessible]) {
if ([attribute isEqualToString:NSAccessibilityRowCountAttribute])
return @(proxy->TableRowCount());
if ([attribute isEqualToString:NSAccessibilityColumnCountAttribute])
return @(proxy->TableColumnCount());
if ([attribute isEqualToString:NSAccessibilityRowsAttribute]) {
// Create a new array with the list of table rows.
NSMutableArray* nativeArray = [[NSMutableArray alloc] init];
uint32_t totalCount = proxy->ChildrenCount();
for (uint32_t i = 0; i < totalCount; i++) {
if (proxy->ChildAt(i)->IsTableRow()) {
mozAccessible* curNative =
GetNativeFromProxy(proxy->ChildAt(i));
if (curNative)
[nativeArray addObject:GetObjectOrRepresentedView(curNative)];
}
}
return nativeArray;
}
}
return [super accessibilityAttributeValue:attribute];
}
@end
@implementation mozTableRowAccessible
- (NSArray*)additionalAccessibilityAttributeNames
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
NSArray* additionalAttributes = [super additionalAccessibilityAttributeNames];
if ([self isLayoutTablePart]) {
return additionalAttributes;
}
static NSArray* tableRowAttrs = nil;
if (!tableRowAttrs) {
NSMutableArray* tempArray = [NSMutableArray new];
[tempArray addObject:NSAccessibilityIndexAttribute];
tableRowAttrs = [[NSArray alloc] initWithArray:tempArray];
[tempArray release];
}
return [additionalAttributes arrayByAddingObjectsFromArray:tableRowAttrs];
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
}
- (id)accessibilityAttributeValue:(NSString*)attribute
{
if (AccessibleWrap* accWrap = [self getGeckoAccessible]) {
if ([attribute isEqualToString:NSAccessibilityIndexAttribute]) {
// Count the number of rows before that one to obtain the row index.
uint32_t index = 0;
Accessible* parent = accWrap->Parent();
if (parent) {
for (int32_t i = accWrap->IndexInParent() - 1; i >= 0; i--) {
if (parent->GetChildAt(i)->IsTableRow()) {
index++;
}
}
}
return [NSNumber numberWithUnsignedInteger:index];
}
} else if (ProxyAccessible* proxy = [self getProxyAccessible]) {
if ([attribute isEqualToString:NSAccessibilityIndexAttribute]) {
// Count the number of rows before that one to obtain the row index.
uint32_t index = 0;
ProxyAccessible* parent = proxy->Parent();
if (parent) {
for (int32_t i = proxy->IndexInParent() - 1; i >= 0; i--) {
if (parent->ChildAt(i)->IsTableRow()) {
index++;
}
}
}
return [NSNumber numberWithUnsignedInteger:index];
}
}
return [super accessibilityAttributeValue:attribute];
}
@end
@implementation mozTableCellAccessible
- (NSArray*)additionalAccessibilityAttributeNames
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
NSArray* additionalAttributes = [super additionalAccessibilityAttributeNames];
if ([self isLayoutTablePart]) {
return additionalAttributes;
}
static NSArray* tableCellAttrs = nil;
if (!tableCellAttrs) {
NSMutableArray* tempArray = [NSMutableArray new];
[tempArray addObject:NSAccessibilityRowIndexRangeAttribute];
[tempArray addObject:NSAccessibilityColumnIndexRangeAttribute];
[tempArray addObject:NSAccessibilityRowHeaderUIElementsAttribute];
[tempArray addObject:NSAccessibilityColumnHeaderUIElementsAttribute];
tableCellAttrs = [[NSArray alloc] initWithArray:tempArray];
[tempArray release];
}
return [additionalAttributes arrayByAddingObjectsFromArray:tableCellAttrs];
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
}
- (id)accessibilityAttributeValue:(NSString*)attribute
{
if (AccessibleWrap* accWrap = [self getGeckoAccessible]) {
TableCellAccessible* cell = accWrap->AsTableCell();
if ([attribute isEqualToString:NSAccessibilityRowIndexRangeAttribute])
return [NSValue valueWithRange:NSMakeRange(cell->RowIdx(),
cell->RowExtent())];
if ([attribute isEqualToString:NSAccessibilityColumnIndexRangeAttribute])
return [NSValue valueWithRange:NSMakeRange(cell->ColIdx(),
cell->ColExtent())];
if ([attribute isEqualToString:NSAccessibilityRowHeaderUIElementsAttribute]) {
AutoTArray<Accessible*, 10> headerCells;
cell->RowHeaderCells(&headerCells);
return ConvertToNSArray(headerCells);
}
if ([attribute isEqualToString:NSAccessibilityColumnHeaderUIElementsAttribute]) {
AutoTArray<Accessible*, 10> headerCells;
cell->ColHeaderCells(&headerCells);
return ConvertToNSArray(headerCells);
}
} else if (ProxyAccessible* proxy = [self getProxyAccessible]) {
if ([attribute isEqualToString:NSAccessibilityRowIndexRangeAttribute])
return [NSValue valueWithRange:NSMakeRange(proxy->RowIdx(),
proxy->RowExtent())];
if ([attribute isEqualToString:NSAccessibilityColumnIndexRangeAttribute])
return [NSValue valueWithRange:NSMakeRange(proxy->ColIdx(),
proxy->ColExtent())];
if ([attribute isEqualToString:NSAccessibilityRowHeaderUIElementsAttribute]) {
nsTArray<ProxyAccessible*> headerCells;
proxy->RowHeaderCells(&headerCells);
return ConvertToNSArray(headerCells);
}
if ([attribute isEqualToString:NSAccessibilityColumnHeaderUIElementsAttribute]) {
nsTArray<ProxyAccessible*> headerCells;
proxy->ColHeaderCells(&headerCells);
return ConvertToNSArray(headerCells);
}
}
return [super accessibilityAttributeValue:attribute];
}
@end
@@ -1,9 +1,17 @@
/* -*- Mode: IDL; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
[Pref="dom.archivereader.enabled"]
interface ArchiveRequest : DOMRequest {
readonly attribute ArchiveReader reader;
};
#import "mozAccessible.h"
#import "HyperTextAccessible.h"
@interface mozTextAccessible : mozAccessible
{
}
@end
@interface mozTextLeafAccessible : mozAccessible
{
}
@end
+627
View File
@@ -0,0 +1,627 @@
/* -*- Mode: Objective-C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "Accessible-inl.h"
#include "HyperTextAccessible-inl.h"
#include "TextLeafAccessible.h"
#include "nsCocoaUtils.h"
#include "nsObjCExceptions.h"
#import "mozTextAccessible.h"
using namespace mozilla;
using namespace mozilla::a11y;
inline bool
ToNSRange(id aValue, NSRange* aRange)
{
NS_PRECONDITION(aRange, "aRange is nil");
if ([aValue isKindOfClass:[NSValue class]] &&
strcmp([(NSValue*)aValue objCType], @encode(NSRange)) == 0) {
*aRange = [aValue rangeValue];
return true;
}
return false;
}
inline NSString*
ToNSString(id aValue)
{
if ([aValue isKindOfClass:[NSString class]]) {
return aValue;
}
return nil;
}
@interface mozTextAccessible ()
- (NSString*)subrole;
- (NSString*)selectedText;
- (NSValue*)selectedTextRange;
- (NSValue*)visibleCharacterRange;
- (long)textLength;
- (BOOL)isReadOnly;
- (NSNumber*)caretLineNumber;
- (void)setText:(NSString*)newText;
- (NSString*)text;
- (NSString*)stringFromRange:(NSRange*)range;
@end
@implementation mozTextAccessible
- (BOOL)accessibilityIsIgnored
{
return ![self getGeckoAccessible] && ![self getProxyAccessible];
}
- (NSArray*)accessibilityAttributeNames
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
static NSMutableArray* supportedAttributes = nil;
if (!supportedAttributes) {
// text-specific attributes to supplement the standard one
supportedAttributes = [[NSMutableArray alloc] initWithObjects:
NSAccessibilitySelectedTextAttribute, // required
NSAccessibilitySelectedTextRangeAttribute, // required
NSAccessibilityNumberOfCharactersAttribute, // required
NSAccessibilityVisibleCharacterRangeAttribute, // required
NSAccessibilityInsertionPointLineNumberAttribute,
@"AXRequired",
@"AXInvalid",
nil
];
[supportedAttributes addObjectsFromArray:[super accessibilityAttributeNames]];
}
return supportedAttributes;
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
}
- (id)accessibilityAttributeValue:(NSString*)attribute
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
if ([attribute isEqualToString:NSAccessibilityNumberOfCharactersAttribute])
return [NSNumber numberWithInt:[self textLength]];
if ([attribute isEqualToString:NSAccessibilityInsertionPointLineNumberAttribute])
return [self caretLineNumber];
if ([attribute isEqualToString:NSAccessibilitySelectedTextRangeAttribute])
return [self selectedTextRange];
if ([attribute isEqualToString:NSAccessibilitySelectedTextAttribute])
return [self selectedText];
if ([attribute isEqualToString:NSAccessibilityTitleAttribute])
return @"";
if ([attribute isEqualToString:NSAccessibilityValueAttribute]) {
// Apple's SpeechSynthesisServer expects AXValue to return an AXStaticText
// object's AXSelectedText attribute. See bug 674612 for details.
// Also if there is no selected text, we return the full text.
// See bug 369710 for details.
if ([[self role] isEqualToString:NSAccessibilityStaticTextRole]) {
NSString* selectedText = [self selectedText];
return (selectedText && [selectedText length]) ? selectedText : [self text];
}
return [self text];
}
if (AccessibleWrap* accWrap = [self getGeckoAccessible]) {
if ([attribute isEqualToString:@"AXRequired"]) {
return [NSNumber numberWithBool:!!(accWrap->State() & states::REQUIRED)];
}
if ([attribute isEqualToString:@"AXInvalid"]) {
return [NSNumber numberWithBool:!!(accWrap->State() & states::INVALID)];
}
} else if (ProxyAccessible* proxy = [self getProxyAccessible]) {
if ([attribute isEqualToString:@"AXRequired"]) {
return [NSNumber numberWithBool:!!(proxy->State() & states::REQUIRED)];
}
if ([attribute isEqualToString:@"AXInvalid"]) {
return [NSNumber numberWithBool:!!(proxy->State() & states::INVALID)];
}
}
if ([attribute isEqualToString:NSAccessibilityVisibleCharacterRangeAttribute])
return [self visibleCharacterRange];
// let mozAccessible handle all other attributes
return [super accessibilityAttributeValue:attribute];
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
}
- (NSArray*)accessibilityParameterizedAttributeNames
{
static NSArray* supportedParametrizedAttributes = nil;
// text specific parametrized attributes
if (!supportedParametrizedAttributes) {
supportedParametrizedAttributes = [[NSArray alloc] initWithObjects:
NSAccessibilityStringForRangeParameterizedAttribute,
NSAccessibilityLineForIndexParameterizedAttribute,
NSAccessibilityRangeForLineParameterizedAttribute,
NSAccessibilityAttributedStringForRangeParameterizedAttribute,
NSAccessibilityBoundsForRangeParameterizedAttribute,
#if DEBUG
NSAccessibilityRangeForPositionParameterizedAttribute,
NSAccessibilityRangeForIndexParameterizedAttribute,
NSAccessibilityRTFForRangeParameterizedAttribute,
NSAccessibilityStyleRangeForIndexParameterizedAttribute,
#endif
nil
];
}
return supportedParametrizedAttributes;
}
- (id)accessibilityAttributeValue:(NSString*)attribute forParameter:(id)parameter
{
AccessibleWrap* accWrap = [self getGeckoAccessible];
ProxyAccessible* proxy = [self getProxyAccessible];
HyperTextAccessible* textAcc = accWrap? accWrap->AsHyperText() : nullptr;
if (!textAcc && !proxy)
return nil;
if ([attribute isEqualToString:NSAccessibilityStringForRangeParameterizedAttribute]) {
NSRange range;
if (!ToNSRange(parameter, &range)) {
#if DEBUG
NSLog(@"%@: range not set", attribute);
#endif
return @"";
}
return [self stringFromRange:&range];
}
if ([attribute isEqualToString:NSAccessibilityRangeForLineParameterizedAttribute]) {
// XXX: actually get the integer value for the line #
return [NSValue valueWithRange:NSMakeRange(0, [self textLength])];
}
if ([attribute isEqualToString:NSAccessibilityAttributedStringForRangeParameterizedAttribute]) {
NSRange range;
if (!ToNSRange(parameter, &range)) {
#if DEBUG
NSLog(@"%@: range not set", attribute);
#endif
return @"";
}
return [[[NSAttributedString alloc] initWithString:[self stringFromRange:&range]] autorelease];
}
if ([attribute isEqualToString:NSAccessibilityLineForIndexParameterizedAttribute]) {
// XXX: actually return the line #
return [NSNumber numberWithInt:0];
}
if ([attribute isEqualToString:NSAccessibilityBoundsForRangeParameterizedAttribute]) {
NSRange range;
if (!ToNSRange(parameter, &range)) {
#if DEBUG
NSLog(@"%@:no range", attribute);
#endif
return nil;
}
int32_t start = range.location;
int32_t end = start + range.length;
DesktopIntRect bounds;
if (textAcc) {
bounds =
DesktopIntRect::FromUnknownRect(textAcc->TextBounds(start, end));
} else if (proxy) {
bounds =
DesktopIntRect::FromUnknownRect(proxy->TextBounds(start, end));
}
return [NSValue valueWithRect:nsCocoaUtils::GeckoRectToCocoaRect(bounds)];
}
#if DEBUG
NSLog(@"unhandled attribute:%@ forParameter:%@", attribute, parameter);
#endif
return nil;
}
- (BOOL)accessibilityIsAttributeSettable:(NSString*)attribute
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_RETURN;
if ([attribute isEqualToString:NSAccessibilityValueAttribute])
return ![self isReadOnly];
if ([attribute isEqualToString:NSAccessibilitySelectedTextAttribute] ||
[attribute isEqualToString:NSAccessibilitySelectedTextRangeAttribute] ||
[attribute isEqualToString:NSAccessibilityVisibleCharacterRangeAttribute])
return YES;
return [super accessibilityIsAttributeSettable:attribute];
NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(NO);
}
- (void)accessibilitySetValue:(id)value forAttribute:(NSString *)attribute
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
AccessibleWrap* accWrap = [self getGeckoAccessible];
ProxyAccessible* proxy = [self getProxyAccessible];
HyperTextAccessible* textAcc = accWrap? accWrap->AsHyperText() : nullptr;
if (!textAcc && !proxy)
return;
if ([attribute isEqualToString:NSAccessibilityValueAttribute]) {
[self setText:ToNSString(value)];
return;
}
if ([attribute isEqualToString:NSAccessibilitySelectedTextAttribute]) {
NSString* stringValue = ToNSString(value);
if (!stringValue)
return;
int32_t start = 0, end = 0;
nsString text;
if (textAcc) {
textAcc->SelectionBoundsAt(0, &start, &end);
textAcc->DeleteText(start, end - start);
nsCocoaUtils::GetStringForNSString(stringValue, text);
textAcc->InsertText(text, start);
} else if (proxy) {
nsString data;
proxy->SelectionBoundsAt(0, data, &start, &end);
proxy->DeleteText(start, end - start);
nsCocoaUtils::GetStringForNSString(stringValue, text);
proxy->InsertText(text, start);
}
}
if ([attribute isEqualToString:NSAccessibilitySelectedTextRangeAttribute]) {
NSRange range;
if (!ToNSRange(value, &range))
return;
if (textAcc) {
textAcc->SetSelectionBoundsAt(0, range.location,
range.location + range.length);
} else if (proxy) {
proxy->SetSelectionBoundsAt(0, range.location,
range.location + range.length);
}
return;
}
if ([attribute isEqualToString:NSAccessibilityVisibleCharacterRangeAttribute]) {
NSRange range;
if (!ToNSRange(value, &range))
return;
if (textAcc) {
textAcc->ScrollSubstringTo(range.location, range.location + range.length,
nsIAccessibleScrollType::SCROLL_TYPE_TOP_EDGE);
} else if (proxy) {
proxy->ScrollSubstringTo(range.location, range.location + range.length,
nsIAccessibleScrollType::SCROLL_TYPE_TOP_EDGE);
}
return;
}
[super accessibilitySetValue:value forAttribute:attribute];
NS_OBJC_END_TRY_ABORT_BLOCK;
}
- (NSString*)subrole
{
if(mRole == roles::PASSWORD_TEXT)
return NSAccessibilitySecureTextFieldSubrole;
return nil;
}
#pragma mark -
- (BOOL)isReadOnly
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_RETURN;
if ([[self role] isEqualToString:NSAccessibilityStaticTextRole])
return YES;
AccessibleWrap* accWrap = [self getGeckoAccessible];
HyperTextAccessible* textAcc = accWrap? accWrap->AsHyperText() : nullptr;
if (textAcc)
return (accWrap->State() & states::READONLY) == 0;
if (ProxyAccessible* proxy = [self getProxyAccessible])
return (proxy->State() & states::READONLY) == 0;
return NO;
NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(NO);
}
- (NSNumber*)caretLineNumber
{
AccessibleWrap* accWrap = [self getGeckoAccessible];
HyperTextAccessible* textAcc = accWrap? accWrap->AsHyperText() : nullptr;
int32_t lineNumber = -1;
if (textAcc) {
lineNumber = textAcc->CaretLineNumber() - 1;
} else if (ProxyAccessible* proxy = [self getProxyAccessible]) {
lineNumber = proxy->CaretLineNumber() - 1;
}
return (lineNumber >= 0) ? [NSNumber numberWithInt:lineNumber] : nil;
}
- (void)setText:(NSString*)aNewString
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
AccessibleWrap* accWrap = [self getGeckoAccessible];
HyperTextAccessible* textAcc = accWrap? accWrap->AsHyperText() : nullptr;
nsString text;
nsCocoaUtils::GetStringForNSString(aNewString, text);
if (textAcc) {
textAcc->ReplaceText(text);
} else if (ProxyAccessible* proxy = [self getProxyAccessible]) {
proxy->ReplaceText(text);
}
NS_OBJC_END_TRY_ABORT_BLOCK;
}
- (NSString*)text
{
AccessibleWrap* accWrap = [self getGeckoAccessible];
ProxyAccessible* proxy = [self getProxyAccessible];
HyperTextAccessible* textAcc = accWrap? accWrap->AsHyperText() : nullptr;
if (!textAcc && !proxy)
return nil;
// A password text field returns an empty value
if (mRole == roles::PASSWORD_TEXT)
return @"";
nsAutoString text;
if (textAcc) {
textAcc->TextSubstring(0, nsIAccessibleText::TEXT_OFFSET_END_OF_TEXT, text);
} else if (proxy) {
proxy->TextSubstring(0, nsIAccessibleText::TEXT_OFFSET_END_OF_TEXT, text);
}
return nsCocoaUtils::ToNSString(text);
}
- (long)textLength
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_RETURN;
AccessibleWrap* accWrap = [self getGeckoAccessible];
ProxyAccessible* proxy = [self getProxyAccessible];
HyperTextAccessible* textAcc = accWrap? accWrap->AsHyperText() : nullptr;
if (!textAcc && !proxy)
return 0;
return textAcc ? textAcc->CharacterCount() : proxy->CharacterCount();
NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(0);
}
- (long)selectedTextLength
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_RETURN;
AccessibleWrap* accWrap = [self getGeckoAccessible];
ProxyAccessible* proxy = [self getProxyAccessible];
HyperTextAccessible* textAcc = accWrap? accWrap->AsHyperText() : nullptr;
if (!textAcc && !proxy)
return 0;
int32_t start = 0, end = 0;
if (textAcc) {
textAcc->SelectionBoundsAt(0, &start, &end);
} else if (proxy) {
nsString data;
proxy->SelectionBoundsAt(0, data, &start, &end);
}
return (end - start);
NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(0);
}
- (NSString*)selectedText
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
AccessibleWrap* accWrap = [self getGeckoAccessible];
ProxyAccessible* proxy = [self getProxyAccessible];
HyperTextAccessible* textAcc = accWrap? accWrap->AsHyperText() : nullptr;
if (!textAcc && !proxy)
return nil;
int32_t start = 0, end = 0;
nsAutoString selText;
if (textAcc) {
textAcc->SelectionBoundsAt(0, &start, &end);
if (start != end) {
textAcc->TextSubstring(start, end, selText);
}
} else if (proxy) {
proxy->SelectionBoundsAt(0, selText, &start, &end);
}
return nsCocoaUtils::ToNSString(selText);
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
}
- (NSValue*)selectedTextRange
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
AccessibleWrap* accWrap = [self getGeckoAccessible];
ProxyAccessible* proxy = [self getProxyAccessible];
HyperTextAccessible* textAcc = accWrap? accWrap->AsHyperText() : nullptr;
int32_t start = 0;
int32_t end = 0;
int32_t count = 0;
if (textAcc) {
count = textAcc->SelectionCount();
if (count) {
textAcc->SelectionBoundsAt(0, &start, &end);
return [NSValue valueWithRange:NSMakeRange(start, end - start)];
}
start = textAcc->CaretOffset();
return [NSValue valueWithRange:NSMakeRange(start != -1 ? start : 0, 0)];
}
if (proxy) {
count = proxy->SelectionCount();
if (count) {
nsString data;
proxy->SelectionBoundsAt(0, data, &start, &end);
return [NSValue valueWithRange:NSMakeRange(start, end - start)];
}
start = proxy->CaretOffset();
return [NSValue valueWithRange:NSMakeRange(start != -1 ? start : 0, 0)];
}
return [NSValue valueWithRange:NSMakeRange(0, 0)];
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
}
- (NSValue*)visibleCharacterRange
{
// XXX this won't work with Textarea and such as we actually don't give
// the visible character range.
AccessibleWrap* accWrap = [self getGeckoAccessible];
ProxyAccessible* proxy = [self getProxyAccessible];
HyperTextAccessible* textAcc = accWrap? accWrap->AsHyperText() : nullptr;
if (!textAcc && !proxy)
return 0;
return [NSValue valueWithRange:
NSMakeRange(0, textAcc ?
textAcc->CharacterCount() : proxy->CharacterCount())];
}
- (void)valueDidChange
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
NSAccessibilityPostNotification(GetObjectOrRepresentedView(self),
NSAccessibilityValueChangedNotification);
NS_OBJC_END_TRY_ABORT_BLOCK;
}
- (void)selectedTextDidChange
{
NSAccessibilityPostNotification(GetObjectOrRepresentedView(self),
NSAccessibilitySelectedTextChangedNotification);
}
- (NSString*)stringFromRange:(NSRange*)range
{
NS_PRECONDITION(range, "no range");
AccessibleWrap* accWrap = [self getGeckoAccessible];
ProxyAccessible* proxy = [self getProxyAccessible];
HyperTextAccessible* textAcc = accWrap? accWrap->AsHyperText() : nullptr;
if (!textAcc && !proxy)
return nil;
nsAutoString text;
if (textAcc) {
textAcc->TextSubstring(range->location,
range->location + range->length, text);
} else if (proxy) {
proxy->TextSubstring(range->location,
range->location + range->length, text);
}
return nsCocoaUtils::ToNSString(text);
}
@end
@implementation mozTextLeafAccessible
- (NSArray*)accessibilityAttributeNames
{
static NSMutableArray* supportedAttributes = nil;
if (!supportedAttributes) {
supportedAttributes = [[super accessibilityAttributeNames] mutableCopy];
[supportedAttributes removeObject:NSAccessibilityChildrenAttribute];
}
return supportedAttributes;
}
- (id)accessibilityAttributeValue:(NSString*)attribute
{
if ([attribute isEqualToString:NSAccessibilityTitleAttribute])
return @"";
if ([attribute isEqualToString:NSAccessibilityValueAttribute])
return [self text];
return [super accessibilityAttributeValue:attribute];
}
- (NSString*)text
{
if (AccessibleWrap* accWrap = [self getGeckoAccessible]) {
return nsCocoaUtils::ToNSString(accWrap->AsTextLeaf()->Text());
}
if (ProxyAccessible* proxy = [self getProxyAccessible]) {
nsString text;
proxy->Text(&text);
return nsCocoaUtils::ToNSString(text);
}
return nil;
}
- (long)textLength
{
if (AccessibleWrap* accWrap = [self getGeckoAccessible]) {
return accWrap->AsTextLeaf()->Text().Length();
}
if (ProxyAccessible* proxy = [self getProxyAccessible]) {
nsString text;
proxy->Text(&text);
return text.Length();
}
return 0;
}
@end
+4 -4
View File
@@ -9,6 +9,8 @@ if 'gtk' in toolkit:
DIRS += ['atk']
elif toolkit == 'windows':
DIRS += ['windows']
elif toolkit == 'cocoa':
DIRS += ['mac']
else:
DIRS += ['other']
@@ -19,12 +21,10 @@ DIRS += [ 'aom',
'interfaces',
'ipc',
'jsat',
'xpcom'
'xpcom',
'xul'
]
if CONFIG['MOZ_XUL']:
DIRS += ['xul']
TEST_DIRS += ['tests/mochitest']
BROWSER_CHROME_MANIFESTS += [
-13
View File
@@ -35,19 +35,6 @@ a11y::PlatformInit()
nsWinUtils::MaybeStartWindowEmulation();
ia2AccessibleText::InitTextChangeData();
if (BrowserTabsRemoteAutostart()) {
mscom::InterceptorLog::Init();
UniquePtr<RegisteredProxy> regProxy(
mscom::RegisterProxy(L"ia2marshal.dll"));
gRegProxy = regProxy.release();
UniquePtr<RegisteredProxy> regAccTlb(
mscom::RegisterTypelib(L"oleacc.dll",
RegistrationFlags::eUseSystemDirectory));
gRegAccTlb = regAccTlb.release();
UniquePtr<RegisteredProxy> regMiscTlb(
mscom::RegisterTypelib(L"Accessible.tlb"));
gRegMiscTlb = regMiscTlb.release();
}
}
void
+3 -7
View File
@@ -33,15 +33,11 @@ SOURCES += [
'RootAccessibleWrap.cpp',
'ServiceProvider.cpp',
'TextLeafAccessibleWrap.cpp',
'XULListboxAccessibleWrap.cpp',
'XULMenuAccessibleWrap.cpp',
'XULTreeGridAccessibleWrap.cpp',
]
if CONFIG['MOZ_XUL']:
SOURCES += [
'XULListboxAccessibleWrap.cpp',
'XULMenuAccessibleWrap.cpp',
'XULTreeGridAccessibleWrap.cpp',
]
LOCAL_INCLUDES += [
'/accessible/base',
'/accessible/generic',
+4
View File
@@ -42,6 +42,10 @@ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
LOCAL_INCLUDES += [
'/accessible/windows/msaa',
]
elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
LOCAL_INCLUDES += [
'/accessible/mac',
]
else:
LOCAL_INCLUDES += [
'/accessible/other',
+4
View File
@@ -37,6 +37,10 @@ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
'/accessible/windows/ia2',
'/accessible/windows/msaa',
]
elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
LOCAL_INCLUDES += [
'/accessible/mac',
]
else:
LOCAL_INCLUDES += [
'/accessible/other',
@@ -1,54 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.gecko.annotationProcessors;
/**
* Object holding annotation data. Used by GeneratableElementIterator.
*/
public class AnnotationInfo {
public enum ExceptionMode {
ABORT,
NSRESULT,
IGNORE;
String nativeValue() {
return "mozilla::jni::ExceptionMode::" + name();
}
}
public enum CallingThread {
GECKO,
UI,
ANY;
String nativeValue() {
return "mozilla::jni::CallingThread::" + name();
}
}
public enum DispatchTarget {
GECKO,
PROXY,
CURRENT;
String nativeValue() {
return "mozilla::jni::DispatchTarget::" + name();
}
}
public final String wrapperName;
public final ExceptionMode exceptionMode;
public final CallingThread callingThread;
public final DispatchTarget dispatchTarget;
public AnnotationInfo(String wrapperName, ExceptionMode exceptionMode,
CallingThread callingThread, DispatchTarget dispatchTarget) {
this.wrapperName = wrapperName;
this.exceptionMode = exceptionMode;
this.callingThread = callingThread;
this.dispatchTarget = dispatchTarget;
}
}
@@ -1,175 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.gecko.annotationProcessors;
import org.mozilla.gecko.annotationProcessors.classloader.AnnotatableEntity;
import org.mozilla.gecko.annotationProcessors.classloader.ClassWithOptions;
import org.mozilla.gecko.annotationProcessors.classloader.IterableJarLoadingURLClassLoader;
import org.mozilla.gecko.annotationProcessors.utils.GeneratableElementIterator;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Arrays;
import java.util.Iterator;
public class AnnotationProcessor {
public static final String GENERATED_COMMENT =
"// GENERATED CODE\n" +
"// Generated by the Java program at /build/annotationProcessors at compile time\n" +
"// from annotations on Java methods. To update, change the annotations on the\n" +
"// corresponding Java methods and rerun the build. Manually updating this file\n" +
"// will cause your build to fail.\n" +
"\n";
private static final StringBuilder headerFile = new StringBuilder(GENERATED_COMMENT);
private static final StringBuilder implementationFile = new StringBuilder(GENERATED_COMMENT);
private static final StringBuilder nativesFile = new StringBuilder(GENERATED_COMMENT);
public static void main(String[] args) {
// We expect a list of jars on the commandline. If missing, whinge about it.
if (args.length <= 2) {
System.err.println("Usage: java AnnotationProcessor outprefix jarfiles ...");
System.exit(1);
}
final String OUTPUT_PREFIX = args[0];
final String SOURCE_FILE = OUTPUT_PREFIX + "JNIWrappers.cpp";
final String HEADER_FILE = OUTPUT_PREFIX + "JNIWrappers.h";
final String NATIVES_FILE = OUTPUT_PREFIX + "JNINatives.h";
System.out.println("Processing annotations...");
// We want to produce the same output as last time as often as possible. Ordering of
// generated statements, therefore, needs to be consistent.
final String[] jars = Arrays.copyOfRange(args, 1, args.length);
Arrays.sort(jars);
// Start the clock!
long s = System.currentTimeMillis();
// Get an iterator over the classes in the jar files given...
Iterator<ClassWithOptions> jarClassIterator = IterableJarLoadingURLClassLoader.getIteratorOverJars(jars);
headerFile.append(
"#ifndef " + getHeaderGuardName(HEADER_FILE) + "\n" +
"#define " + getHeaderGuardName(HEADER_FILE) + "\n" +
"\n" +
"#include \"mozilla/jni/Refs.h\"\n" +
"\n" +
"namespace mozilla {\n" +
"namespace java {\n" +
"\n");
implementationFile.append(
"#include \"" + HEADER_FILE + "\"\n" +
"#include \"mozilla/jni/Accessors.h\"\n" +
"\n" +
"namespace mozilla {\n" +
"namespace java {\n" +
"\n");
nativesFile.append(
"#ifndef " + getHeaderGuardName(NATIVES_FILE) + "\n" +
"#define " + getHeaderGuardName(NATIVES_FILE) + "\n" +
"\n" +
"#include \"" + HEADER_FILE + "\"\n" +
"#include \"mozilla/jni/Natives.h\"\n" +
"\n" +
"namespace mozilla {\n" +
"namespace java {\n" +
"\n");
while (jarClassIterator.hasNext()) {
generateClass(jarClassIterator.next());
}
implementationFile.append(
"} /* java */\n" +
"} /* mozilla */\n");
headerFile.append(
"} /* java */\n" +
"} /* mozilla */\n" +
"#endif // " + getHeaderGuardName(HEADER_FILE) + "\n");
nativesFile.append(
"} /* java */\n" +
"} /* mozilla */\n" +
"#endif // " + getHeaderGuardName(NATIVES_FILE) + "\n");
writeOutputFile(SOURCE_FILE, implementationFile);
writeOutputFile(HEADER_FILE, headerFile);
writeOutputFile(NATIVES_FILE, nativesFile);
long e = System.currentTimeMillis();
System.out.println("Annotation processing complete in " + (e - s) + "ms");
}
private static void generateClass(final ClassWithOptions annotatedClass) {
// Get an iterator over the appropriately generated methods of this class
final GeneratableElementIterator methodIterator
= new GeneratableElementIterator(annotatedClass);
final ClassWithOptions[] innerClasses = methodIterator.getInnerClasses();
if (!methodIterator.hasNext() && innerClasses.length == 0) {
return;
}
final CodeGenerator generatorInstance = new CodeGenerator(annotatedClass);
generatorInstance.generateClasses(innerClasses);
// Iterate all annotated members in this class..
while (methodIterator.hasNext()) {
AnnotatableEntity aElementTuple = methodIterator.next();
switch (aElementTuple.mEntityType) {
case METHOD:
generatorInstance.generateMethod(aElementTuple);
break;
case NATIVE:
generatorInstance.generateNative(aElementTuple);
break;
case FIELD:
generatorInstance.generateField(aElementTuple);
break;
case CONSTRUCTOR:
generatorInstance.generateConstructor(aElementTuple);
break;
}
}
headerFile.append(generatorInstance.getHeaderFileContents());
implementationFile.append(generatorInstance.getWrapperFileContents());
nativesFile.append(generatorInstance.getNativesFileContents());
for (ClassWithOptions innerClass : innerClasses) {
generateClass(innerClass);
}
}
private static String getHeaderGuardName(final String name) {
return name.replaceAll("\\W", "_");
}
private static void writeOutputFile(final String name,
final StringBuilder content) {
FileOutputStream outStream = null;
try {
outStream = new FileOutputStream(name);
outStream.write(content.toString().getBytes());
} catch (IOException e) {
System.err.println("Unable to write " + name + ". Perhaps a permissions issue?");
e.printStackTrace(System.err);
} finally {
if (outStream != null) {
try {
outStream.close();
} catch (IOException e) {
System.err.println("Unable to close outStream due to "+e);
e.printStackTrace(System.err);
}
}
}
}
}
@@ -1,627 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.gecko.annotationProcessors;
import org.mozilla.gecko.annotationProcessors.classloader.AnnotatableEntity;
import org.mozilla.gecko.annotationProcessors.classloader.ClassWithOptions;
import org.mozilla.gecko.annotationProcessors.utils.Utils;
import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.HashSet;
public class CodeGenerator {
private static final Class<?>[] EMPTY_CLASS_ARRAY = new Class<?>[0];
// Buffers holding the strings to ultimately be written to the output files.
private final StringBuilder cpp = new StringBuilder();
private final StringBuilder header = new StringBuilder();
private final StringBuilder natives = new StringBuilder();
private final StringBuilder nativesInits = new StringBuilder();
private final Class<?> cls;
private final String clsName;
private AnnotationInfo.CallingThread callingThread = null;
private int numNativesInits;
private final HashSet<String> takenMethodNames = new HashSet<String>();
public CodeGenerator(ClassWithOptions annotatedClass) {
this.cls = annotatedClass.wrappedClass;
this.clsName = annotatedClass.generatedName;
final String unqualifiedName = Utils.getUnqualifiedName(clsName);
header.append(
"class " + clsName + " : public mozilla::jni::ObjectBase<" +
unqualifiedName + ">\n" +
"{\n" +
"public:\n" +
" static const char name[];\n" +
"\n" +
" explicit " + unqualifiedName + "(const Context& ctx) : ObjectBase<" +
unqualifiedName + ">(ctx) {}\n" +
"\n");
cpp.append(
"const char " + clsName + "::name[] =\n" +
" \"" + cls.getName().replace('.', '/') + "\";\n" +
"\n");
natives.append(
"template<class Impl>\n" +
"class " + clsName + "::Natives : " +
"public mozilla::jni::NativeImpl<" + unqualifiedName + ", Impl>\n" +
"{\n" +
"public:\n");
}
private String getTraitsName(String uniqueName, boolean includeScope) {
return (includeScope ? clsName + "::" : "") + uniqueName + "_t";
}
/**
* Return the C++ type name for this class or any class within the chain
* of declaring classes, if the target class matches the given type.
*
* Return null if the given type does not match any class searched.
*/
private String getMatchingClassType(final Class<?> type) {
Class<?> cls = this.cls;
String clsName = this.clsName;
while (cls != null) {
if (type.equals(cls)) {
return clsName;
}
cls = cls.getDeclaringClass();
clsName = clsName.substring(0, Math.max(0, clsName.lastIndexOf("::")));
}
return null;
}
private String getNativeParameterType(Class<?> type, AnnotationInfo info) {
final String clsName = getMatchingClassType(type);
if (clsName != null) {
return Utils.getUnqualifiedName(clsName) + "::Param";
}
return Utils.getNativeParameterType(type, info);
}
private String getNativeReturnType(Class<?> type, AnnotationInfo info) {
final String clsName = getMatchingClassType(type);
if (clsName != null) {
return Utils.getUnqualifiedName(clsName) + "::LocalRef";
}
return Utils.getNativeReturnType(type, info);
}
private void generateMember(AnnotationInfo info, Member member,
String uniqueName, Class<?> type, Class<?>[] argTypes) {
final StringBuilder args = new StringBuilder();
for (Class<?> argType : argTypes) {
args.append("\n " + getNativeParameterType(argType, info) + ",");
}
if (args.length() > 0) {
args.setLength(args.length() - 1);
}
header.append(
" struct " + getTraitsName(uniqueName, /* includeScope */ false) + " {\n" +
" typedef " + Utils.getUnqualifiedName(clsName) + " Owner;\n" +
" typedef " + getNativeReturnType(type, info) + " ReturnType;\n" +
" typedef " + getNativeParameterType(type, info) + " SetterType;\n" +
" typedef mozilla::jni::Args<" + args + "> Args;\n" +
" static constexpr char name[] = \"" +
Utils.getMemberName(member) + "\";\n" +
" static constexpr char signature[] =\n" +
" \"" + Utils.getSignature(member) + "\";\n" +
" static const bool isStatic = " + Utils.isStatic(member) + ";\n" +
" static const mozilla::jni::ExceptionMode exceptionMode =\n" +
" " + info.exceptionMode.nativeValue() + ";\n" +
" static const mozilla::jni::CallingThread callingThread =\n" +
" " + info.callingThread.nativeValue() + ";\n" +
" static const mozilla::jni::DispatchTarget dispatchTarget =\n" +
" " + info.dispatchTarget.nativeValue() + ";\n" +
" };\n" +
"\n");
cpp.append(
"constexpr char " + getTraitsName(uniqueName, /* includeScope */ true) +
"::name[];\n" +
"constexpr char " + getTraitsName(uniqueName, /* includeScope */ true) +
"::signature[];\n" +
"\n");
if (this.callingThread == null) {
this.callingThread = info.callingThread;
} else if (this.callingThread != info.callingThread) {
// We have a mix of calling threads, so specify "any" for the whole class.
this.callingThread = AnnotationInfo.CallingThread.ANY;
}
}
private String getUniqueMethodName(String basename) {
String newName = basename;
int index = 1;
while (takenMethodNames.contains(newName)) {
newName = basename + (++index);
}
takenMethodNames.add(newName);
return newName;
}
/**
* Generate a method prototype that includes return and argument types,
* without specifiers (static, const, etc.).
*/
private String generatePrototype(String name, Class<?>[] argTypes,
Class<?> returnType, AnnotationInfo info,
boolean includeScope, boolean includeArgName,
boolean isConst) {
final StringBuilder proto = new StringBuilder();
int argIndex = 0;
proto.append("auto ");
if (includeScope) {
proto.append(clsName).append("::");
}
proto.append(name).append('(');
for (Class<?> argType : argTypes) {
proto.append(getNativeParameterType(argType, info));
if (includeArgName) {
proto.append(" a").append(argIndex++);
}
proto.append(", ");
}
if (info.exceptionMode == AnnotationInfo.ExceptionMode.NSRESULT &&
!returnType.equals(void.class)) {
proto.append(getNativeReturnType(returnType, info)).append('*');
if (includeArgName) {
proto.append(" a").append(argIndex++);
}
proto.append(", ");
}
if (proto.substring(proto.length() - 2).equals(", ")) {
proto.setLength(proto.length() - 2);
}
proto.append(')');
if (isConst) {
proto.append(" const");
}
if (info.exceptionMode == AnnotationInfo.ExceptionMode.NSRESULT) {
proto.append(" -> nsresult");
} else {
proto.append(" -> ").append(getNativeReturnType(returnType, info));
}
return proto.toString();
}
/**
* Generate a method declaration that includes the prototype with specifiers,
* but without the method body.
*/
private String generateDeclaration(String name, Class<?>[] argTypes,
Class<?> returnType, AnnotationInfo info,
boolean isStatic) {
return (isStatic ? "static " : "") +
generatePrototype(name, argTypes, returnType, info,
/* includeScope */ false, /* includeArgName */ false,
/* isConst */ !isStatic) + ';';
}
/**
* Generate a method definition that includes the prototype with specifiers,
* and with the method body.
*/
private String generateDefinition(String accessorName, String name, Class<?>[] argTypes,
Class<?> returnType, AnnotationInfo info, boolean isStatic) {
final StringBuilder def = new StringBuilder(
generatePrototype(name, argTypes, returnType, info,
/* includeScope */ true, /* includeArgName */ true,
/* isConst */ !isStatic));
def.append("\n{\n");
// Generate code to handle the return value, if needed.
// We initialize rv to NS_OK instead of NS_ERROR_* because loading NS_OK (0) uses
// fewer instructions. We are guaranteed to set rv to the correct value later.
if (info.exceptionMode == AnnotationInfo.ExceptionMode.NSRESULT &&
returnType.equals(void.class)) {
def.append(
" nsresult rv = NS_OK;\n" +
" ");
} else if (info.exceptionMode == AnnotationInfo.ExceptionMode.NSRESULT) {
// Non-void return type
final String resultArg = "a" + argTypes.length;
def.append(
" MOZ_ASSERT(" + resultArg + ");\n" +
" nsresult rv = NS_OK;\n" +
" *" + resultArg + " = ");
} else {
def.append(
" return ");
}
// Generate a call, e.g., Method<Traits>::Call(a0, a1, a2);
def.append(accessorName).append("(")
.append(Utils.getUnqualifiedName(clsName) +
(isStatic ? "::Context()" : "::mCtx"));
if (info.exceptionMode == AnnotationInfo.ExceptionMode.NSRESULT) {
def.append(", &rv");
} else {
def.append(", nullptr");
}
// Generate the call argument list.
for (int argIndex = 0; argIndex < argTypes.length; argIndex++) {
def.append(", a").append(argIndex);
}
def.append(");\n");
if (info.exceptionMode == AnnotationInfo.ExceptionMode.NSRESULT) {
def.append(" return rv;\n");
}
return def.append("}").toString();
}
/**
* Append the appropriate generated code to the buffers for the method provided.
*
* @param annotatedMethod The Java method, plus annotation data.
*/
public void generateMethod(AnnotatableEntity annotatedMethod) {
// Unpack the tuple and extract some useful fields from the Method..
final Method method = annotatedMethod.getMethod();
final AnnotationInfo info = annotatedMethod.mAnnotationInfo;
final String uniqueName = getUniqueMethodName(info.wrapperName);
final Class<?>[] argTypes = method.getParameterTypes();
final Class<?> returnType = method.getReturnType();
if (method.isSynthetic()) {
return;
}
// Sanity check
if (info.dispatchTarget != AnnotationInfo.DispatchTarget.CURRENT) {
throw new IllegalStateException("Invalid dispatch target \"" +
info.dispatchTarget.name().toLowerCase() +
"\" for non-native method " + clsName + "::" + uniqueName);
}
generateMember(info, method, uniqueName, returnType, argTypes);
final boolean isStatic = Utils.isStatic(method);
header.append(
" " + generateDeclaration(info.wrapperName, argTypes,
returnType, info, isStatic) + "\n" +
"\n");
cpp.append(
generateDefinition(
"mozilla::jni::Method<" +
getTraitsName(uniqueName, /* includeScope */ false) + ">::Call",
info.wrapperName, argTypes, returnType, info, isStatic) + "\n" +
"\n");
}
/**
* Append the appropriate generated code to the buffers for the native method provided.
*
* @param annotatedMethod The Java native method, plus annotation data.
*/
public void generateNative(AnnotatableEntity annotatedMethod) {
// Unpack the tuple and extract some useful fields from the Method..
final Method method = annotatedMethod.getMethod();
final AnnotationInfo info = annotatedMethod.mAnnotationInfo;
final String uniqueName = getUniqueMethodName(info.wrapperName);
final Class<?>[] argTypes = method.getParameterTypes();
final Class<?> returnType = method.getReturnType();
// Sanity check
if (info.exceptionMode != AnnotationInfo.ExceptionMode.ABORT &&
info.exceptionMode != AnnotationInfo.ExceptionMode.IGNORE) {
throw new IllegalStateException("Invalid exception mode \"" +
info.exceptionMode.name().toLowerCase() +
"\" for native method " + clsName + "::" + uniqueName);
}
if (info.dispatchTarget != AnnotationInfo.DispatchTarget.CURRENT &&
returnType != void.class) {
throw new IllegalStateException(
"Must return void when not dispatching to current thread for native method " +
clsName + "::" + uniqueName);
}
generateMember(info, method, uniqueName, returnType, argTypes);
final String traits = getTraitsName(uniqueName, /* includeScope */ true);
if (nativesInits.length() > 0) {
nativesInits.append(',');
}
nativesInits.append(
"\n" +
"\n" +
" mozilla::jni::MakeNativeMethod<" + traits + ">(\n" +
" mozilla::jni::NativeStub<" + traits + ", Impl>\n" +
" ::template Wrap<&Impl::" + info.wrapperName + ">)");
numNativesInits++;
}
private String getLiteral(Object val, AnnotationInfo info) {
final Class<?> type = val.getClass();
if (type.equals(char.class) || type.equals(Character.class)) {
final char c = (char) val;
if (c >= 0x20 && c < 0x7F) {
return "'" + c + '\'';
}
return "u'\\u" + Integer.toHexString(0x10000 | (int) c).substring(1) + '\'';
} else if (type.equals(CharSequence.class) || type.equals(String.class)) {
final CharSequence str = (CharSequence) val;
final StringBuilder out = new StringBuilder("u\"");
for (int i = 0; i < str.length(); i++) {
final char c = str.charAt(i);
if (c >= 0x20 && c < 0x7F) {
out.append(c);
} else {
out.append("\\u").append(Integer.toHexString(0x10000 | (int) c).substring(1));
}
}
return out.append('"').toString();
}
return String.valueOf(val);
}
public void generateField(AnnotatableEntity annotatedField) {
final Field field = annotatedField.getField();
final AnnotationInfo info = annotatedField.mAnnotationInfo;
final String uniqueName = info.wrapperName;
final Class<?> type = field.getType();
// Handles a peculiar case when dealing with enum types. We don't care about this field.
// It just gets in the way and stops our code from compiling.
if (field.isSynthetic() || field.getName().equals("$VALUES")) {
return;
}
// Sanity check
if (info.dispatchTarget != AnnotationInfo.DispatchTarget.CURRENT) {
throw new IllegalStateException("Invalid dispatch target \"" +
info.dispatchTarget.name().toLowerCase() +
"\" for field " + clsName + "::" + uniqueName);
}
final boolean isStatic = Utils.isStatic(field);
final boolean isFinal = Utils.isFinal(field);
if (isStatic && isFinal && (type.isPrimitive() || type.equals(String.class))) {
Object val = null;
try {
field.setAccessible(true);
val = field.get(null);
} catch (final IllegalAccessException e) {
}
if (val != null && type.isPrimitive()) {
// For static final primitive fields, we can use a "static const" declaration.
header.append(
" static const " + Utils.getNativeReturnType(type, info) +
' ' + info.wrapperName + " = " + getLiteral(val, info) + ";\n" +
"\n");
return;
} else if (val != null && type.equals(String.class)) {
final String nativeType = "char16_t";
header.append(
" static const " + nativeType + ' ' + info.wrapperName + "[];\n" +
"\n");
cpp.append(
"const " + nativeType + ' ' + clsName + "::" + info.wrapperName +
"[] = " + getLiteral(val, info) + ";\n" +
"\n");
return;
}
// Fall back to using accessors if we encounter an exception.
}
generateMember(info, field, uniqueName, type, EMPTY_CLASS_ARRAY);
final Class<?>[] getterArgs = EMPTY_CLASS_ARRAY;
header.append(
" " + generateDeclaration(info.wrapperName, getterArgs,
type, info, isStatic) + "\n" +
"\n");
cpp.append(
generateDefinition(
"mozilla::jni::Field<" +
getTraitsName(uniqueName, /* includeScope */ false) + ">::Get",
info.wrapperName, getterArgs, type, info, isStatic) + "\n" +
"\n");
if (isFinal) {
return;
}
final Class<?>[] setterArgs = new Class<?>[] { type };
header.append(
" " + generateDeclaration(info.wrapperName, setterArgs,
void.class, info, isStatic) + "\n" +
"\n");
cpp.append(
generateDefinition(
"mozilla::jni::Field<" +
getTraitsName(uniqueName, /* includeScope */ false) + ">::Set",
info.wrapperName, setterArgs, void.class, info, isStatic) + "\n" +
"\n");
}
public void generateConstructor(AnnotatableEntity annotatedConstructor) {
// Unpack the tuple and extract some useful fields from the Method..
final Constructor<?> method = annotatedConstructor.getConstructor();
final AnnotationInfo info = annotatedConstructor.mAnnotationInfo;
final String wrapperName = "New";
final String uniqueName = getUniqueMethodName(wrapperName);
final Class<?>[] argTypes = method.getParameterTypes();
final Class<?> returnType = cls;
if (method.isSynthetic()) {
return;
}
// Sanity check
if (info.dispatchTarget != AnnotationInfo.DispatchTarget.CURRENT) {
throw new IllegalStateException("Invalid dispatch target \"" +
info.dispatchTarget.name().toLowerCase() +
"\" for constructor " + clsName + "::" + uniqueName);
}
generateMember(info, method, uniqueName, returnType, argTypes);
header.append(
" " + generateDeclaration(wrapperName, argTypes,
returnType, info, /* isStatic */ true) + "\n" +
"\n");
cpp.append(
generateDefinition(
"mozilla::jni::Constructor<" +
getTraitsName(uniqueName, /* includeScope */ false) + ">::Call",
wrapperName, argTypes, returnType, info, /* isStatic */ true) + "\n" +
"\n");
}
public void generateMembers(Member[] members) {
for (Member m : members) {
if (!Modifier.isPublic(m.getModifiers())) {
continue;
}
String name = Utils.getMemberName(m);
name = name.substring(0, 1).toUpperCase() + name.substring(1);
// Default for SDK bindings.
final AnnotationInfo info = new AnnotationInfo(name,
AnnotationInfo.ExceptionMode.NSRESULT,
AnnotationInfo.CallingThread.ANY,
AnnotationInfo.DispatchTarget.CURRENT);
final AnnotatableEntity entity = new AnnotatableEntity(m, info);
if (m instanceof Constructor) {
generateConstructor(entity);
} else if (m instanceof Method) {
generateMethod(entity);
} else if (m instanceof Field) {
generateField(entity);
} else {
throw new IllegalArgumentException(
"expected member to be Constructor, Method, or Field");
}
}
}
public void generateClasses(final ClassWithOptions[] classes) {
if (classes.length == 0) {
return;
}
for (final ClassWithOptions cls : classes) {
// Extract "Inner" from "Outer::Inner".
header.append(
" class " + Utils.getUnqualifiedName(cls.generatedName) + ";\n");
}
header.append('\n');
}
/**
* Get the finalised bytes to go into the generated wrappers file.
*
* @return The bytes to be written to the wrappers file.
*/
public String getWrapperFileContents() {
return cpp.toString();
}
/**
* Get the finalised bytes to go into the generated header file.
*
* @return The bytes to be written to the header file.
*/
public String getHeaderFileContents() {
if (this.callingThread == null) {
this.callingThread = AnnotationInfo.CallingThread.ANY;
}
header.append(
" static const mozilla::jni::CallingThread callingThread =\n" +
" " + this.callingThread.nativeValue() + ";\n" +
"\n");
if (nativesInits.length() > 0) {
header.append(
" template<class Impl> class Natives;\n");
}
header.append(
"};\n" +
"\n");
return header.toString();
}
/**
* Get the finalised bytes to go into the generated natives header file.
*
* @return The bytes to be written to the header file.
*/
public String getNativesFileContents() {
if (nativesInits.length() == 0) {
return "";
}
natives.append(
" static const JNINativeMethod methods[" + numNativesInits + "];\n" +
"};\n" +
"\n" +
"template<class Impl>\n" +
"const JNINativeMethod " + clsName + "::Natives<Impl>::methods[] = {" + nativesInits + '\n' +
"};\n" +
"\n");
return natives.toString();
}
}
-10
View File
@@ -1,10 +0,0 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
include $(topsrcdir)/config/rules.mk
# Include Android specific java flags, instead of what's in rules.mk.
include $(topsrcdir)/config/android-common.mk
export:: annotationProcessors.jar
@@ -1,258 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.gecko.annotationProcessors;
import com.android.tools.lint.checks.ApiLookup;
import com.android.tools.lint.LintCliClient;
import org.mozilla.gecko.annotationProcessors.classloader.AnnotatableEntity;
import org.mozilla.gecko.annotationProcessors.classloader.ClassWithOptions;
import org.mozilla.gecko.annotationProcessors.classloader.IterableJarLoadingURLClassLoader;
import org.mozilla.gecko.annotationProcessors.utils.GeneratableElementIterator;
import org.mozilla.gecko.annotationProcessors.utils.Utils;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Iterator;
import java.util.Properties;
import java.util.Scanner;
import java.util.Vector;
import java.net.URL;
import java.net.URLClassLoader;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
public class SDKProcessor {
public static final String GENERATED_COMMENT =
"// GENERATED CODE\n" +
"// Generated by the Java program at /build/annotationProcessors at compile time\n" +
"// from annotations on Java methods. To update, change the annotations on the\n" +
"// corresponding Javamethods and rerun the build. Manually updating this file\n" +
"// will cause your build to fail.\n" +
"\n";
private static ApiLookup sApiLookup;
private static int sMaxSdkVersion;
public static void main(String[] args) throws Exception {
// We expect a list of jars on the commandline. If missing, whinge about it.
if (args.length < 5) {
System.err.println("Usage: java SDKProcessor sdkjar classlistfile outdir fileprefix max-sdk-version");
System.exit(1);
}
System.out.println("Processing platform bindings...");
String sdkJar = args[0];
Vector classes = getClassList(args[1]);
String outdir = args[2];
String generatedFilePrefix = args[3];
sMaxSdkVersion = Integer.parseInt(args[4]);
LintCliClient lintClient = new LintCliClient();
sApiLookup = ApiLookup.get(lintClient);
// Start the clock!
long s = System.currentTimeMillis();
// Get an iterator over the classes in the jar files given...
// Iterator<ClassWithOptions> jarClassIterator = IterableJarLoadingURLClassLoader.getIteratorOverJars(args);
StringBuilder headerFile = new StringBuilder(GENERATED_COMMENT);
headerFile.append(
"#ifndef " + generatedFilePrefix + "_h__\n" +
"#define " + generatedFilePrefix + "_h__\n" +
"\n" +
"#include \"mozilla/jni/Refs.h\"\n" +
"\n" +
"namespace mozilla {\n" +
"namespace java {\n" +
"namespace sdk {\n" +
"\n");
StringBuilder implementationFile = new StringBuilder(GENERATED_COMMENT);
implementationFile.append(
"#include \"" + generatedFilePrefix + ".h\"\n" +
"#include \"mozilla/jni/Accessors.h\"\n" +
"\n" +
"namespace mozilla {\n" +
"namespace java {\n" +
"namespace sdk {\n" +
"\n");
// Used to track the calls to the various class-specific initialisation functions.
ClassLoader loader = null;
try {
loader = URLClassLoader.newInstance(new URL[] { new URL("file://" + sdkJar) },
SDKProcessor.class.getClassLoader());
} catch (Exception e) {
throw new RuntimeException(e.toString());
}
for (Iterator<String> i = classes.iterator(); i.hasNext(); ) {
String className = i.next();
System.out.println("Looking up: " + className);
generateClass(Class.forName(className, true, loader),
implementationFile,
headerFile);
}
implementationFile.append(
"} /* sdk */\n" +
"} /* java */\n" +
"} /* mozilla */\n");
headerFile.append(
"} /* sdk */\n" +
"} /* java */\n" +
"} /* mozilla */\n" +
"#endif\n");
writeOutputFiles(outdir, generatedFilePrefix, headerFile, implementationFile);
long e = System.currentTimeMillis();
System.out.println("SDK processing complete in " + (e - s) + "ms");
}
private static int getAPIVersion(Class<?> cls, Member m) {
if (m instanceof Method || m instanceof Constructor) {
return sApiLookup.getCallVersion(
cls.getName().replace('.', '/'),
Utils.getMemberName(m),
Utils.getSignature(m));
} else if (m instanceof Field) {
return sApiLookup.getFieldVersion(
Utils.getClassDescriptor(m.getDeclaringClass()), m.getName());
} else {
throw new IllegalArgumentException("expected member to be Method, Constructor, or Field");
}
}
private static Member[] sortAndFilterMembers(Class<?> cls, Member[] members) {
Arrays.sort(members, new Comparator<Member>() {
@Override
public int compare(Member a, Member b) {
return a.getName().compareTo(b.getName());
}
});
ArrayList<Member> list = new ArrayList<>();
for (Member m : members) {
// Sometimes (e.g. Bundle) has methods that moved to/from a superclass in a later SDK
// version, so we check for both classes and see if we can find a minimum SDK version.
int version = getAPIVersion(cls, m);
final int version2 = getAPIVersion(m.getDeclaringClass(), m);
if (version2 > 0 && version2 < version) {
version = version2;
}
if (version > sMaxSdkVersion) {
System.out.println("Skipping " + m.getDeclaringClass().getName() + "." + m.getName() +
", version " + version + " > " + sMaxSdkVersion);
continue;
}
// Sometimes (e.g. KeyEvent) a field can appear in both a class and a superclass. In
// that case we want to filter out the version that appears in the superclass, or
// we'll have bindings with duplicate names.
try {
if (m instanceof Field && !m.equals(cls.getField(m.getName()))) {
// m is a field in a superclass that has been hidden by
// a field with the same name in a subclass.
System.out.println("Skipping " + m.getName() +
" from " + m.getDeclaringClass());
continue;
}
} catch (final NoSuchFieldException e) {
}
list.add(m);
}
return list.toArray(new Member[list.size()]);
}
private static void generateClass(Class<?> clazz,
StringBuilder implementationFile,
StringBuilder headerFile) {
String generatedName = clazz.getSimpleName();
CodeGenerator generator = new CodeGenerator(new ClassWithOptions(clazz, generatedName));
generator.generateMembers(sortAndFilterMembers(clazz, clazz.getConstructors()));
generator.generateMembers(sortAndFilterMembers(clazz, clazz.getMethods()));
generator.generateMembers(sortAndFilterMembers(clazz, clazz.getFields()));
headerFile.append(generator.getHeaderFileContents());
implementationFile.append(generator.getWrapperFileContents());
}
private static Vector<String> getClassList(String path) {
Scanner scanner = null;
try {
scanner = new Scanner(new FileInputStream(path));
Vector lines = new Vector();
while (scanner.hasNextLine()) {
lines.add(scanner.nextLine());
}
return lines;
} catch (Exception e) {
System.out.println(e.toString());
return null;
} finally {
if (scanner != null) {
scanner.close();
}
}
}
private static void writeOutputFiles(String aOutputDir, String aPrefix, StringBuilder aHeaderFile,
StringBuilder aImplementationFile) {
FileOutputStream implStream = null;
try {
implStream = new FileOutputStream(new File(aOutputDir, aPrefix + ".cpp"));
implStream.write(aImplementationFile.toString().getBytes());
} catch (IOException e) {
System.err.println("Unable to write " + aOutputDir + ". Perhaps a permissions issue?");
e.printStackTrace(System.err);
} finally {
if (implStream != null) {
try {
implStream.close();
} catch (IOException e) {
System.err.println("Unable to close implStream due to "+e);
e.printStackTrace(System.err);
}
}
}
FileOutputStream headerStream = null;
try {
headerStream = new FileOutputStream(new File(aOutputDir, aPrefix + ".h"));
headerStream.write(aHeaderFile.toString().getBytes());
} catch (IOException e) {
System.err.println("Unable to write " + aOutputDir + ". Perhaps a permissions issue?");
e.printStackTrace(System.err);
} finally {
if (headerStream != null) {
try {
headerStream.close();
} catch (IOException e) {
System.err.println("Unable to close headerStream due to "+e);
e.printStackTrace(System.err);
}
}
}
}
}
@@ -1,62 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.gecko.annotationProcessors.classloader;
import org.mozilla.gecko.annotationProcessors.AnnotationInfo;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
/**
* Union type to hold either a method, field, or ctor. Allows us to iterate "The generatable stuff", despite
* the fact that such things can be of either flavour.
*/
public class AnnotatableEntity {
public enum ENTITY_TYPE {METHOD, NATIVE, FIELD, CONSTRUCTOR}
private final Member mMember;
public final ENTITY_TYPE mEntityType;
public final AnnotationInfo mAnnotationInfo;
public AnnotatableEntity(Member aObject, AnnotationInfo aAnnotationInfo) {
mMember = aObject;
mAnnotationInfo = aAnnotationInfo;
if (aObject instanceof Method) {
if (Modifier.isNative(aObject.getModifiers())) {
mEntityType = ENTITY_TYPE.NATIVE;
} else {
mEntityType = ENTITY_TYPE.METHOD;
}
} else if (aObject instanceof Field) {
mEntityType = ENTITY_TYPE.FIELD;
} else {
mEntityType = ENTITY_TYPE.CONSTRUCTOR;
}
}
public Method getMethod() {
if (mEntityType != ENTITY_TYPE.METHOD && mEntityType != ENTITY_TYPE.NATIVE) {
throw new UnsupportedOperationException("Attempt to cast to unsupported member type.");
}
return (Method) mMember;
}
public Field getField() {
if (mEntityType != ENTITY_TYPE.FIELD) {
throw new UnsupportedOperationException("Attempt to cast to unsupported member type.");
}
return (Field) mMember;
}
public Constructor<?> getConstructor() {
if (mEntityType != ENTITY_TYPE.CONSTRUCTOR) {
throw new UnsupportedOperationException("Attempt to cast to unsupported member type.");
}
return (Constructor<?>) mMember;
}
}
@@ -1,15 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.gecko.annotationProcessors.classloader;
public class ClassWithOptions {
public final Class<?> wrappedClass;
public final String generatedName;
public ClassWithOptions(Class<?> someClass, String name) {
wrappedClass = someClass;
generatedName = name;
}
}
@@ -1,75 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.gecko.annotationProcessors.classloader;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
/**
* A classloader which can be initialised with a list of jar files and which can provide an iterator
* over the top level classes in the jar files it was initialised with.
* classNames is kept sorted to ensure iteration order is consistent across program invocations.
* Otherwise, we'd forever be reporting the outdatedness of the generated code as we permute its
* contents.
*/
public class IterableJarLoadingURLClassLoader extends URLClassLoader {
LinkedList<String> classNames = new LinkedList<String>();
/**
* Create an instance and return its iterator. Provides an iterator over the classes in the jar
* files provided as arguments.
* Inner classes are not supported.
*
* @param args A list of jar file names an iterator over the classes of which is desired.
* @return An iterator over the top level classes in the jar files provided, in arbitrary order.
*/
public static Iterator<ClassWithOptions> getIteratorOverJars(String[] args) {
URL[] urlArray = new URL[args.length];
LinkedList<String> aClassNames = new LinkedList<String>();
for (int i = 0; i < args.length; i++) {
try {
urlArray[i] = (new File(args[i])).toURI().toURL();
Enumeration<JarEntry> entries = new JarFile(args[i]).entries();
while (entries.hasMoreElements()) {
JarEntry e = entries.nextElement();
String fName = e.getName();
if (!fName.endsWith(".class")) {
continue;
}
final String className = fName.substring(0, fName.length() - 6).replace('/', '.');
aClassNames.add(className);
}
} catch (IOException e) {
System.err.println("Error loading jar file \"" + args[i] + '"');
e.printStackTrace(System.err);
}
}
Collections.sort(aClassNames);
return new JarClassIterator(new IterableJarLoadingURLClassLoader(urlArray, aClassNames));
}
/**
* Constructs a classloader capable of loading all classes given as URLs in urls. Used by static
* method above.
*
* @param urls URLs for all classes the new instance shall be capable of loading.
* @param aClassNames A list of names of the classes this instance shall be capable of loading.
*/
protected IterableJarLoadingURLClassLoader(URL[] urls, LinkedList<String> aClassNames) {// Array to populate with URLs for each class in the given jars.
super(urls);
classNames = aClassNames;
}
}
@@ -1,84 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.gecko.annotationProcessors.classloader;
import java.util.Iterator;
/**
* Class for iterating over an IterableJarLoadingURLClassLoader's classes.
*
* This class is not thread safe: use it only from a single thread.
*/
public class JarClassIterator implements Iterator<ClassWithOptions> {
private IterableJarLoadingURLClassLoader mTarget;
private Iterator<String> mTargetClassListIterator;
private ClassWithOptions lookAhead;
public JarClassIterator(IterableJarLoadingURLClassLoader aTarget) {
mTarget = aTarget;
mTargetClassListIterator = aTarget.classNames.iterator();
}
@Override
public boolean hasNext() {
return fillLookAheadIfPossible();
}
@Override
public ClassWithOptions next() {
if (!fillLookAheadIfPossible()) {
throw new IllegalStateException("Failed to look ahead in next()!");
}
ClassWithOptions next = lookAhead;
lookAhead = null;
return next;
}
private boolean fillLookAheadIfPossible() {
if (lookAhead != null) {
return true;
}
if (!mTargetClassListIterator.hasNext()) {
return false;
}
String className = mTargetClassListIterator.next();
try {
Class<?> ret = mTarget.loadClass(className);
// Incremental builds can leave stale classfiles in the jar. Such classfiles will cause
// an exception at this point. We can safely ignore these classes - they cannot possibly
// ever be loaded as they conflict with their parent class and will be killed by
// Proguard later on anyway.
final Class<?> enclosingClass;
try {
enclosingClass = ret.getEnclosingClass();
} catch (IncompatibleClassChangeError e) {
return fillLookAheadIfPossible();
}
if (enclosingClass != null) {
// Anonymous inner class - unsupported.
// Or named inner class, which will be processed when we process the outer class.
return fillLookAheadIfPossible();
}
lookAhead = new ClassWithOptions(ret, ret.getSimpleName());
return true;
} catch (ClassNotFoundException e) {
System.err.println("Unable to enumerate class: " + className + ". Corrupted jar file?");
e.printStackTrace();
System.exit(2);
}
return false;
}
@Override
public void remove() {
throw new UnsupportedOperationException("Removal of classes from iterator not supported.");
}
}
-23
View File
@@ -1,23 +0,0 @@
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
jar = add_java_jar('annotationProcessors')
jar.sources += [
'AnnotationInfo.java',
'AnnotationProcessor.java',
'classloader/AnnotatableEntity.java',
'classloader/ClassWithOptions.java',
'classloader/IterableJarLoadingURLClassLoader.java',
'classloader/JarClassIterator.java',
'CodeGenerator.java',
'SDKProcessor.java',
'utils/AlphabeticAnnotatableEntityComparator.java',
'utils/GeneratableElementIterator.java',
'utils/Utils.java',
]
jar.extra_jars += [
CONFIG['ANDROID_TOOLS'] + '/lib/lint.jar',
CONFIG['ANDROID_TOOLS'] + '/lib/lint-checks.jar',
]
@@ -1,81 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.gecko.annotationProcessors.utils;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.util.Comparator;
public class AlphabeticAnnotatableEntityComparator<T extends Member> implements Comparator<T> {
@Override
public int compare(T aLhs, T aRhs) {
// Constructors, Methods, Fields.
boolean lIsConstructor = aLhs instanceof Constructor;
boolean rIsConstructor = aRhs instanceof Constructor;
boolean lIsMethod = aLhs instanceof Method;
boolean rIsField = aRhs instanceof Field;
if (lIsConstructor) {
if (!rIsConstructor) {
return -1;
}
} else if (lIsMethod) {
if (rIsConstructor) {
return 1;
} else if (rIsField) {
return -1;
}
} else {
if (!rIsField) {
return 1;
}
}
// Verify these objects are the same type and cast them.
if (aLhs instanceof Method) {
return compare((Method) aLhs, (Method) aRhs);
} else if (aLhs instanceof Field) {
return compare((Field) aLhs, (Field) aRhs);
} else {
return compare((Constructor) aLhs, (Constructor) aRhs);
}
}
// Alas, the type system fails us.
private static int compare(Method aLhs, Method aRhs) {
// Initially, attempt to differentiate the methods be name alone..
String lName = aLhs.getName();
String rName = aRhs.getName();
int ret = lName.compareTo(rName);
if (ret != 0) {
return ret;
}
// The names were the same, so we need to compare signatures to find their uniqueness..
lName = Utils.getSignature(aLhs);
rName = Utils.getSignature(aRhs);
return lName.compareTo(rName);
}
private static int compare(Constructor<?> aLhs, Constructor<?> aRhs) {
// The names will be the same, so we need to compare signatures to find their uniqueness..
String lName = Utils.getSignature(aLhs);
String rName = Utils.getSignature(aRhs);
return lName.compareTo(rName);
}
private static int compare(Field aLhs, Field aRhs) {
// Compare field names..
String lName = aLhs.getName();
String rName = aRhs.getName();
return lName.compareTo(rName);
}
}
@@ -1,267 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.gecko.annotationProcessors.utils;
import org.mozilla.gecko.annotationProcessors.AnnotationInfo;
import org.mozilla.gecko.annotationProcessors.classloader.AnnotatableEntity;
import org.mozilla.gecko.annotationProcessors.classloader.ClassWithOptions;
import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Iterator;
/**
* Iterator over the methods in a given method list which have the WrappedJNIMethod
* annotation. Returns an object containing both the annotation (Which may contain interesting
* parameters) and the argument.
*/
public class GeneratableElementIterator implements Iterator<AnnotatableEntity> {
private final ClassWithOptions mClass;
private final Member[] mObjects;
private AnnotatableEntity mNextReturnValue;
private int mElementIndex;
private AnnotationInfo mClassInfo;
private boolean mIterateEveryEntry;
private boolean mSkipCurrentEntry;
public GeneratableElementIterator(ClassWithOptions annotatedClass) {
mClass = annotatedClass;
final Class<?> aClass = annotatedClass.wrappedClass;
// Get all the elements of this class as AccessibleObjects.
Member[] aMethods = aClass.getDeclaredMethods();
Member[] aFields = aClass.getDeclaredFields();
Member[] aCtors = aClass.getDeclaredConstructors();
// Shove them all into one buffer.
Member[] objs = new Member[aMethods.length + aFields.length + aCtors.length];
int offset = 0;
System.arraycopy(aMethods, 0, objs, 0, aMethods.length);
offset += aMethods.length;
System.arraycopy(aFields, 0, objs, offset, aFields.length);
offset += aFields.length;
System.arraycopy(aCtors, 0, objs, offset, aCtors.length);
// Sort the elements to ensure determinism.
Arrays.sort(objs, new AlphabeticAnnotatableEntityComparator<Member>());
mObjects = objs;
// Check for "Wrap ALL the things" flag.
for (Annotation annotation : aClass.getDeclaredAnnotations()) {
mClassInfo = buildAnnotationInfo(aClass, annotation);
if (mClassInfo != null) {
mIterateEveryEntry = true;
break;
}
}
if (mSkipCurrentEntry) {
throw new IllegalArgumentException("Cannot skip entire class");
}
findNextValue();
}
private Class<?>[] getFilteredInnerClasses() {
// Go through all inner classes and see which ones we want to generate.
final Class<?>[] candidates = mClass.wrappedClass.getDeclaredClasses();
int count = 0;
for (int i = 0; i < candidates.length; ++i) {
final GeneratableElementIterator testIterator
= new GeneratableElementIterator(new ClassWithOptions(candidates[i], null));
if (testIterator.hasNext()
|| testIterator.getFilteredInnerClasses() != null) {
count++;
continue;
}
// Clear out ones that don't match.
candidates[i] = null;
}
return count > 0 ? candidates : null;
}
public ClassWithOptions[] getInnerClasses() {
final Class<?>[] candidates = getFilteredInnerClasses();
if (candidates == null) {
return new ClassWithOptions[0];
}
int count = 0;
for (Class<?> candidate : candidates) {
if (candidate != null) {
count++;
}
}
final ClassWithOptions[] ret = new ClassWithOptions[count];
count = 0;
for (Class<?> candidate : candidates) {
if (candidate != null) {
ret[count++] = new ClassWithOptions(
candidate, mClass.generatedName + "::" + candidate.getSimpleName());
}
}
assert ret.length == count;
Arrays.sort(ret, new Comparator<ClassWithOptions>() {
@Override public int compare(ClassWithOptions lhs, ClassWithOptions rhs) {
return lhs.generatedName.compareTo(rhs.generatedName);
}
});
return ret;
}
private static <T extends Enum<T>> T getEnumValue(Class<T> type, String name)
throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
try {
return Enum.valueOf(type, name.toUpperCase());
} catch (IllegalArgumentException e) {
Object[] values = (Object[]) type.getDeclaredMethod("values").invoke(null);
StringBuilder names = new StringBuilder();
for (int i = 0; i < values.length; i++) {
if (i != 0) {
names.append(", ");
}
names.append(values[i].toString().toLowerCase());
}
System.err.println("***");
System.err.println("*** Invalid value \"" + name + "\" for " + type.getSimpleName());
System.err.println("*** Specify one of " + names.toString());
System.err.println("***");
e.printStackTrace(System.err);
System.exit(6);
return null;
}
}
private AnnotationInfo buildAnnotationInfo(AnnotatedElement element, Annotation annotation) {
Class<? extends Annotation> annotationType = annotation.annotationType();
final String annotationTypeName = annotationType.getName();
if (!annotationTypeName.equals("org.mozilla.gecko.annotation.WrapForJNI")) {
return null;
}
String stubName = null;
AnnotationInfo.ExceptionMode exceptionMode = null;
AnnotationInfo.CallingThread callingThread = null;
AnnotationInfo.DispatchTarget dispatchTarget = null;
try {
final Method skipMethod = annotationType.getDeclaredMethod("skip");
skipMethod.setAccessible(true);
if ((Boolean) skipMethod.invoke(annotation)) {
mSkipCurrentEntry = true;
return null;
}
// Determine the explicitly-given name of the stub to generate, if any.
final Method stubNameMethod = annotationType.getDeclaredMethod("stubName");
stubNameMethod.setAccessible(true);
stubName = (String) stubNameMethod.invoke(annotation);
final Method exceptionModeMethod = annotationType.getDeclaredMethod("exceptionMode");
exceptionModeMethod.setAccessible(true);
exceptionMode = getEnumValue(
AnnotationInfo.ExceptionMode.class,
(String) exceptionModeMethod.invoke(annotation));
final Method calledFromMethod = annotationType.getDeclaredMethod("calledFrom");
calledFromMethod.setAccessible(true);
callingThread = getEnumValue(
AnnotationInfo.CallingThread.class,
(String) calledFromMethod.invoke(annotation));
final Method dispatchToMethod = annotationType.getDeclaredMethod("dispatchTo");
dispatchToMethod.setAccessible(true);
dispatchTarget = getEnumValue(
AnnotationInfo.DispatchTarget.class,
(String) dispatchToMethod.invoke(annotation));
} catch (NoSuchMethodException e) {
System.err.println("Unable to find expected field on WrapForJNI annotation. Did the signature change?");
e.printStackTrace(System.err);
System.exit(3);
} catch (IllegalAccessException e) {
System.err.println("IllegalAccessException reading fields on WrapForJNI annotation. Seems the semantics of Reflection have changed...");
e.printStackTrace(System.err);
System.exit(4);
} catch (InvocationTargetException e) {
System.err.println("InvocationTargetException reading fields on WrapForJNI annotation. This really shouldn't happen.");
e.printStackTrace(System.err);
System.exit(5);
}
// If the method name was not explicitly given in the annotation generate one...
if (stubName.isEmpty()) {
stubName = Utils.getNativeName(element);
}
return new AnnotationInfo(stubName, exceptionMode, callingThread, dispatchTarget);
}
/**
* Find and cache the next appropriately annotated method, plus the annotation parameter, if
* one exists. Otherwise cache null, so hasNext returns false.
*/
private void findNextValue() {
while (mElementIndex < mObjects.length) {
Member candidateElement = mObjects[mElementIndex];
mElementIndex++;
for (Annotation annotation : ((AnnotatedElement) candidateElement).getDeclaredAnnotations()) {
AnnotationInfo info = buildAnnotationInfo((AnnotatedElement)candidateElement, annotation);
if (info != null) {
mNextReturnValue = new AnnotatableEntity(candidateElement, info);
return;
}
}
if (mSkipCurrentEntry) {
mSkipCurrentEntry = false;
continue;
}
// If no annotation found, we might be expected to generate anyway
// using default arguments, thanks to the "Generate everything" annotation.
if (mIterateEveryEntry) {
AnnotationInfo annotationInfo = new AnnotationInfo(
Utils.getNativeName(candidateElement),
mClassInfo.exceptionMode,
mClassInfo.callingThread,
mClassInfo.dispatchTarget);
mNextReturnValue = new AnnotatableEntity(candidateElement, annotationInfo);
return;
}
}
mNextReturnValue = null;
}
@Override
public boolean hasNext() {
return mNextReturnValue != null;
}
@Override
public AnnotatableEntity next() {
AnnotatableEntity ret = mNextReturnValue;
findNextValue();
return ret;
}
@Override
public void remove() {
throw new UnsupportedOperationException("Removal of methods from GeneratableElementIterator not supported.");
}
}
-288
View File
@@ -1,288 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.gecko.annotationProcessors.utils;
import org.mozilla.gecko.annotationProcessors.AnnotationInfo;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.nio.ByteBuffer;
import java.util.HashMap;
/**
* A collection of utility methods used by CodeGenerator. Largely used for translating types.
*/
public class Utils {
// A collection of lookup tables to simplify the functions to follow...
private static final HashMap<String, String> NATIVE_TYPES = new HashMap<String, String>();
static {
NATIVE_TYPES.put("void", "void");
NATIVE_TYPES.put("boolean", "bool");
NATIVE_TYPES.put("byte", "int8_t");
NATIVE_TYPES.put("char", "char16_t");
NATIVE_TYPES.put("short", "int16_t");
NATIVE_TYPES.put("int", "int32_t");
NATIVE_TYPES.put("long", "int64_t");
NATIVE_TYPES.put("float", "float");
NATIVE_TYPES.put("double", "double");
}
private static final HashMap<String, String> NATIVE_ARRAY_TYPES = new HashMap<String, String>();
static {
NATIVE_ARRAY_TYPES.put("boolean", "mozilla::jni::BooleanArray");
NATIVE_ARRAY_TYPES.put("byte", "mozilla::jni::ByteArray");
NATIVE_ARRAY_TYPES.put("char", "mozilla::jni::CharArray");
NATIVE_ARRAY_TYPES.put("short", "mozilla::jni::ShortArray");
NATIVE_ARRAY_TYPES.put("int", "mozilla::jni::IntArray");
NATIVE_ARRAY_TYPES.put("long", "mozilla::jni::LongArray");
NATIVE_ARRAY_TYPES.put("float", "mozilla::jni::FloatArray");
NATIVE_ARRAY_TYPES.put("double", "mozilla::jni::DoubleArray");
}
private static final HashMap<String, String> CLASS_DESCRIPTORS = new HashMap<String, String>();
static {
CLASS_DESCRIPTORS.put("void", "V");
CLASS_DESCRIPTORS.put("boolean", "Z");
CLASS_DESCRIPTORS.put("byte", "B");
CLASS_DESCRIPTORS.put("char", "C");
CLASS_DESCRIPTORS.put("short", "S");
CLASS_DESCRIPTORS.put("int", "I");
CLASS_DESCRIPTORS.put("long", "J");
CLASS_DESCRIPTORS.put("float", "F");
CLASS_DESCRIPTORS.put("double", "D");
}
/**
* Get the C++ type corresponding to the provided type parameter.
*
* @param type Class to determine the corresponding JNI type for.
* @return C++ type as a String
*/
public static String getNativeParameterType(Class<?> type, AnnotationInfo info) {
final String name = type.getName().replace('.', '/');
if (NATIVE_TYPES.containsKey(name)) {
return NATIVE_TYPES.get(name);
}
if (type.isArray()) {
final String compName = type.getComponentType().getName();
if (NATIVE_ARRAY_TYPES.containsKey(compName)) {
return NATIVE_ARRAY_TYPES.get(compName) + "::Param";
}
return "mozilla::jni::ObjectArray::Param";
}
if (type.equals(String.class) || type.equals(CharSequence.class)) {
return "mozilla::jni::String::Param";
}
if (type.equals(Class.class)) {
// You're doing reflection on Java objects from inside C, returning Class objects
// to C, generating the corresponding code using this Java program. Really?!
return "mozilla::jni::Class::Param";
}
if (type.equals(Throwable.class)) {
return "mozilla::jni::Throwable::Param";
}
if (type.equals(ByteBuffer.class)) {
return "mozilla::jni::ByteBuffer::Param";
}
return "mozilla::jni::Object::Param";
}
public static String getNativeReturnType(Class<?> type, AnnotationInfo info) {
final String name = type.getName().replace('.', '/');
if (NATIVE_TYPES.containsKey(name)) {
return NATIVE_TYPES.get(name);
}
if (type.isArray()) {
final String compName = type.getComponentType().getName();
if (NATIVE_ARRAY_TYPES.containsKey(compName)) {
return NATIVE_ARRAY_TYPES.get(compName) + "::LocalRef";
}
return "mozilla::jni::ObjectArray::LocalRef";
}
if (type.equals(String.class)) {
return "mozilla::jni::String::LocalRef";
}
if (type.equals(Class.class)) {
// You're doing reflection on Java objects from inside C, returning Class objects
// to C, generating the corresponding code using this Java program. Really?!
return "mozilla::jni::Class::LocalRef";
}
if (type.equals(Throwable.class)) {
return "mozilla::jni::Throwable::LocalRef";
}
if (type.equals(ByteBuffer.class)) {
return "mozilla::jni::ByteBuffer::LocalRef";
}
return "mozilla::jni::Object::LocalRef";
}
/**
* Get the JNI class descriptor corresponding to the provided type parameter.
*
* @param type Class to determine the corresponding JNI descriptor for.
* @return Class descripor as a String
*/
public static String getClassDescriptor(Class<?> type) {
final String name = type.getName().replace('.', '/');
if (CLASS_DESCRIPTORS.containsKey(name)) {
return CLASS_DESCRIPTORS.get(name);
}
if (type.isArray()) {
// Array names are already in class descriptor form.
return name;
}
return "L" + name + ';';
}
/**
* Get the JNI signaure for a member.
*
* @param member Member to get the signature for.
* @return JNI signature as a string
*/
public static String getSignature(Member member) {
return member instanceof Field ? getSignature((Field) member) :
member instanceof Method ? getSignature((Method) member) :
getSignature((Constructor<?>) member);
}
/**
* Get the JNI signaure for a field.
*
* @param member Field to get the signature for.
* @return JNI signature as a string
*/
public static String getSignature(Field member) {
return getClassDescriptor(member.getType());
}
private static String getSignature(Class<?>[] args, Class<?> ret) {
final StringBuilder sig = new StringBuilder("(");
for (int i = 0; i < args.length; i++) {
sig.append(getClassDescriptor(args[i]));
}
return sig.append(')').append(getClassDescriptor(ret)).toString();
}
/**
* Get the JNI signaure for a method.
*
* @param member Method to get the signature for.
* @return JNI signature as a string
*/
public static String getSignature(Method member) {
return getSignature(member.getParameterTypes(), member.getReturnType());
}
/**
* Get the JNI signaure for a constructor.
*
* @param member Constructor to get the signature for.
* @return JNI signature as a string
*/
public static String getSignature(Constructor<?> member) {
return getSignature(member.getParameterTypes(), void.class);
}
/**
* Get the C++ name for a member.
*
* @param member Member to get the name for.
* @return JNI name as a string
*/
public static String getNativeName(Member member) {
final String name = getMemberName(member);
return name.substring(0, 1).toUpperCase() + name.substring(1);
}
/**
* Get the C++ name for a member.
*
* @param member Member to get the name for.
* @return JNI name as a string
*/
public static String getNativeName(Class<?> clz) {
final String name = clz.getName();
return name.substring(0, 1).toUpperCase() + name.substring(1);
}
/**
* Get the C++ name for a member.
*
* @param member Member to get the name for.
* @return JNI name as a string
*/
public static String getNativeName(AnnotatedElement element) {
if (element instanceof Class<?>) {
return getNativeName((Class<?>)element);
} else if (element instanceof Member) {
return getNativeName((Member)element);
} else {
return null;
}
}
/**
* Get the JNI name for a member.
*
* @param member Member to get the name for.
* @return JNI name as a string
*/
public static String getMemberName(Member member) {
if (member instanceof Constructor) {
return "<init>";
}
return member.getName();
}
public static String getUnqualifiedName(String name) {
return name.substring(name.lastIndexOf(':') + 1);
}
/**
* Determine if a member is declared static.
*
* @param member The Member to check.
* @return true if the member is declared static, false otherwise.
*/
public static boolean isStatic(final Member member) {
return Modifier.isStatic(member.getModifiers());
}
/**
* Determine if a member is declared final.
*
* @param member The Member to check.
* @return true if the member is declared final, false otherwise.
*/
public static boolean isFinal(final Member member) {
return Modifier.isFinal(member.getModifiers());
}
}
-12
View File
@@ -28,24 +28,12 @@ MOZ_ARG_WITH_STRING(arch,
if test -z "$MOZ_ARCH"; then
dnl Defaults
case "${CPU_ARCH}-${OS_TARGET}" in
arm-Android)
MOZ_THUMB=yes
MOZ_ARCH=armv7-a
MOZ_FPU=vfp
MOZ_FLOAT_ABI=softfp
MOZ_ALIGN=no
;;
arm-Darwin)
MOZ_ARCH=toolchain-default
;;
esac
fi
if test "$MOZ_ARCH" = "armv6" -a "$OS_TARGET" = "Android"; then
MOZ_FPU=vfp
MOZ_FLOAT_ABI=softfp
fi
MOZ_ARG_WITH_STRING(thumb,
[ --with-thumb[[=yes|no|toolchain-default]]]
[ Use Thumb instruction set (-mthumb)],
+8 -16
View File
@@ -16,7 +16,7 @@ dnl set DEVELOPER_OPTIONS early; MOZ_DEFAULT_COMPILER is usually the first non-s
DEVELOPER_OPTIONS=,
DEVELOPER_OPTIONS=1)
dnl Default to MSVC for win32 and gcc-4.2 for darwin
dnl Default to MSVC for win32
dnl ==============================================================
if test -z "$CROSS_COMPILE"; then
case "$target" in
@@ -176,8 +176,8 @@ if test "$GNU_CC"; then
CFLAGS="$CFLAGS -ffunction-sections -fdata-sections"
CXXFLAGS="$CXXFLAGS -ffunction-sections -fdata-sections"
fi
CFLAGS="$CFLAGS -fno-math-errno"
CXXFLAGS="$CXXFLAGS -fno-exceptions -fno-math-errno"
CFLAGS="$CFLAGS -fno-math-errno -pipe"
CXXFLAGS="$CXXFLAGS -fno-exceptions -fno-math-errno -pipe"
if test "$CPU_ARCH" = "x86" -o "$CPU_ARCH" = "x86_64"; then
CFLAGS="$CFLAGS -msse2 -mfpmath=sse"
@@ -186,7 +186,8 @@ if test "$GNU_CC"; then
if test -z "$CLANG_CC"; then
case "$CC_VERSION" in
4.* | 5.*)
4.* | 5.* | 6.*)
AC_MSG_ERROR([Unsupported GCC version.])
;;
*)
# Lifetime Dead Store Elimination level 2 (default in GCC6+) breaks Gecko.
@@ -270,18 +271,9 @@ if test "$GNU_CC" -a "$GCC_USE_GNU_LD" -a -z "$DEVELOPER_OPTIONS"; then
fi
fi
# bionic in Android < 4.1 doesn't support PIE
# On OSX, the linker defaults to building PIE programs when targetting OSX 10.7+,
# but not when targetting OSX < 10.7. OSX < 10.7 doesn't support running PIE
# programs, so as long as support for OSX 10.6 is kept, we can't build PIE.
# Even after dropping 10.6 support, MOZ_PIE would not be useful since it's the
# default (and clang says the -pie option is not used).
# On other Unix systems, some file managers (Nautilus) can't start PIE programs
if test -n "$gonkdir" && test "$ANDROID_VERSION" -ge 16; then
MOZ_PIE=1
else
MOZ_PIE=
fi
# On some Unix systems, some file managers (e.g. Nautilus) can't start PIE programs
# so don't enable it by default.
MOZ_PIE=
MOZ_ARG_ENABLE_BOOL(pie,
[ --enable-pie Enable Position Independent Executables],
+2 -6
View File
@@ -114,7 +114,7 @@ esac
# Here we must recognize all the valid KERNEL-OS combinations.
maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
case $maybe_os in
nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | \
linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \
kopensolaris*-gnu* | \
@@ -122,10 +122,6 @@ case $maybe_os in
os=-$maybe_os
basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
;;
android-linux)
os=-linux-android
basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown
;;
*)
basic_machine=`echo $1 | sed 's/-[^-]*$//'`
if [ $basic_machine != $1 ]
@@ -1389,7 +1385,7 @@ case $os in
| -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
| -chorusos* | -chorusrdb* | -cegcc* \
| -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
| -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
| -mingw32* | -mingw64* | -linux-gnu* \
| -linux-newlib* | -linux-musl* | -linux-uclibc* \
| -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \
| -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
-5
View File
@@ -7,11 +7,6 @@ dnl disabling frame pointers in this architecture based on the configure
dnl options
AC_DEFUN([MOZ_SET_FRAMEPTR_FLAGS], [
case "$target" in
*android*)
unwind_tables="-funwind-tables"
;;
esac
if test "$GNU_CC"; then
MOZ_ENABLE_FRAME_PTR="-fno-omit-frame-pointer $unwind_tables"
MOZ_DISABLE_FRAME_PTR="-fomit-frame-pointer"
+2
View File
@@ -138,6 +138,8 @@ if test -n "$NSPR_CFLAGS" -o -n "$NSPR_LIBS"; then
,
AC_MSG_ERROR([system NSPR does not support PR_UINT64 or including prtypes.h does not provide it]))
CFLAGS=$_SAVE_CFLAGS
NSPR_INCLUDE_DIR=`echo ${NSPR_CFLAGS} | sed -e 's/.*-I\([^ ]*\).*/\1/'`
NSPR_LIB_DIR=`echo ${NSPR_LIBS} | sed -e 's/.*-L\([^ ]*\).*/\1/'`
elif test -z "$JS_POSIX_NSPR"; then
NSPR_INCLUDE_DIR="${DIST}/include/nspr"
NSPR_CFLAGS="-I${NSPR_INCLUDE_DIR}"
-90
View File
@@ -1,90 +0,0 @@
.. _build_androideclipse:
========================
Android Eclipse Projects
========================
The build system contains alpha support for generating Android Eclipse
project files to aid with development.
To generate Android Eclipse project files, you'll need to have a fully
built and packaged tree::
mach build && mach package
(This is because Eclipse itself packages an APK containing
``omni.ja``, and ``omni.ja`` is only assembled during packaging.)
Then, simply generate the Android Eclipse build backend::
mach build-backend -b AndroidEclipse
If all goes well, the path to the generated projects should be
printed (currently, ``$OBJDIR/android_eclipse``).
To use the generated Android Eclipse project files, you'll need to
have a recent version of Eclipse (see `Tested Versions`_) with the
`Eclipse ADT plugin
<http://developer.android.com/tools/sdk/eclipse-adt.html>`_
installed. You can then import all the projects into Eclipse using
*File > Import ... > General > Existing Projects into Workspace*.
Updating Project Files
======================
As you pull and update the source tree, your Android Eclipse files may
fall out of sync with the build configuration. The tree should still
build fine from within Eclipse, but source files may be missing and in
rare circumstances Eclipse's index may not have the proper build
configuration.
To account for this, you'll want to periodically regenerate the
Android Eclipse project files. You can do this by running ``mach build
&& mach package && mach build-backend -b AndroidEclipse`` from the
command line. It's a good idea to refresh and clean build all projects
in Eclipse after doing this.
In future, we'd like to include an Android Eclipse run configuration
or build target that integrates updating the project files.
Currently, regeneration rewrites the original project files. **If
you've made any customizations to the projects, they will likely get
overwritten.** We would like to improve this user experience in the
future.
Troubleshooting
===============
If Eclipse's builder gets confused, you should always refresh and
clean build all projects. If Eclipse's builder is continually
confused, you can see a log of what is happening at
``$OBJDIR/android_eclipse/build.log``.
If you run into memory problems executing ``dex``, you should
`Increase Eclipse's memory limits <http://stackoverflow.com/a/11093228>`_.
The produced Android Eclipse project files are unfortunately not
portable. Please don't move them around.
Structure of Android Eclipse projects
=====================================
The Android Eclipse backend generates several projects spanning Fennec
itself and its tests. You'll mostly interact with the *Fennec* project
itself.
In future, we'd like to expand this documentation to include some of
the technical details of how the Eclipse integration works, and how to
add additional Android Eclipse projects using the ``moz.build``
system.
Tested Versions
===============
=============== ==================================== =================
OS Version Working as of
=============== ==================================== =================
Mac OS X Luna (Build id: 20130919-0819) February 2014
Mac OS X Kepler (Build id: 20131219-0014) February 2014
Mac OS X 10.8.5 Kepler (Build id: 20130919-0819) February 2014
=============== ==================================== =================
+4 -4
View File
@@ -18,14 +18,14 @@ built tree::
mach build
Then, simply generate the Android Eclipse build backend::
Then, simply generate the Eclipse build backend::
mach build-backend -b CppEclipse
If all goes well, the path to the generated workspace should be
printed (currently, ``$OBJDIR/android_eclipse``).
printed.
To use the generated Android Eclipse project files, you'll need to
To use the generated Eclipse project files, you'll need to
have a Eclipse CDT 8.3 (We plan to follow the latest Eclipse release)
`Eclipse CDT plugin
<https://www.eclipse.org/cdt/>`_
@@ -43,7 +43,7 @@ rare circumstances Eclipse's index may not have the proper build
configuration.
To account for this, you'll want to periodically regenerate the
Android Eclipse project files. You can do this by running ``mach build
Eclipse project files. You can do this by running ``mach build
&& mach build-backend -b CppEclipse`` from the
command line.
-1
View File
@@ -33,7 +33,6 @@ integrated development environment (IDE)
.. toctree::
:maxdepth: 1
androideclipse
cppeclipse
visualstudio
-79
View File
@@ -17,84 +17,5 @@ like a re-packaging post-processing step.
There are scripts in-tree in mozharness to orchestrate these re-packaging
steps for `Desktop
<https://dxr.mozilla.org/mozilla-central/source/testing/mozharness/scripts/desktop_l10n.py>`_
and `Android
<https://dxr.mozilla.org/mozilla-central/source/testing/mozharness/scripts/mobile_l10n.py>`_
but they rely heavily on buildbot information so they are almost impossible to
run locally.
The following instructions are extracted from the `Android script with hg hash
494289c7
<https://dxr.mozilla.org/mozilla-central/rev/494289c72ba3997183e7b5beaca3e0447ecaf96d/testing/mozharness/scripts/mobile_l10n.py>`_,
and may need to be updated and slightly modified for Desktop.
Step by step instructions for Android
-------------------------------------
This assumes that ``$AB_CD`` is the locale you want to repack with; I tested
with "ar" and "en-GB".
.. warning:: l10n repacks do not work with artifact builds. Repackaging
compiles no code so supporting ``--disable-compile-environment`` would not
save much, if any, time.
#. You must have a built and packaged object directory, or a pre-built
``en-US`` package.
.. code-block:: shell
./mach build
./mach package
#. Clone ``l10n-central/$AB_CD`` so that it is a sibling to your
``mozilla-central`` directory.
.. code-block:: shell
$ ls -al
mozilla-central
...
$ mkdir -p l10n-central
$ hg clone https://hg.mozilla.org/l10n-central/$AB_CD l10n-central/$AB_CD
$ ls -al
mozilla-central
l10n-central/$AB_CD
...
#. Copy your ``mozconfig`` to ``mozconfig.l10n`` and add the following.
::
ac_add_options --with-l10n-base=../../l10n-central
ac_add_options --disable-tests
mk_add_options MOZ_OBJDIR=./objdir-l10n
#. Configure and prepare the l10n object directory.
.. code-block:: shell
MOZCONFIG=mozconfig.l10n ./mach configure
MOZCONFIG=mozconfig.l10n ./mach build -C config export
MOZCONFIG=mozconfig.l10n ./mach build buildid.h
#. Copy your built package and unpack it into the l10n object directory.
.. code-block:: shell
cp $OBJDIR/dist/fennec-*en-US*.apk ./objdir-l10n/dist
MOZCONFIG=mozconfig.l10n ./mach build -C mobile/android/locales unpack
#. Run the ``compare-locales`` script to write locale-specific changes into
``objdir-l10n/merged``.
.. code-block:: shell
MOZCONFIG=mozconfig.l10n ./mach compare-locales --merge-dir objdir-l10n/merged $AB_CD
#. Finally, repackage using the locale-specific changes.
.. code-block:: shell
MOZCONFIG=mozconfig.l10n LOCALE_MERGEDIR=`realpath objdir-l10n/merged` ./mach build -C mobile/android/locales installers-$AB_CD
(Note the absolute path for ``LOCALE_MERGEDIR``.) You should find a
re-packaged build at ``objdir-l10n/dist/fennec-*$AB_CD*.apk``.
+4 -19
View File
@@ -62,8 +62,7 @@ bits
buildapp
The path to the XUL application being built.
For desktop Firefox, this is ``browser``. For Fennec, it's
``mobile/android``. For B2G, it's ``b2g``.
For desktop Firefox, this is ``browser``.
crashreporter
Whether the crash reporter is enabled for this build.
@@ -72,13 +71,6 @@ crashreporter
Always defined.
datareporting
Whether data reporting (MOZ_DATA_REPORTING) is enabled for this build.
Values are ``true`` and ``false``.
Always defined.
debug
Whether this is a debug build.
@@ -86,13 +78,6 @@ debug
Always defined.
healthreport
Whether the Health Report feature is enabled.
Values are ``true`` and ``false``.
Always defined.
mozconfig
The path of the :ref:`mozconfig file <mozconfig>` used to produce this build.
@@ -107,9 +92,9 @@ nightly_build
os
The operating system the build is produced for. Values for tier-1
supported platforms are ``linux``, ``win``, ``mac``, ``b2g``, and
``android``. For other platforms, the value is the lowercase version
of the ``OS_TARGET`` variable from ``config.status``.
supported platforms are ``linux`` and ``win``. For other platforms,
the value is the lowercase version of the ``OS_TARGET`` variable
from ``config.status``.
Always defined.
-55
View File
@@ -54,58 +54,3 @@ archive::
$ ./mach python build/windows_toolchain.py create-zip vs2015u3
The produced archive will be the argument to ``create-zip`` + ``.zip``.
Firefox for Android with Gradle
===============================
To build Firefox for Android with Gradle in automation, archives
containing both the Gradle executable and a Maven repository
comprising the exact build dependencies are produced and uploaded to
an internal Mozilla server. The build automation will download,
verify, and extract these archive before building. These archives
provide a self-contained Gradle and Maven repository so that machines
don't need to fetch additional Maven dependencies at build time.
(Gradle and the downloaded Maven dependencies can be both
redistributed publicly.)
Archiving the Gradle executable is straight-forward, but archiving a
local Maven repository is not. Therefore a special Task Cluster
Docker image and job exist for producing the required archives. The
Docker image definition is rooted in
``taskcluster/docker/android-gradle-build``. The Task Cluster job
definition is in
``testing/taskcluster/tasks/builds/android_api_15_gradle_dependencies.yml``.
The job runs in a container based on the custom Docker image and
spawns a Sonatype Nexus proxying Maven repository process in the
background. The job builds Firefox for Android using Gradle and the
in-tree Gradle configuration rooted at ``build.gradle``. The spawned
proxying Maven repository downloads external dependencies and collects
them. After the Gradle build completes, the job archives the Gradle
version used to build, and the downloaded Maven repository, and
exposes them as Task Cluster artifacts.
Here is `an example try job fetching these dependencies
<https://treeherder.mozilla.org/#/jobs?repo=try&revision=75bc98935147&selectedJob=17793653>`_.
The resulting task produced a `Gradle archive
<https://queue.taskcluster.net/v1/task/CeYMgAP3Q-KF8h37nMhJjg/runs/0/artifacts/public%2Fbuild%2Fgradle.tar.xz>`_
and a `Maven repository archive
<https://queue.taskcluster.net/v1/task/CeYMgAP3Q-KF8h37nMhJjg/runs/0/artifacts/public%2Fbuild%2Fjcentral.tar.xz>`_.
These archives were then uploaded (manually) to Mozilla automation
using tooltool for consumption in Gradle builds.
To update the version of Gradle in the archive produced, update
``gradle/wrapper/gradle-wrapper.properties``. Be sure to also update
the SHA256 checksum to prevent poisoning the build machines!
To update the versions of Gradle dependencies used, update
``dependencies`` sections in the in-tree Gradle configuration rooted
at ``build.gradle``. Once you are confident your changes build
locally, push a fresh try build with an invocation like::
$ hg push-to-try -m "try: -b o -p android-api-15-gradle-dependencies"
Then `upload your archives to tooltool
<https://wiki.mozilla.org/ReleaseEngineering/Applications/Tooltool#How_To_Upload_To_Tooltool>`_,
update the in-tree manifests in
``mobile/android/config/tooltool-manifests``, and push a fresh try
build.
+4 -39
View File
@@ -3,7 +3,9 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
gyp_vars = {
include('gyp_base.mozbuild')
gyp_vars.update({
'lsan': 0,
'asan': 0,
'build_with_mozilla': 1,
@@ -18,8 +20,6 @@ gyp_vars = {
'clang_use_chrome_plugins': 0,
'enable_protobuf': 0,
'include_tests': 0,
'enable_android_opensl': 1,
'enable_android_opensl_output': 0,
# use_system_lib* still seems to be in use in trunk/build
'use_system_libjpeg': 0,
'use_system_libvpx': 0,
@@ -67,42 +67,7 @@ gyp_vars = {
# linker to throw away uneeded bits.
'include_isac': 1,
'include_pcm16b': 1,
}
os = CONFIG['OS_TARGET']
if os == 'WINNT':
gyp_vars.update(
MSVS_VERSION=CONFIG['_MSVS_VERSION'],
MSVS_OS_BITS=64 if CONFIG['HAVE_64BIT_BUILD'] else 32,
)
elif os == 'Android':
gyp_vars.update(
gtest_target_type='executable',
moz_webrtc_mediacodec=1,
android_toolchain=CONFIG.get('ANDROID_TOOLCHAIN', ''),
)
flavors = {
'WINNT': 'win',
'Android': 'android',
'Linux': 'linux',
'SunOS': 'solaris',
'GNU/kFreeBSD': 'freebsd',
'DragonFly': 'dragonfly',
'FreeBSD': 'freebsd',
'NetBSD': 'netbsd',
'OpenBSD': 'openbsd',
}
gyp_vars['OS'] = flavors.get(os)
arches = {
'x86_64': 'x64',
'x86': 'ia32',
'aarch64': 'arm64',
}
gyp_vars['target_arch'] = arches.get(CONFIG['CPU_ARCH'], CONFIG['CPU_ARCH'])
})
if CONFIG['ARM_ARCH']:
if int(CONFIG['ARM_ARCH']) < 7:
+36
View File
@@ -0,0 +1,36 @@
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
gyp_vars = {}
os = CONFIG['OS_TARGET']
if os == 'WINNT':
gyp_vars.update(
MSVS_VERSION=CONFIG['_MSVS_VERSION'],
MSVS_OS_BITS=64 if CONFIG['HAVE_64BIT_BUILD'] else 32,
)
flavors = {
'WINNT': 'win',
'Linux': 'linux',
'Darwin': 'mac' if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa' else 'ios',
'SunOS': 'solaris',
'GNU/kFreeBSD': 'freebsd',
'DragonFly': 'dragonfly',
'FreeBSD': 'freebsd',
'NetBSD': 'netbsd',
'OpenBSD': 'openbsd',
}
gyp_vars['OS'] = flavors.get(os)
arches = {
'x86_64': 'x64',
'x86': 'ia32',
'aarch64': 'arm64',
}
gyp_vars['host_arch'] = arches.get(CONFIG['HOST_CPU_ARCH'], CONFIG['HOST_CPU_ARCH'])
gyp_vars['target_arch'] = arches.get(CONFIG['CPU_ARCH'], CONFIG['CPU_ARCH'])
+14 -10
View File
@@ -35,7 +35,6 @@ Press ENTER/RETURN to continue or CTRL+c to abort.
# TODO Bug 794506 Integrate with the in-tree virtualenv configuration.
SEARCH_PATHS = [
'python/mach',
'python/mozboot',
'python/mozbuild',
'python/mozlint',
'python/mozversioncontrol',
@@ -65,11 +64,6 @@ SEARCH_PATHS = [
'other-licenses/ply',
'taskcluster',
'testing',
'testing/firefox-ui/harness',
'testing/marionette/client',
'testing/marionette/harness',
'testing/marionette/harness/marionette_harness/runner/mixins/browsermob-proxy-py',
'testing/marionette/puppeteer/firefox',
'testing/mozbase/mozcrash',
'testing/mozbase/mozdebug',
'testing/mozbase/mozdevice',
@@ -105,16 +99,13 @@ MACH_MODULES = [
'python/mach/mach/commands/commandinfo.py',
'python/mach/mach/commands/settings.py',
'python/compare-locales/mach_commands.py',
'python/mozboot/mozboot/mach_commands.py',
'python/mozbuild/mozbuild/mach_commands.py',
'python/mozbuild/mozbuild/backend/mach_commands.py',
'python/mozbuild/mozbuild/compilation/codecomplete.py',
'python/mozbuild/mozbuild/frontend/mach_commands.py',
'services/common/tests/mach_commands.py',
'taskcluster/mach_commands.py',
'testing/firefox-ui/mach_commands.py',
'testing/mach_commands.py',
'testing/marionette/mach_commands.py',
'testing/mochitest/mach_commands.py',
'testing/mozharness/mach_commands.py',
'testing/talos/mach_commands.py',
@@ -198,7 +189,20 @@ def bootstrap(topsrcdir, mozilla_dir=None):
# like surprises.
sys.path[0:0] = [os.path.join(mozilla_dir, path) for path in SEARCH_PATHS]
import mach.main
from mozboot.util import get_state_dir
def get_state_dir():
"""Obtain path to a directory to hold state.
Returns a tuple of the path and a bool indicating whether the
value came from an environment variable.
"""
state_user_dir = os.path.expanduser('~/.mozbuild')
state_env_dir = os.environ.get('MOZBUILD_STATE_PATH')
if state_env_dir:
return state_env_dir, True
else:
return state_user_dir, False
def telemetry_handler(context, data):
# We have not opted-in to telemetry
+26
View File
@@ -0,0 +1,26 @@
#!/bin/bash
set -e
if ! git remote -v | grep origin | grep -q cctools-port; then
echo "must be in a cctools-port checkout"
exit 1
fi
mkdir build-cctools
cd build-cctools
CFLAGS='-mcpu=generic -mtune=generic' MACOSX_DEPLOYMENT_TARGET=10.7 ../cctools/configure --target=x86_64-apple-darwin11
env MACOSX_DEPLOYMENT_TARGET=10.7 make -s -j4
if test ! -e ld64/src/ld/ld; then
echo "ld did not get built"
exit 1
fi
gtar jcf cctools.tar.bz2 ld64/src/ld/ld --transform 's#ld64/src/ld#cctools/bin#'
cd ../
echo "build from $(git show --pretty=format:%H -s HEAD) complete!"
echo "upload the build-cctools/cctools.tar.bz2 file to tooltool"
+47
View File
@@ -0,0 +1,47 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
MOZ_AUTOMATION_L10N_CHECK=0
if [ "x$IS_NIGHTLY" = "xyes" ]; then
# Some nightlies (eg: Mulet) don't want these set.
MOZ_AUTOMATION_UPDATE_PACKAGING=${MOZ_AUTOMATION_UPDATE_PACKAGING-1}
MOZ_AUTOMATION_SDK=${MOZ_AUTOMATION_SDK-1}
fi
. "$topsrcdir/build/mozconfig.common"
# ld needs libLTO.so from llvm
mk_add_options "export LD_LIBRARY_PATH=$topsrcdir/clang/lib"
CROSS_CCTOOLS_PATH=$topsrcdir/cctools
CROSS_SYSROOT=$topsrcdir/MacOSX10.7.sdk
CROSS_PRIVATE_FRAMEWORKS=$CROSS_SYSROOT/System/Library/PrivateFrameworks
FLAGS="-target x86_64-apple-darwin10 -mlinker-version=136 -B $CROSS_CCTOOLS_PATH/bin -isysroot $CROSS_SYSROOT"
export CC="$topsrcdir/clang/bin/clang $FLAGS"
export CXX="$topsrcdir/clang/bin/clang++ $FLAGS"
export CPP="$topsrcdir/clang/bin/clang $FLAGS -E"
export LLVMCONFIG=$topsrcdir/clang/bin/llvm-config
export LDFLAGS="-Wl,-syslibroot,$CROSS_SYSROOT -Wl,-dead_strip"
export TOOLCHAIN_PREFIX=$CROSS_CCTOOLS_PATH/bin/x86_64-apple-darwin10-
export DSYMUTIL=$topsrcdir/clang/bin/llvm-dsymutil
export GENISOIMAGE=$topsrcdir/genisoimage/genisoimage
export DMG_TOOL=$topsrcdir/dmg/dmg
export HOST_CC="$topsrcdir/clang/bin/clang"
export HOST_CXX="$topsrcdir/clang/bin/clang++"
export HOST_CPP="$topsrcdir/clang/bin/clang -E"
export HOST_CFLAGS="-g"
export HOST_CXXFLAGS="-g"
export HOST_LDFLAGS="-g"
ac_add_options --target=x86_64-apple-darwin
ac_add_options --with-macos-private-frameworks=$CROSS_PRIVATE_FRAMEWORKS
# Enable static analysis checks by default on OSX cross builds.
ac_add_options --enable-clang-plugin
. "$topsrcdir/build/mozconfig.cache"
export SOCORRO_SYMBOL_UPLOAD_TOKEN_FILE=/builds/crash-stats-api.token
+46
View File
@@ -0,0 +1,46 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
if [ "x$IS_NIGHTLY" = "xyes" ]; then
# Some nightlies (eg: Mulet) don't want these set.
MOZ_AUTOMATION_UPLOAD_SYMBOLS=${MOZ_AUTOMATION_UPLOAD_SYMBOLS-1}
MOZ_AUTOMATION_UPDATE_PACKAGING=${MOZ_AUTOMATION_UPDATE_PACKAGING-1}
MOZ_AUTOMATION_SDK=${MOZ_AUTOMATION_SDK-1}
fi
. "$topsrcdir/build/mozconfig.common"
if [ -d "$topsrcdir/clang" ]; then
# mozilla-central based build
export CC=$topsrcdir/clang/bin/clang
export CXX=$topsrcdir/clang/bin/clang++
export LLVMCONFIG=$topsrcdir/clang/bin/llvm-config
export DSYMUTIL=$topsrcdir/clang/bin/llvm-dsymutil
# Use an updated linker.
ldflags="-B$topsrcdir/cctools/bin"
elif [ -d "$topsrcdir/../clang" ]; then
# comm-central based build
export CC=$topsrcdir/../clang/bin/clang
export CXX=$topsrcdir/../clang/bin/clang++
export LLVMCONFIG=$topsrcdir/../clang/bin/llvm-config
export DSYMUTIL=$topsrcdir/../clang/bin/llvm-dsymutil
# Use an updated linker.
ldflags="-B$topsrcdir/../cctools/bin"
fi
# Ensure the updated linker doesn't generate things our older build tools
# don't understand.
ldflags="$ldflags -Wl,-no_data_in_code_info"
export LDFLAGS="$ldflags"
# If not set use the system default clang
if [ -z "$CC" ]; then
export CC=clang
fi
# If not set use the system default clang++
if [ -z "$CXX" ]; then
export CXX=clang++
fi
export SOCORRO_SYMBOL_UPLOAD_TOKEN_FILE=/builds/crash-stats-api.token
+5
View File
@@ -0,0 +1,5 @@
if test `uname -s` = Linux; then
. $topsrcdir/build/macosx/cross-mozconfig.common
else
. $topsrcdir/build/macosx/local-mozconfig.common
fi
+20
View File
@@ -0,0 +1,20 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include <unistd.h>
#include <stdio.h>
int main(int argc, char **argv)
{
if (argc != 2)
return 1;
uid_t realuser = getuid();
char uidstring[20];
snprintf(uidstring, 19, "%i", realuser);
uidstring[19] = '\0';
return execl("/usr/sbin/chown",
"/usr/sbin/chown", "-R", "-h", uidstring, argv[1], (char*) 0);
}
+14
View File
@@ -0,0 +1,14 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include <unistd.h>
int main(int argc, char **argv)
{
if (argc != 2)
return 1;
return execl("/usr/sbin/chown",
"/usr/sbin/chown", "-R", "-h", "root:admin", argv[1], (char*) 0);
}
+11
View File
@@ -0,0 +1,11 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
# i386/x86-64 Universal Build mozconfig
# As used here, arguments in $MOZ_BUILD_PROJECTS are suitable as arguments
# to gcc's -arch parameter.
mk_add_options MOZ_BUILD_PROJECTS="x86_64 i386"
. $topsrcdir/build/macosx/universal/mozconfig.common
+55
View File
@@ -0,0 +1,55 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
mk_add_options MOZ_UNIFY_BDATE=1
DARWIN_VERSION=10
ac_add_app_options i386 --target=i386-apple-darwin$DARWIN_VERSION
ac_add_app_options x86_64 --target=x86_64-apple-darwin$DARWIN_VERSION
ac_add_app_options i386 --with-unify-dist=../x86_64/dist
ac_add_app_options x86_64 --with-unify-dist=../i386/dist
if ! test `uname -s` = Linux; then
# Cross-universal builds already do the equivalent of this by setting -isysroot directly
ac_add_options --with-macos-sdk=/Developer/SDKs/MacOSX10.7.sdk
fi
. $topsrcdir/build/macosx/mozconfig.common
# $MOZ_BUILD_APP is only defined when sourced by configure. That's not a
# problem, because the variables it affects only need to be set for
# configure.
if test -n "$MOZ_BUILD_APP" ; then
if test "$MOZ_BUILD_APP" = "i386" -o "$MOZ_BUILD_APP" = "x86_64"; then
TARGET_CPU=$MOZ_BUILD_APP
# $HOST_CXX is presently unused. $HOST_CC will only be used during a cross
# compile.
HOST_CC=$CC
HOST_CXX=$CXX
NATIVE_CPU=`$topsrcdir/build/autoconf/config.guess | cut -f1 -d-`
# It's not strictly necessary to specify -arch during native builds, but it
# makes the merged about:buildconfig easier to follow, and it reduces
# conditionalized differences between builds.
CC="$CC -arch $TARGET_CPU"
CXX="$CXX -arch $TARGET_CPU"
# These must be set for cross builds, and don't hurt straight builds.
RANLIB="${TOOLCHAIN_PREFIX}ranlib"
AR="${TOOLCHAIN_PREFIX}ar"
AS=$CC
LD=ld
STRIP="${TOOLCHAIN_PREFIX}strip"
OTOOL="${TOOLCHAIN_PREFIX}otool"
# Each per-CPU build should be entirely oblivious to the fact that a
# universal binary will be produced. The exception is packager.mk, which
# needs to know to look for universal bits when building the .dmg.
UNIVERSAL_BINARY=1
export CC CXX HOST_CC HOST_CXX RANLIB AR AS LD STRIP OTOOL
fi
fi
+1525
View File
File diff suppressed because it is too large. Load diff
-451
View File
@@ -1,451 +0,0 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
# You can obtain one at http://mozilla.org/MPL/2.0/.
import datetime
import mozcrash
import threading
import os
import posixpath
import Queue
import re
import shutil
import signal
import tempfile
import time
import traceback
import zipfile
from automation import Automation
from mozlog import get_default_logger
from mozprocess import ProcessHandlerMixin
class StdOutProc(ProcessHandlerMixin):
"""Process handler for b2g which puts all output in a Queue.
"""
def __init__(self, cmd, queue, **kwargs):
self.queue = queue
kwargs.setdefault('processOutputLine', []).append(self.handle_output)
ProcessHandlerMixin.__init__(self, cmd, **kwargs)
def handle_output(self, line):
self.queue.put_nowait(line)
class B2GRemoteAutomation(Automation):
_devicemanager = None
def __init__(self, deviceManager, appName='', remoteLog=None,
marionette=None):
self._devicemanager = deviceManager
self._appName = appName
self._remoteProfile = None
self._remoteLog = remoteLog
self.marionette = marionette
self._is_emulator = False
self.test_script = None
self.test_script_args = None
# Default our product to b2g
self._product = "b2g"
self.lastTestSeen = "b2gautomation.py"
# Default log finish to mochitest standard
self.logFinish = 'INFO SimpleTest FINISHED'
Automation.__init__(self)
def setEmulator(self, is_emulator):
self._is_emulator = is_emulator
def setDeviceManager(self, deviceManager):
self._devicemanager = deviceManager
def setAppName(self, appName):
self._appName = appName
def setRemoteProfile(self, remoteProfile):
self._remoteProfile = remoteProfile
def setProduct(self, product):
self._product = product
def setRemoteLog(self, logfile):
self._remoteLog = logfile
def getExtensionIDFromRDF(self, rdfSource):
"""
Retrieves the extension id from an install.rdf file (or string).
"""
from xml.dom.minidom import parse, parseString, Node
if isinstance(rdfSource, file):
document = parse(rdfSource)
else:
document = parseString(rdfSource)
# Find the <em:id> element. There can be multiple <em:id> tags
# within <em:targetApplication> tags, so we have to check this way.
for rdfChild in document.documentElement.childNodes:
if rdfChild.nodeType == Node.ELEMENT_NODE and rdfChild.tagName == "Description":
for descChild in rdfChild.childNodes:
if descChild.nodeType == Node.ELEMENT_NODE and descChild.tagName == "em:id":
return descChild.childNodes[0].data
return None
def installExtension(self, extensionSource, profileDir, extensionID=None):
# Bug 827504 - installing special-powers extension separately causes problems in B2G
if extensionID != "special-powers@mozilla.org":
if not os.path.isdir(profileDir):
self.log.info("INFO | automation.py | Cannot install extension, invalid profileDir at: %s", profileDir)
return
installRDFFilename = "install.rdf"
extensionsRootDir = os.path.join(profileDir, "extensions", "staged")
if not os.path.isdir(extensionsRootDir):
os.makedirs(extensionsRootDir)
if os.path.isfile(extensionSource):
reader = zipfile.ZipFile(extensionSource, "r")
for filename in reader.namelist():
# Sanity check the zip file.
if os.path.isabs(filename):
self.log.info("INFO | automation.py | Cannot install extension, bad files in xpi")
return
# We may need to dig the extensionID out of the zip file...
if extensionID is None and filename == installRDFFilename:
extensionID = self.getExtensionIDFromRDF(reader.read(filename))
# We must know the extensionID now.
if extensionID is None:
self.log.info("INFO | automation.py | Cannot install extension, missing extensionID")
return
# Make the extension directory.
extensionDir = os.path.join(extensionsRootDir, extensionID)
os.mkdir(extensionDir)
# Extract all files.
reader.extractall(extensionDir)
elif os.path.isdir(extensionSource):
if extensionID is None:
filename = os.path.join(extensionSource, installRDFFilename)
if os.path.isfile(filename):
with open(filename, "r") as installRDF:
extensionID = self.getExtensionIDFromRDF(installRDF)
if extensionID is None:
self.log.info("INFO | automation.py | Cannot install extension, missing extensionID")
return
# Copy extension tree into its own directory.
# "destination directory must not already exist".
shutil.copytree(extensionSource, os.path.join(extensionsRootDir, extensionID))
else:
self.log.info("INFO | automation.py | Cannot install extension, invalid extensionSource at: %s", extensionSource)
# Set up what we need for the remote environment
def environment(self, env=None, xrePath=None, crashreporter=True, debugger=False):
# Because we are running remote, we don't want to mimic the local env
# so no copying of os.environ
if env is None:
env = {}
# We always hide the results table in B2G; it's much slower if we don't.
env['MOZ_HIDE_RESULTS_TABLE'] = '1'
return env
def waitForNet(self):
active = False
time_out = 0
while not active and time_out < 40:
data = self._devicemanager._runCmd(['shell', '/system/bin/netcfg']).stdout.readlines()
data.pop(0)
for line in data:
if (re.search(r'UP\s+(?:[0-9]{1,3}\.){3}[0-9]{1,3}', line)):
active = True
break
time_out += 1
time.sleep(1)
return active
def checkForCrashes(self, directory, symbolsPath):
crashed = False
remote_dump_dir = self._remoteProfile + '/minidumps'
print "checking for crashes in '%s'" % remote_dump_dir
if self._devicemanager.dirExists(remote_dump_dir):
local_dump_dir = tempfile.mkdtemp()
self._devicemanager.getDirectory(remote_dump_dir, local_dump_dir)
try:
logger = get_default_logger()
if logger is not None:
crashed = mozcrash.log_crashes(logger, local_dump_dir, symbolsPath, test=self.lastTestSeen)
else:
crashed = mozcrash.check_for_crashes(local_dump_dir, symbolsPath, test_name=self.lastTestSeen)
except:
traceback.print_exc()
finally:
shutil.rmtree(local_dump_dir)
self._devicemanager.removeDir(remote_dump_dir)
return crashed
def buildCommandLine(self, app, debuggerInfo, profileDir, testURL, extraArgs):
# if remote profile is specified, use that instead
if (self._remoteProfile):
profileDir = self._remoteProfile
cmd, args = Automation.buildCommandLine(self, app, debuggerInfo, profileDir, testURL, extraArgs)
return app, args
def waitForFinish(self, proc, utilityPath, timeout, maxTime, startTime,
debuggerInfo, symbolsPath, outputHandler=None):
""" Wait for tests to finish (as evidenced by a signature string
in logcat), or for a given amount of time to elapse with no
output.
"""
timeout = timeout or 120
while True:
lines = proc.getStdoutLines(timeout)
if lines:
currentlog = '\n'.join(lines)
if outputHandler:
for line in lines:
outputHandler(line)
else:
print(currentlog)
# Match the test filepath from the last TEST-START line found in the new
# log content. These lines are in the form:
# ... INFO TEST-START | /filepath/we/wish/to/capture.html\n
testStartFilenames = re.findall(r"TEST-START \| ([^\s]*)", currentlog)
if testStartFilenames:
self.lastTestSeen = testStartFilenames[-1]
if (outputHandler and outputHandler.suite_finished) or (
hasattr(self, 'logFinish') and self.logFinish in currentlog):
return 0
else:
self.log.info("TEST-UNEXPECTED-FAIL | %s | application timed "
"out after %d seconds with no output",
self.lastTestSeen, int(timeout))
self._devicemanager.killProcess('/system/b2g/b2g', sig=signal.SIGABRT)
timeout = 10 # seconds
starttime = datetime.datetime.utcnow()
while datetime.datetime.utcnow() - starttime < datetime.timedelta(seconds=timeout):
if not self._devicemanager.processExist('/system/b2g/b2g'):
break
time.sleep(1)
else:
print "timed out after %d seconds waiting for b2g process to exit" % timeout
return 1
self.checkForCrashes(None, symbolsPath)
return 1
def getDeviceStatus(self, serial=None):
# Get the current status of the device. If we know the device
# serial number, we look for that, otherwise we use the (presumably
# only) device shown in 'adb devices'.
serial = serial or self._devicemanager._deviceSerial
status = 'unknown'
for line in self._devicemanager._runCmd(['devices']).stdout.readlines():
result = re.match('(.*?)\t(.*)', line)
if result:
thisSerial = result.group(1)
if not serial or thisSerial == serial:
serial = thisSerial
status = result.group(2)
return (serial, status)
def restartB2G(self):
# TODO hangs in subprocess.Popen without this delay
time.sleep(5)
self._devicemanager._checkCmd(['shell', 'stop', 'b2g'])
# Wait for a bit to make sure B2G has completely shut down.
time.sleep(10)
self._devicemanager._checkCmd(['shell', 'start', 'b2g'])
if self._is_emulator:
self.marionette.emulator.wait_for_port(self.marionette.port)
def rebootDevice(self):
# find device's current status and serial number
serial, status = self.getDeviceStatus()
# reboot!
self._devicemanager._runCmd(['shell', '/system/bin/reboot'])
# The above command can return while adb still thinks the device is
# connected, so wait a little bit for it to disconnect from adb.
time.sleep(10)
# wait for device to come back to previous status
print 'waiting for device to come back online after reboot'
start = time.time()
rserial, rstatus = self.getDeviceStatus(serial)
while rstatus != 'device':
if time.time() - start > 120:
# device hasn't come back online in 2 minutes, something's wrong
raise Exception("Device %s (status: %s) not back online after reboot" % (serial, rstatus))
time.sleep(5)
rserial, rstatus = self.getDeviceStatus(serial)
print 'device:', serial, 'status:', rstatus
def Process(self, cmd, stdout=None, stderr=None, env=None, cwd=None):
# On a desktop or fennec run, the Process method invokes a gecko
# process in which to the tests. For B2G, we simply
# reboot the device (which was configured with a test profile
# already), wait for B2G to start up, and then navigate to the
# test url using Marionette. There doesn't seem to be any way
# to pass env variables into the B2G process, but this doesn't
# seem to matter.
# reboot device so it starts up with the mochitest profile
# XXX: We could potentially use 'stop b2g' + 'start b2g' to achieve
# a similar effect; will see which is more stable while attempting
# to bring up the continuous integration.
if not self._is_emulator:
self.rebootDevice()
time.sleep(5)
#wait for wlan to come up
if not self.waitForNet():
raise Exception("network did not come up, please configure the network" +
" prior to running before running the automation framework")
# stop b2g
self._devicemanager._runCmd(['shell', 'stop', 'b2g'])
time.sleep(5)
# For some reason user.js in the profile doesn't get picked up.
# Manually copy it over to prefs.js. See bug 1009730 for more details.
self._devicemanager.moveTree(posixpath.join(self._remoteProfile, 'user.js'),
posixpath.join(self._remoteProfile, 'prefs.js'))
# relaunch b2g inside b2g instance
instance = self.B2GInstance(self._devicemanager, env=env)
time.sleep(5)
# Set up port forwarding again for Marionette, since any that
# existed previously got wiped out by the reboot.
if not self._is_emulator:
self._devicemanager._checkCmd(['forward',
'tcp:%s' % self.marionette.port,
'tcp:%s' % self.marionette.port])
if self._is_emulator:
self.marionette.emulator.wait_for_port(self.marionette.port)
else:
time.sleep(5)
# start a marionette session
session = self.marionette.start_session()
if 'b2g' not in session:
raise Exception("bad session value %s returned by start_session" % session)
with self.marionette.using_context(self.marionette.CONTEXT_CHROME):
self.marionette.execute_script("""
let SECURITY_PREF = "security.turn_off_all_security_so_that_viruses_can_take_over_this_computer";
Components.utils.import("resource://gre/modules/Services.jsm");
Services.prefs.setBoolPref(SECURITY_PREF, true);
if (!testUtils.hasOwnProperty("specialPowersObserver")) {
let loader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
.getService(Components.interfaces.mozIJSSubScriptLoader);
loader.loadSubScript("chrome://specialpowers/content/SpecialPowersObserver.jsm",
testUtils);
testUtils.specialPowersObserver = new testUtils.SpecialPowersObserver();
testUtils.specialPowersObserver.init();
}
""")
# run the script that starts the tests
if self.test_script:
if os.path.isfile(self.test_script):
script = open(self.test_script, 'r')
self.marionette.execute_script(script.read(), script_args=self.test_script_args)
script.close()
elif isinstance(self.test_script, basestring):
self.marionette.execute_script(self.test_script, script_args=self.test_script_args)
else:
# assumes the tests are started on startup automatically
pass
return instance
# be careful here as this inner class doesn't have access to outer class members
class B2GInstance(object):
"""Represents a B2G instance running on a device, and exposes
some process-like methods/properties that are expected by the
automation.
"""
def __init__(self, dm, env=None):
self.dm = dm
self.env = env or {}
self.stdout_proc = None
self.queue = Queue.Queue()
# Launch b2g in a separate thread, and dump all output lines
# into a queue. The lines in this queue are
# retrieved and returned by accessing the stdout property of
# this class.
cmd = [self.dm._adbPath]
if self.dm._deviceSerial:
cmd.extend(['-s', self.dm._deviceSerial])
cmd.append('shell')
for k, v in self.env.iteritems():
cmd.append("%s=%s" % (k, v))
cmd.append('/system/bin/b2g.sh')
proc = threading.Thread(target=self._save_stdout_proc, args=(cmd, self.queue))
proc.daemon = True
proc.start()
def _save_stdout_proc(self, cmd, queue):
self.stdout_proc = StdOutProc(cmd, queue)
self.stdout_proc.run()
if hasattr(self.stdout_proc, 'processOutput'):
self.stdout_proc.processOutput()
self.stdout_proc.wait()
self.stdout_proc = None
@property
def pid(self):
# a dummy value to make the automation happy
return 0
def getStdoutLines(self, timeout):
# Return any lines in the queue used by the
# b2g process handler.
lines = []
# get all of the lines that are currently available
while True:
try:
lines.append(self.queue.get_nowait())
except Queue.Empty:
break
# wait 'timeout' for any additional lines
if not lines:
try:
lines.append(self.queue.get(True, timeout))
except Queue.Empty:
pass
return lines
def wait(self, timeout=None):
# this should never happen
raise Exception("'wait' called on B2GInstance")
def kill(self):
# this should never happen
raise Exception("'kill' called on B2GInstance")
-401
View File
@@ -1,401 +0,0 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
import datetime
import glob
import time
import re
import os
import posixpath
import tempfile
import shutil
import subprocess
import sys
from automation import Automation
from mozdevice import DMError, DeviceManager
from mozlog import get_default_logger
import mozcrash
# signatures for logcat messages that we don't care about much
fennecLogcatFilters = [ "The character encoding of the HTML document was not declared",
"Use of Mutation Events is deprecated. Use MutationObserver instead.",
"Unexpected value from nativeGetEnabledTags: 0" ]
class RemoteAutomation(Automation):
_devicemanager = None
# Part of a hack for Robocop: "am COMMAND" is handled specially if COMMAND
# is in this set. See usages below.
_specialAmCommands = ('instrument', 'start')
def __init__(self, deviceManager, appName = '', remoteLog = None,
processArgs=None):
self._devicemanager = deviceManager
self._appName = appName
self._remoteProfile = None
self._remoteLog = remoteLog
self._processArgs = processArgs or {};
# Default our product to fennec
self._product = "fennec"
self.lastTestSeen = "remoteautomation.py"
Automation.__init__(self)
def setDeviceManager(self, deviceManager):
self._devicemanager = deviceManager
def setAppName(self, appName):
self._appName = appName
def setRemoteProfile(self, remoteProfile):
self._remoteProfile = remoteProfile
def setProduct(self, product):
self._product = product
def setRemoteLog(self, logfile):
self._remoteLog = logfile
# Set up what we need for the remote environment
def environment(self, env=None, xrePath=None, crashreporter=True, debugger=False, dmdPath=None, lsanPath=None):
# Because we are running remote, we don't want to mimic the local env
# so no copying of os.environ
if env is None:
env = {}
if dmdPath:
env['MOZ_REPLACE_MALLOC_LIB'] = os.path.join(dmdPath, 'libdmd.so')
# Except for the mochitest results table hiding option, which isn't
# passed to runtestsremote.py as an actual option, but through the
# MOZ_HIDE_RESULTS_TABLE environment variable.
if 'MOZ_HIDE_RESULTS_TABLE' in os.environ:
env['MOZ_HIDE_RESULTS_TABLE'] = os.environ['MOZ_HIDE_RESULTS_TABLE']
env['MOZ_CRASHREPORTER_DISABLE'] = '1'
# Crash on non-local network connections by default.
# MOZ_DISABLE_NONLOCAL_CONNECTIONS can be set to "0" to temporarily
# enable non-local connections for the purposes of local testing.
# Don't override the user's choice here. See bug 1049688.
env.setdefault('MOZ_DISABLE_NONLOCAL_CONNECTIONS', '1')
# Send an env var noting that we are in automation. Passing any
# value except the empty string will declare the value to exist.
#
# This may be used to disabled network connections during testing, e.g.
# Switchboard & telemetry uploads.
env.setdefault('MOZ_IN_AUTOMATION', '1')
# Set WebRTC logging in case it is not set yet.
# On Android, environment variables cannot contain ',' so the
# standard WebRTC setting for NSPR_LOG_MODULES is not available.
# env.setdefault('NSPR_LOG_MODULES', 'signaling:5,mtransport:5,datachannel:5,jsep:5,MediaPipelineFactory:5')
env.setdefault('R_LOG_LEVEL', '6')
env.setdefault('R_LOG_DESTINATION', 'stderr')
env.setdefault('R_LOG_VERBOSE', '1')
return env
def waitForFinish(self, proc, utilityPath, timeout, maxTime, startTime, debuggerInfo, symbolsPath, outputHandler=None):
""" Wait for tests to finish.
If maxTime seconds elapse or no output is detected for timeout
seconds, kill the process and fail the test.
"""
# maxTime is used to override the default timeout, we should honor that
status = proc.wait(timeout = maxTime, noOutputTimeout = timeout)
self.lastTestSeen = proc.getLastTestSeen
topActivity = self._devicemanager.getTopActivity()
if topActivity == proc.procName:
proc.kill(True)
if status == 1:
if maxTime:
print "TEST-UNEXPECTED-FAIL | %s | application ran for longer than " \
"allowed maximum time of %s seconds" % (self.lastTestSeen, maxTime)
else:
print "TEST-UNEXPECTED-FAIL | %s | application ran for longer than " \
"allowed maximum time" % (self.lastTestSeen)
if status == 2:
print "TEST-UNEXPECTED-FAIL | %s | application timed out after %d seconds with no output" \
% (self.lastTestSeen, int(timeout))
return status
def deleteANRs(self):
# empty ANR traces.txt file; usually need root permissions
# we make it empty and writable so we can test the ANR reporter later
traces = "/data/anr/traces.txt"
try:
self._devicemanager.shellCheckOutput(['echo', '', '>', traces], root=True,
timeout=DeviceManager.short_timeout)
self._devicemanager.shellCheckOutput(['chmod', '666', traces], root=True,
timeout=DeviceManager.short_timeout)
except DMError:
print "Error deleting %s" % traces
pass
def checkForANRs(self):
traces = "/data/anr/traces.txt"
if self._devicemanager.fileExists(traces):
try:
t = self._devicemanager.pullFile(traces)
if t:
stripped = t.strip()
if len(stripped) > 0:
print "Contents of %s:" % traces
print t
# Once reported, delete traces
self.deleteANRs()
except DMError:
print "Error pulling %s" % traces
except IOError:
print "Error pulling %s" % traces
else:
print "%s not found" % traces
def deleteTombstones(self):
# delete any existing tombstone files from device
remoteDir = "/data/tombstones"
try:
self._devicemanager.shellCheckOutput(['rm', '-r', remoteDir], root=True,
timeout=DeviceManager.short_timeout)
except DMError:
# This may just indicate that the tombstone directory is missing
pass
def checkForTombstones(self):
# pull any tombstones from device and move to MOZ_UPLOAD_DIR
remoteDir = "/data/tombstones"
blobberUploadDir = os.environ.get('MOZ_UPLOAD_DIR', None)
if blobberUploadDir:
if not os.path.exists(blobberUploadDir):
os.mkdir(blobberUploadDir)
if self._devicemanager.dirExists(remoteDir):
# copy tombstone files from device to local blobber upload directory
try:
self._devicemanager.shellCheckOutput(['chmod', '777', remoteDir], root=True,
timeout=DeviceManager.short_timeout)
self._devicemanager.shellCheckOutput(['chmod', '666', os.path.join(remoteDir, '*')], root=True,
timeout=DeviceManager.short_timeout)
self._devicemanager.getDirectory(remoteDir, blobberUploadDir, False)
except DMError:
# This may just indicate that no tombstone files are present
pass
self.deleteTombstones()
# add a .txt file extension to each tombstone file name, so
# that blobber will upload it
for f in glob.glob(os.path.join(blobberUploadDir, "tombstone_??")):
# add a unique integer to the file name, in case there are
# multiple tombstones generated with the same name, for
# instance, after multiple robocop tests
for i in xrange(1, sys.maxint):
newname = "%s.%d.txt" % (f, i)
if not os.path.exists(newname):
os.rename(f, newname)
break
else:
print "%s does not exist; tombstone check skipped" % remoteDir
else:
print "MOZ_UPLOAD_DIR not defined; tombstone check skipped"
def checkForCrashes(self, directory, symbolsPath):
self.checkForANRs()
self.checkForTombstones()
logcat = self._devicemanager.getLogcat(filterOutRegexps=fennecLogcatFilters)
javaException = mozcrash.check_for_java_exception(logcat, test_name=self.lastTestSeen)
if javaException:
return True
# No crash reporting means we can't say anything.
return False
def buildCommandLine(self, app, debuggerInfo, profileDir, testURL, extraArgs):
# If remote profile is specified, use that instead
if (self._remoteProfile):
profileDir = self._remoteProfile
# Hack for robocop, if app & testURL == None and extraArgs contains the rest of the stuff, lets
# assume extraArgs is all we need
if app == "am" and extraArgs[0] in RemoteAutomation._specialAmCommands:
return app, extraArgs
cmd, args = Automation.buildCommandLine(self, app, debuggerInfo, profileDir, testURL, extraArgs)
# Remove -foreground if it exists, if it doesn't this just returns
try:
args.remove('-foreground')
except:
pass
#TODO: figure out which platform require NO_EM_RESTART
# return app, ['--environ:NO_EM_RESTART=1'] + args
return app, args
def Process(self, cmd, stdout = None, stderr = None, env = None, cwd = None):
if stdout == None or stdout == -1 or stdout == subprocess.PIPE:
stdout = self._remoteLog
return self.RProcess(self._devicemanager, cmd, stdout, stderr, env, cwd, self._appName,
**self._processArgs)
# be careful here as this inner class doesn't have access to outer class members
class RProcess(object):
# device manager process
dm = None
def __init__(self, dm, cmd, stdout=None, stderr=None, env=None, cwd=None, app=None,
messageLogger=None):
self.dm = dm
self.stdoutlen = 0
self.lastTestSeen = "remoteautomation.py"
self.proc = dm.launchProcess(cmd, stdout, cwd, env, True)
self.messageLogger = messageLogger
if (self.proc is None):
if cmd[0] == 'am':
self.proc = stdout
else:
raise Exception("unable to launch process")
self.procName = cmd[0].split('/')[-1]
if cmd[0] == 'am' and cmd[1] in RemoteAutomation._specialAmCommands:
self.procName = app
# Setting timeout at 1 hour since on a remote device this takes much longer.
# Temporarily increased to 90 minutes because no more chunks can be created.
self.timeout = 5400
# The benefit of the following sleep is unclear; it was formerly 15 seconds
time.sleep(1)
# Used to buffer log messages until we meet a line break
self.logBuffer = ""
@property
def pid(self):
pid = self.dm.processExist(self.procName)
# HACK: we should probably be more sophisticated about monitoring
# running processes for the remote case, but for now we'll assume
# that this method can be called when nothing exists and it is not
# an error
if pid is None:
return 0
return pid
def read_stdout(self):
"""
Fetch the full remote log file using devicemanager, process them and
return whether there were any new log entries since the last call.
"""
if not self.dm.fileExists(self.proc):
return False
try:
newLogContent = self.dm.pullFile(self.proc, self.stdoutlen)
except DMError:
# we currently don't retry properly in the pullFile
# function in dmSUT, so an error here is not necessarily
# the end of the world
return False
if not newLogContent:
return False
self.stdoutlen += len(newLogContent)
if self.messageLogger is None:
testStartFilenames = re.findall(r"TEST-START \| ([^\s]*)", newLogContent)
if testStartFilenames:
self.lastTestSeen = testStartFilenames[-1]
print newLogContent
return True
self.logBuffer += newLogContent
lines = self.logBuffer.split('\n')
lines = [l for l in lines if l]
if lines:
if self.logBuffer.endswith('\n'):
# all lines are complete; no need to buffer
self.logBuffer = ""
else:
# keep the last (unfinished) line in the buffer
self.logBuffer = lines[-1]
del lines[-1]
if not lines:
return False
for line in lines:
# This passes the line to the logger (to be logged or buffered)
parsed_messages = self.messageLogger.write(line)
for message in parsed_messages:
if isinstance(message, dict) and message.get('action') == 'test_start':
self.lastTestSeen = message['test']
return True
@property
def getLastTestSeen(self):
return self.lastTestSeen
# Wait for the remote process to end (or for its activity to go to background).
# While waiting, periodically retrieve the process output and print it.
# If the process is still running after *timeout* seconds, return 1;
# If the process is still running but no output is received in *noOutputTimeout*
# seconds, return 2;
# Else, once the process exits/goes to background, return 0.
def wait(self, timeout = None, noOutputTimeout = None):
timer = 0
noOutputTimer = 0
interval = 10
if timeout == None:
timeout = self.timeout
status = 0
top = self.procName
slowLog = False
while (top == self.procName):
# Get log updates on each interval, but if it is taking
# too long, only do it every 60 seconds
if (not slowLog) or (timer % 60 == 0):
startRead = datetime.datetime.utcnow()
hasOutput = self.read_stdout()
if (datetime.datetime.utcnow() - startRead) > datetime.timedelta(seconds=5):
slowLog = True
if hasOutput:
noOutputTimer = 0
time.sleep(interval)
timer += interval
noOutputTimer += interval
if (timer > timeout):
status = 1
break
if (noOutputTimeout and noOutputTimer > noOutputTimeout):
status = 2
break
top = self.dm.getTopActivity()
# Flush anything added to stdout during the sleep
self.read_stdout()
return status
def kill(self, stagedShutdown = False):
if stagedShutdown:
# Trigger an ANR report with "kill -3" (SIGQUIT)
self.dm.killProcess(self.procName, 3)
time.sleep(3)
# Trigger a breakpad dump with "kill -6" (SIGABRT)
self.dm.killProcess(self.procName, 6)
# Wait for process to end
retries = 0
while retries < 3:
pid = self.dm.processExist(self.procName)
if pid and pid > 0:
print "%s still alive after SIGABRT: waiting..." % self.procName
time.sleep(5)
else:
return
retries += 1
self.dm.killProcess(self.procName, 9)
pid = self.dm.processExist(self.procName)
if pid and pid > 0:
self.dm.killProcess(self.procName)
else:
self.dm.killProcess(self.procName)
+1 -1
View File
@@ -15,7 +15,7 @@ ifndef JS_STANDALONE
include $(topsrcdir)/toolkit/mozapps/installer/package-name.mk
include $(topsrcdir)/toolkit/mozapps/installer/upload-files.mk
# Clear out DIST_FILES if it was set by upload-files.mk (for Android builds)
# Clear out DIST_FILES if it was set
DIST_FILES =
endif
+1 -7
View File
@@ -3,9 +3,6 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
with Files('**'):
BUG_COMPONENT = ('Core', 'Build Config')
# This cannot be named "build" because of bug 922191.
SPHINX_TREES['buildsystem'] = 'docs'
@@ -14,9 +11,6 @@ if CONFIG['OS_ARCH'] == 'WINNT':
else:
DIRS += ['unix']
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android':
DIRS += ['annotationProcessors']
for var in ('GRE_MILESTONE',
'MOZ_APP_VERSION',
'MOZ_APP_BASENAME',
@@ -70,7 +64,7 @@ if CONFIG['MOZ_ASAN'] and CONFIG['CLANG_CL']:
if CONFIG['MOZ_APP_BASENAME']:
FINAL_TARGET_PP_FILES += ['application.ini']
if CONFIG['MOZ_WIDGET_TOOLKIT'] != 'android' and CONFIG['MOZ_UPDATER']:
if CONFIG['MOZ_UPDATER']:
FINAL_TARGET_PP_FILES += ['update-settings.ini']
if CONFIG['MOZ_APP_STATIC_INI']:
-149
View File
@@ -1,149 +0,0 @@
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
js_option('--with-android-ndk', nargs=1,
help='location where the Android NDK can be found')
js_option('--with-android-toolchain', nargs=1,
help='location of the Android toolchain')
js_option('--with-android-gnu-compiler-version', nargs=1,
help='GNU compiler version to use')
min_android_version = dependable(lambda: '9')
js_option('--with-android-version',
nargs=1,
help='android platform version',
default=min_android_version)
@depends('--with-android-version', min_android_version)
@imports(_from='__builtin__', _import='ValueError')
def android_version(value, min_version):
if not value:
# Someone has passed --without-android-version.
die('--with-android-version cannot be disabled.')
try:
version = int(value[0])
except ValueError:
die('--with-android-version expects an integer value')
if version < int(min_version):
die('--with-android-version must be at least %s (got %s)',
min_version, value[0])
return version
add_old_configure_assignment('android_version', android_version)
@depends('--with-android-ndk', build_project)
def ndk(value, build_project):
if build_project == 'mobile/android' and not value:
die('You must specify --with-android-ndk=/path/to/ndk when '
'building mobile/android')
if value:
return value[0]
set_config('ANDROID_NDK', ndk)
add_old_configure_assignment('android_ndk', ndk)
@depends(target, android_version, ndk)
@checking('for android platform directory')
@imports(_from='os.path', _import='isdir')
def android_platform(target, android_version, ndk):
if target.os != 'Android':
return
if 'mips' in target.cpu:
target_dir_name = 'mips'
elif 'aarch64' == target.cpu:
target_dir_name = 'arm64'
else:
target_dir_name = target.cpu
# Not all Android releases have their own platform release. We use
# the next lower platform version in these cases.
if android_version in (11, 10):
platform_version = 9
elif android_version in (20, 22):
platform_version = android_version - 1
else:
platform_version = android_version
platform_dir = os.path.join(ndk,
'platforms',
'android-%s' % platform_version,
'arch-%s' % target_dir_name)
if not isdir(platform_dir):
die("Android platform directory not found. With the current "
"configuration, it should be in %s" % platform_dir)
return platform_dir
add_old_configure_assignment('android_platform', android_platform)
@depends(android_platform)
def extra_toolchain_flags(platform_dir):
if not platform_dir:
return []
return ['-idirafter',
os.path.join(platform_dir, 'usr', 'include')]
@depends(target, host, ndk, '--with-android-toolchain',
'--with-android-gnu-compiler-version')
@checking('for the Android toolchain directory', lambda x: x or 'not found')
@imports(_from='os.path', _import='isdir')
@imports(_from='mozbuild.shellutil', _import='quote')
def android_toolchain(target, host, ndk, toolchain, gnu_compiler_version):
if not ndk:
return
if toolchain:
return toolchain[0]
else:
if target.cpu == 'arm' and target.endianness == 'little':
target_base = 'arm-linux-androideabi'
elif target.cpu == 'x86':
target_base = 'x86'
elif target.cpu == 'mips32' and target.endianness == 'little':
target_base = 'mipsel-linux-android'
elif target.cpu == 'aarch64' and target.endianness == 'little':
target_base = 'aarch64-linux-android'
else:
die('Target cpu is not supported.')
toolchain_format = '%s/toolchains/%s-%s/prebuilt/%s-%s'
for version in gnu_compiler_version or ['4.9', '4.8', '4.7']:
toolchain = toolchain_format % (ndk, target_base, version,
host.kernel.lower(), host.cpu)
log.debug('Trying %s' % quote(toolchain))
if not isdir(toolchain) and host.cpu == 'x86_64':
toolchain = toolchain_format % (ndk, target_base, version,
host.kernel.lower(), 'x86')
log.debug('Trying %s' % quote(toolchain))
if isdir(toolchain):
return toolchain
else:
if gnu_compiler_version:
die('Your --with-android-gnu-compiler-version may be wrong')
die('You have to specify --with-android-toolchain='
'/path/to/ndk/toolchain.')
set_config('ANDROID_TOOLCHAIN', android_toolchain)
@depends(target, android_toolchain)
def android_toolchain_prefix(target, toolchain):
if toolchain:
if target.cpu == 'x86':
# Ideally, the --target should just have the right x86 variant
# in the first place.
return '%s/bin/i686-linux-android-' % toolchain
return '%s/bin/%s-' % (toolchain, target.toolchain)
imply_option('--with-toolchain-prefix', android_toolchain_prefix,
reason='--with-android-ndk')
Loaded 100 of 3160 files, more files were not shown because too many files have changed in this diff. Show more