Compare commits

...

226 Commits

Author SHA1 Message Date
Electron Bot
024cb4afd9 Bump v3.1.11 2019-06-06 10:15:16 -07:00
Milan Burda
516233c0da fix: emit IPC event in correct context if isolation and sandbox enabled (#16352) (#18668)
* fix: emit IPC event in correct context if isolation and sandbox enabled

IPC events were not being delivered to renderer processes when both
`contextIsolation` and `sandbox` were enabled. This is because the
`AtomSandboxedRenderFrameObserver` class was incorrectly using the
`MainWorldScriptContext`, rather than conditionally selecting the
context based on if isolation was enabled.

Fixes #11922
2019-06-06 12:11:41 -05:00
John Kleinschmidt
93655d67b3 build: move Windows release builds to AppVeyor cloud (#18627)
* build: move Windows release builds to AppVeyor cloud

* Use new env variable for AppVeyor cloud server

(cherry picked from commit ca712150a3)
2019-06-04 12:04:53 -04:00
John Kleinschmidt
363d0dafc5 build: fixes for CI flakes (#18523)
Turns off ELECTRON_ENABLE_LOGGING/ELECTRON_ENABLE_STACK_DUMPING in Windows as they are causing issues.

In Linux, use a newer version of python-dbusmock to resolve dbusmock hanging on dbus_stop
2019-05-30 14:57:10 -04:00
Electron Bot
5da219b14c Bump v3.1.10 2019-05-29 08:40:07 -07:00
Electron Bot
1e12291776 chore: bump libcc (3-1-x) (#18426)
* chore: bump libcc submodule to 55625e1de5d34a815921975f4d5556133b8142af

* chore: bump libcc in DEPS to 55625e1de5d34a815921975f4d5556133b8142af
2019-05-29 08:37:59 -07:00
Electron Bot
14660a2295 Bump v3.1.9 2019-05-01 10:34:43 -07:00
Milan Burda
276ebca24c fix: copy pixels in AddImageSkiaRepFromBuffer (#17843) (#17861) 2019-04-18 08:54:05 -07:00
Roller Bot
7897913161 chore: bump libcc (3-1-x) (#17850)
* chore: bump libcc submodule to 83fd716a064b29c7a314f4e6b3447d8144d99035

* chore: bump libcc in DEPS to 83fd716a064b29c7a314f4e6b3447d8144d99035
2019-04-18 08:37:04 -07:00
trop[bot]
15315ea916 fix: reset the NSUserNotication handle on dismiss (#17820) 2019-04-16 19:41:29 -04:00
Milan Burda
f11ab9dac5 fix: emit process 'loaded' event in sandboxed renderers (#17809) 2019-04-16 16:23:25 -07:00
Shelley Vohr
aaad1edfe9 docs: note desktop audio limitation on macOS (#17816) 2019-04-16 18:52:53 -04:00
Milan Burda
87a71ed1ed fix: report module name when require fails in sandboxed renderers (#17703) 2019-04-12 13:37:53 -04:00
Electron Bot
e84a6860e3 Bump v3.1.8 2019-03-28 13:05:09 -07:00
Brendan Forster
bbf5178d9f chore: bump node to get hotfix https://github.com/electron/node/pull/97 (#17592) 2019-03-28 12:56:40 -07:00
trop[bot]
7b11604435 fix: handle a race condition between preload scripts executing and navigations (#17595)
There is a race condition between DidCreateScriptContext and another
navigation occuring in the main process. If the navigation occurs while
the preload script is running, the same process is re-used.  This
ensures that any pending navigations are completely removed / ignored
when we trigger a new navigation.

Fixes #17576
2019-03-28 12:56:17 -07:00
Electron Bot
95ed048331 Revert "Bump v3.1.8"
This reverts commit 761996ce46.
2019-03-28 09:50:30 -07:00
Electron Bot
761996ce46 Bump v3.1.8 2019-03-28 08:59:09 -07:00
Electron Bot
5797a9d102 Revert "Bump v3.1.8"
This reverts commit 4e5269b076.
2019-03-27 14:22:02 -07:00
Electron Bot
4e5269b076 Bump v3.1.8 2019-03-27 14:00:31 -07:00
Samuel Attard
018fd925f4 chore: update package-lock.json with updated version number 2019-03-27 11:53:42 -07:00
trop[bot]
a4bea62b98 fix: add missing buffer size check in nativeImage (#17569) 2019-03-27 11:35:01 -07:00
Electron Bot
e964d346c5 Bump v3.1.7 2019-03-21 13:05:34 -07:00
Roller Bot
400f0548e5 chore: bump libcc (3-1-x) (#17503)
* chore: bump libcc submodule to bdb1c8e9d2f184ebeb75a25824aca0be27aa879b

* chore: bump libcc in DEPS to bdb1c8e9d2f184ebeb75a25824aca0be27aa879b
2019-03-21 13:02:26 -07:00
Samuel Attard
59b06a0d04 Revert "Bump v3.1.7"
This reverts commit 078d8c1451.
2019-03-21 12:27:33 -07:00
Electron Bot
078d8c1451 Bump v3.1.7 2019-03-20 15:28:15 -07:00
Electron Bot
0541526104 Revert "Bump v3.1.7"
This reverts commit c242974f4a.
2019-03-20 15:26:03 -07:00
Electron Bot
c242974f4a Bump v3.1.7 2019-03-20 14:32:50 -07:00
Electron Bot
1ba66805e8 Revert "Bump v3.1.7"
This reverts commit b34c6425f7.
2019-03-20 14:26:26 -07:00
Electron Bot
b34c6425f7 Bump v3.1.7 2019-03-20 14:19:14 -07:00
Electron Bot
ab1e5fd476 Revert "Bump v3.1.7"
This reverts commit d048024876.
2019-03-20 14:13:17 -07:00
Electron Bot
d048024876 Bump v3.1.7 2019-03-20 13:50:24 -07:00
trop[bot]
fd60283dbc fix: use a more unique identifier for NSUserNotification instances (#17482)
So although apple has it documented that notifications with duplicate identifiers in the same session won't be presented.  They apparently forgot to mention that macOS also non-deterministically and without any errors, logs or warnings will also not present some notifications in future sessions if they have a previously used identifier.

As such, we're going to truly randomize these identifiers so they are
unique between apps and sessions.  The identifier now consists of a
randomly generated UUID and the app bundle id.
2019-03-20 11:19:15 -07:00
trop[bot]
02d357619e fix: don't crash when nativeImage.createFromBuffer() called with invalid buffer (#17372) 2019-03-13 18:21:07 -07:00
trop[bot]
e0519dad72 fix: remove label/image from segment if they are mutated to undefined/null (#17336) 2019-03-11 17:19:57 -07:00
John Kleinschmidt
93eef7dca0 build: move macos release builds to CircleCI (3-1-x) (#17277) 2019-03-11 15:41:20 -04:00
Electron Bot
73158a6419 Bump v3.1.6 2019-03-07 19:15:50 -08:00
Samuel Attard
9e62197713 Revert "Bump v3.1.6"
This reverts commit 1d93989d26.
2019-03-07 19:03:37 -08:00
Electron Bot
1d93989d26 Bump v3.1.6 2019-03-07 16:38:09 -08:00
Roller Bot
94f7cbe1dc chore: bump libcc (3-1-x) (#17273)
* chore: bump libcc submodule to 5ff272e25eb552d8c0e7f07f919ed0bad804500b

* chore: bump libcc in DEPS to 5ff272e25eb552d8c0e7f07f919ed0bad804500b
2019-03-07 16:08:38 -08:00
John Kleinschmidt
d29afb5f49 build: Fix windows test hang (#17271)
* Try to track down test hangs

* Run tests with cmd instead of powershell

* Fix skip condition

* Update libcc to latest

* Turn off verbose logging on tests

* Revert "Update libcc to latest"

This reverts commit 972bbe0f3f.
2019-03-07 14:45:20 -08:00
Electron Bot
60d85d03a4 Bump v3.1.5 2019-03-04 15:05:36 -08:00
Electron Bot
4ff0b8d6b5 Revert "Bump v3.1.5"
This reverts commit b37884cb5e.
2019-03-04 14:58:08 -08:00
Electron Bot
b37884cb5e Bump v3.1.5 2019-03-04 14:53:46 -08:00
trop[bot]
36f7974e18 fix: set cancelId to 1 when defaultId == 0 and no 'cancel' button (#17149) 2019-02-27 10:10:18 -08:00
Electron Bot
08d8c16720 Bump v3.1.4 2019-02-15 11:06:36 -08:00
Michelle Tilley
439e9d61d6 Revert "Bump v3.1.4"
This reverts commit 0082e8083c.
2019-02-15 11:02:31 -08:00
Cheng Zhao
dd4b688b5f Fix memory leak when using webFrame and spell checker (3-1-x) (#16771)
* fix: do not create native api::WebFrame in webFrame

When reloading a page without restarting renderer process (for example
sandbox mode), the blink::WebFrame is not destroyed, but api::WebFrame
is always recreated for the new page context. This leaves a leak of
api::WebFrame.

* fix: remove spell checker when page context is released
2019-02-15 10:22:41 -08:00
Electron Bot
0082e8083c Bump v3.1.4 2019-02-14 15:06:46 -08:00
Roller Bot
b398305cdd chore: bump libcc (3-1-x) (#16971)
* chore: bump libcc submodule to cd7a2326b0668f24b83d568eccab16ee9ba8dc9a

* chore: bump libcc in DEPS to cd7a2326b0668f24b83d568eccab16ee9ba8dc9a
2019-02-14 14:22:00 -08:00
trop[bot]
94a53cdb30 build: ensure that the uploaded symbol path is correct for our symbol server (#16914) 2019-02-13 07:10:54 -10:00
trop[bot]
438a7d8e1e chore: disable get/setLoginItemSettings specs (#16843) 2019-02-08 14:07:29 -08:00
trop[bot]
cdb7eed21d build: ensure index.json is actually valid JSON before uploading (backport: 3-1-x) (#16752)
* build: ensure index.json is actually valid JSON before uploading

* chore: fix py linting for validation of index.json
2019-02-05 15:01:20 -08:00
trop[bot]
98d7b61a4a fix: crash when calling setProgressBar on macOS (backport: 3-1-x) (#16726)
* fix: correctly check whether dock has progress bar

* fix: do not leak memory when setting dockTile
2019-02-05 08:09:08 -08:00
Electron Bot
72ff292302 Bump v3.1.3 2019-01-31 13:13:54 -08:00
Electron Bot
c0c179fad0 Revert "Bump v3.1.3"
This reverts commit b450e51319.
2019-01-31 10:30:40 -08:00
Electron Bot
b450e51319 Bump v3.1.3 2019-01-31 10:02:53 -08:00
Electron Bot
753683ad22 Revert "Bump v3.1.3"
This reverts commit 34a68725a0.
2019-01-31 08:44:50 -08:00
Electron Bot
34a68725a0 Bump v3.1.3 2019-01-31 08:27:26 -08:00
Cheng Zhao
8ab1309215 fix: return pointer instead of pointer's content (#16641) 2019-01-31 20:19:21 +09:00
Charles Kerr
440a3fa6d8 fix: move open handling to web-contents.js (#16628) 2019-01-30 17:12:48 -08:00
trop[bot]
3b61384c26 fix: register accelerator if role has no registerAccelerator (backport: 3-1-x) (#16598)
* fix: register accelerator if role has no registerAccelerator

* ensure roles[role].registerAccelerator is defined
2019-01-29 22:11:47 -08:00
Nitish Sakhawalkar
ce33169b71 fix: correctly destroy spellcheck client (#16526)
* fix: Destroy spellcheck client

* Address review comments
2019-01-29 15:58:59 -08:00
Heilig Benedek
6d5b225ac5 feat: add registerAccelerator flag to allow menu items to optionally skip accelerator registration (backport: 3-1-x) (#15892)
* feat: add registerAccelerator flag to allow menu items to skip registration

* docs: add docs for registerAccelerator
2019-01-29 14:58:45 -08:00
Electron Bot
bb28fa8e8e Bump v3.1.2 2019-01-24 14:46:50 -08:00
trop[bot]
42acbec1c8 fix: prevent double-destroy of window (#16512) 2019-01-24 14:56:11 +01:00
Roller Bot
3c97c90621 chore: bump libcc (3-1-x) (#16516)
* chore: bump libcc submodule to 7ea271f92018b1eeb8e70ec6de8c29f9758a0c05

* chore: bump libcc in DEPS to 7ea271f92018b1eeb8e70ec6de8c29f9758a0c05
2019-01-24 10:42:13 +09:00
trop[bot]
1e27157de2 docs: fix web-request.md listener signatures in electron.d.ts (#16488) 2019-01-22 19:50:57 +01:00
trop[bot]
95c73eebb2 chore: always try to nuke tags (#16452) 2019-01-18 16:34:48 -08:00
Shelley Vohr
03e051cfbb chore: backport cleanup changes to 3-1-x (#16395)
* chore: backport cleanup changes to 3-1-x

* whoops

* minimize diff

* address review comments
2019-01-16 08:01:49 -08:00
Electron Bot
84f3470032 Bump v3.1.1 2019-01-14 14:27:33 -08:00
Michelle Tilley
cbf5274a96 Revert "Bump v3.1.1"
This reverts commit 22a7f57293.
2019-01-14 13:59:40 -08:00
Electron Bot
22a7f57293 Bump v3.1.1 2019-01-14 10:25:33 -08:00
Michelle Tilley
9b6eab1b42 Revert "Bump v3.1.1"
This reverts commit 8733c2d6c6.
2019-01-14 10:20:58 -08:00
Electron Bot
8733c2d6c6 Bump v3.1.1 2019-01-14 09:56:08 -08:00
Shelley Vohr
8f629a2f31 fix: don't register some shortcuts without accessibility (#16276) 2019-01-12 10:30:13 -08:00
Michelle Tilley
ece0487228 Revert "Bump v3.1.1"
This reverts commit edf2938ca5.
2019-01-11 12:57:58 -08:00
Electron Bot
edf2938ca5 Bump v3.1.1 2019-01-11 12:00:33 -08:00
trop[bot]
79e55e5e85 test: allow retries for flaky mas loginitem specs (#16358) 2019-01-11 08:12:04 -08:00
trop[bot]
27bfeb6148 chore: fix tag cleanup (#16354) 2019-01-10 14:11:41 -08:00
Cobinja
55e9c211f8 backport: fix:menubar item fgcolor (3-1-x) (#16222) 2019-01-09 21:43:42 -08:00
Roller Bot
8db09e26b1 chore: bump libcc (3-1-x) (#16331)
* chore: bump libcc submodule to 01b1896f3f91266d757eb4b1d42464bbee3058f7

* chore: bump libcc in DEPS to 01b1896f3f91266d757eb4b1d42464bbee3058f7
2019-01-09 21:42:00 -08:00
trop[bot]
17c00954bd fix: properly determine if WebContents is offscreen in WebContentsDelegate (backport: 3-1-x) (#16341) 2019-01-09 15:14:40 -08:00
trop[bot]
034ea3cdfb Add instructions to get Notifications working on Win 10 Update (#16324)
Fails silently and was frustratingly hard to know why. Hope this save a lot of people some time.
2019-01-08 16:42:21 -05:00
Electron Bot
4913fc81d1 Bump v3.1.0 2019-01-07 09:57:52 -08:00
trop[bot]
846b43d7bd chore: add additional logging for release upload failures (3-1-x) (#16277) 2019-01-04 12:47:18 -08:00
trop[bot]
d644eb4164 docs: Update reference to xcode 8.3.3 (backport: 3-1-x) (#16271)
* Update reference to xcode

* Update to reflect use of 10.12 SDK
2019-01-04 15:42:37 -05:00
Electron Bot
dc4057bb48 Bump v3.1.0-beta.5 2019-01-04 11:55:02 -08:00
Michelle Tilley
c3867ba6d5 Revert "Bump v3.1.0-beta.5"
This reverts commit aa57be70a0.
2019-01-04 11:52:30 -08:00
Electron Bot
aa57be70a0 Bump v3.1.0-beta.5 2019-01-04 11:08:14 -08:00
Michelle Tilley
9d24d28816 Revert "Bump v3.1.0-beta.5"
This reverts commit 75a21678d7.
2019-01-04 11:04:09 -08:00
Electron Bot
75a21678d7 Bump v3.1.0-beta.5 2019-01-04 10:32:49 -08:00
Jeremy Apthorp
7f0056f683 Merge pull request #16140 from electron/http_auth_prefs_3_1_x
fix: UAF with http auth preferences (3-1-x)
2018-12-20 15:56:28 -08:00
Jeremy Apthorp
02eeef4dc0 fix: ensure that file descriptors 0/1/2 are opened at startup (backport: 3-0-x) (backport: 3-1-x) (#16167)
This fixes an issue where the gpu subprocess was writing messages to a
random pipe or socket. The standard file desciptors are closed in
chromium's subprocesses because of an unfortunate interaction with
libuv's tty handling code leaving them with the FD_CLOEXEC flag.
2018-12-20 15:47:35 -08:00
Andrzej Szombierski
7d8c59deda style: fix lint warnings 2018-12-20 23:00:41 +00:00
Andrzej Szombierski
1e9a75d9f2 fix: ensure that file descriptors 0/1/2 are opened at startup
This fixes an issue where the gpu subprocess was writing messages to a
random pipe or socket. The standard file desciptors are closed in
chromium's subprocesses because of an unfortunate interaction with
libuv's tty handling code leaving them with the FD_CLOEXEC flag.
2018-12-20 23:00:41 +00:00
deepak1556
e7688723f9 fix: UAF with http auth preferences (3-1-x) 2018-12-21 02:40:49 +05:30
trop[bot]
6fb569cc6c fix: extending tracing startRecording API to take a full tracing config (#16159)
This allows memory-infra to be traced correctly.
Fixes #12506.
2018-12-20 08:27:47 -07:00
trop[bot]
349f10d779 chore: release.id => release.data.id (#16134) 2018-12-18 19:53:43 -07:00
Electron Bot
9f6bee704f Bump v3.1.0-beta.4 2018-12-17 12:08:13 -08:00
Michelle Tilley
e6668f60c8 Revert "Bump v3.1.0-beta.4"
This reverts commit 409b58525a.
2018-12-17 12:04:16 -08:00
Electron Bot
409b58525a Bump v3.1.0-beta.4 2018-12-17 11:14:36 -08:00
Shelley Vohr
ea83871cf6 chore: correctly capitalize releaseID (#16107) 2018-12-17 11:08:42 -08:00
Michelle Tilley
53ace2e099 Revert "Bump v3.1.0-beta.4"
This reverts commit 38fc10f068.
2018-12-17 11:06:47 -08:00
Electron Bot
38fc10f068 Bump v3.1.0-beta.4 2018-12-17 10:28:11 -08:00
Roller Bot
03b9f0db58 chore: bump libcc (3-1-x) (#16076)
* chore: bump libcc submodule to 29e02cd4c37777734f97d00b5a538d7c7acfa67a

* chore: bump libcc in DEPS to 29e02cd4c37777734f97d00b5a538d7c7acfa67a
2018-12-17 10:00:52 -05:00
Electron Bot
aea44b9227 Bump v3.1.0-beta.3 2018-12-14 13:08:19 -08:00
Robo
eb9e468bcc fix: remove event monitor before destroying window (#16056) 2018-12-13 15:05:19 -08:00
Roller Bot
936d088210 chore: bump libcc (3-1-x) (#16033)
* chore: bump libcc submodule to e856446abf81a7eaa3e2f7884f0ef837228234fc

* chore: bump libcc in DEPS to e856446abf81a7eaa3e2f7884f0ef837228234fc
2018-12-13 02:04:43 +05:30
trop[bot]
9490a9f9ba fix: allow 2 threads for CreateIoCompletionPort on single-core to prevent busy looping (backport: 3-1-x) (#16011)
* allow 2 threads for CreateIoCompletionPort on single-core

* use base::SysInfo::NumberOfProcessors instead of env var

* CHECK that uv_loop_ has not been used before replacing its iocp
2018-12-11 16:11:47 +09:00
trop[bot]
3c4cd3f662 fix: do not print an error for an expected condition (#15991) (#15998) 2018-12-10 13:17:28 -08:00
Shelley Vohr
15f8d15b1b fix: incorrect view ordering for customButtonsOnHover (#15997) 2018-12-10 12:27:38 -08:00
Shelley Vohr
9f472acf80 chore: expose release id for use in cleanup (#15904) 2018-12-04 08:04:18 -08:00
Electron Bot
0043acf70a Bump v3.1.0-beta.2 2018-12-03 18:35:22 -08:00
Roller Bot
e25f8c1a08 chore: bump libcc (3-1-x) (#15937)
* chore: bump libcc submodule to dfad80d80b265e508c4e583dda3f2860b20128b7

* chore: bump libcc in DEPS to dfad80d80b265e508c4e583dda3f2860b20128b7
2018-12-04 13:30:31 +11:00
Electron Bot
e2be247579 Bump v3.1.0-beta.1 2018-12-02 09:56:52 -08:00
Roller Bot
9de5965bb7 chore: bump libcc (3-1-x) (#15913)
* chore: bump libcc submodule to 99d8f691c3d64704304020f68d46113a1993e281

* chore: bump libcc in DEPS to 99d8f691c3d64704304020f68d46113a1993e281
2018-12-02 09:54:14 -08:00
Shelley Vohr
67af030df7 Revert "Bump v3.1.0-beta.1"
This reverts commit f0b47b2541.
2018-11-30 14:33:27 -08:00
Electron Bot
f0b47b2541 Bump v3.1.0-beta.1 2018-11-30 12:17:44 -08:00
Shelley Vohr
97ffaf058f roll libcc deps for 3-1-x 2018-11-30 12:12:44 -08:00
Shelley Vohr
a4a0eff1e7 Revert "Bump v3.1.0-beta.1"
This reverts commit 1ad67754c0.
2018-11-30 12:11:43 -08:00
Electron Bot
1ad67754c0 Bump v3.1.0-beta.1 2018-11-30 11:54:17 -08:00
Shelley Vohr
8408136082 chore: don't generate full release notes for beta.1 2018-11-30 11:49:58 -08:00
Shelley Vohr
56f7359ed3 update package.json version from beta.0 to stable 2018-11-30 11:43:35 -08:00
trop[bot]
5dc15fc5d9 chore: allow bumping stable => beta (#15907) 2018-11-30 11:17:02 -08:00
Shelley Vohr
17481882d0 Revert "Bump v3.1.0-beta.1"
This reverts commit b23b72f9c3.
2018-11-30 09:46:09 -08:00
Electron Bot
b23b72f9c3 Bump v3.1.0-beta.1 2018-11-29 19:38:53 -08:00
John Kleinschmidt
957ac493e6 ci: clean git before building (#15887) 2018-11-29 10:52:05 -08:00
Shelley Vohr
5ddc2fb6e7 Revert "Bump v3.1.0-beta.1"
This reverts commit 5d05f1c72a.
2018-11-28 16:05:18 -08:00
Shelley Vohr
31d5e9bbe1 Revert "chore: bump libcc (3-1-x) (#15858)"
This reverts commit 386e356ed6.
2018-11-28 15:59:48 -08:00
Roller Bot
386e356ed6 chore: bump libcc (3-1-x) (#15858)
* chore: bump libcc submodule to b3212522d71a4637cc3f7208ad04c819255963b4

* chore: bump libcc in DEPS to b3212522d71a4637cc3f7208ad04c819255963b4
2018-11-28 10:29:14 -08:00
Tom Moor
250a09a43f fix: send NSView* as the response to getNativeWindowHandle() instead of a null handle (#15521) (#15803) 2018-11-28 11:00:37 +09:00
Roller Bot
3ed5a24c72 chore: bump libcc (3-1-x) (#15839)
* chore: bump libcc submodule to ccf1e2dd1dd2e12125dbbdb98b2cc51142cd07b9

* chore: bump libcc in DEPS to ccf1e2dd1dd2e12125dbbdb98b2cc51142cd07b9
2018-11-27 13:13:09 -05:00
Electron Bot
5d05f1c72a Bump v3.1.0-beta.1 2018-11-26 20:36:36 -08:00
Samuel Attard
0fa449f5f4 chore: bump version number in electron.gyp (#15848) 2018-11-27 15:29:05 +11:00
Felix Rieseberg
05ffcbdb3b chore: Bump version number (#15846) 2018-11-26 17:31:25 -08:00
Robo
4abf55801f fix: switch to mojo proxy resolver (3-1-x) (#15813) 2018-11-26 15:38:33 -08:00
Shelley Vohr
d5a6bb665b fix: no longer require submenu for services menuitem (#15672) 2018-11-20 13:18:24 -05:00
Electron Bot
4305657858 Bump v3.0.10 2018-11-19 12:40:54 -08:00
Michelle Tilley
e391b7df69 Revert "Bump v3.0.10"
This reverts commit 82e7bd3f22.
2018-11-19 12:19:50 -08:00
Electron Bot
82e7bd3f22 Bump v3.0.10 2018-11-19 11:04:25 -08:00
trop[bot]
eb30cc2ede docs: limits of nativeWindowOpen (#15754) 2018-11-19 10:36:52 -05:00
John Kleinschmidt
d9efaa946b build: include needed bin files for v8_context_snapshot_generator (#15713) 2018-11-14 11:19:01 -08:00
Roller Bot
3f99cf4f1d chore: bump libcc (3-0-x) (#15690)
* chore: bump libcc submodule to d9e39391cfae447a84e276a402342cf8b4b5bcba
* chore: bump libcc in DEPS to d9e39391cfae447a84e276a402342cf8b4b5bcba
2018-11-13 14:37:32 +01:00
Electron Bot
a0a9d9d159 Bump v3.0.9 2018-11-12 19:18:08 -08:00
Samuel Attard
7165fb181d Revert "Bump v3.0.9"
This reverts commit 67cf0eb9b0.
2018-11-13 14:14:50 +11:00
Electron Bot
67cf0eb9b0 Bump v3.0.9 2018-11-12 13:34:43 -08:00
trop[bot]
e9823f07be fix: NSWindow crash happening on macos 10.9 (#15669) 2018-11-11 13:44:06 -05:00
Roller Bot
c272f5fc56 chore: bump libcc (3-0-x) (#15659)
* chore: bump libcc submodule to 7361dbe5ac927be4276ec7da1d3548c4f22343a0

* chore: bump libcc in DEPS to 7361dbe5ac927be4276ec7da1d3548c4f22343a0
2018-11-10 14:20:31 -05:00
Nitish Sakhawalkar
48ebebcafe fix: Linux empty menu model handling (#15605)
* fix: Linux empty menu model handling

* Update root_view.cc
2018-11-08 08:11:15 -08:00
trop[bot]
ae9f4ef425 chore: add simple set/unset loginitem spec (#15600) 2018-11-06 22:08:44 -08:00
Electron Bot
5c14992e43 Bump v3.0.8 2018-11-05 14:36:14 -08:00
trop[bot]
53b871ecbd fix: use NSURL path for receipt url (#15573) 2018-11-05 13:21:40 -08:00
John Kleinschmidt
ec6fe27fca build: add v8_context_generator to mksnapshot zip (3-0-x) (#15505)
* build: add v8_context_generator to mksnapshot

Starting with 3-0-x, in order to use custom snapshots the v8_context_snapshot_generator binary is also needed.
Also, add tests for mksnapshot.

* Actually run verify-mksnapshot
2018-11-05 13:31:33 -04:00
Nitish Sakhawalkar
8566f8712c fix: Empty menu case (#15553) 2018-11-02 12:32:57 -07:00
Alexey Kuzmin
08ec270b90 docs: fix the "second-instance" event handler signature in the docs (#15546) 2018-11-02 22:18:12 +11:00
trop[bot]
b2822ed800 docs: add Size as an option for pageSize in docs for printToPDF (#15525) 2018-11-01 07:16:08 -07:00
Samuel Attard
6bec85f30c chore: publish to the latest tag correctly when releasing old versions (#15515) (#15520)
Manual backport of #15274 to <= 3-0-x
2018-11-01 07:15:32 -07:00
trop[bot]
6d658b319b fix: explicitly set windowsHide to the old node default (#15514)
Notes: fix Electron not being visible when launching in development mode on node v11
2018-11-01 15:37:06 +11:00
Cheng Zhao
5c853b681c Fix missing remote object error when calling remote function created in preload script (3-0-x) (#15445)
* fix: report wrong context error based on contextId

* fix: destroyed remote renderer warning is now async
2018-11-01 08:55:02 +09:00
Electron Bot
7b0959ed2b Bump v3.0.7 2018-10-31 16:11:44 -07:00
trop[bot]
3e8b854975 docs: add return type for subscribeNotification (#15499) 2018-10-31 09:48:33 -07:00
trop[bot]
fd97fcf6f0 doc: clarify menu item properties not available top-level (#15461) 2018-10-29 16:23:58 -07:00
Heilig Benedek
809534dca0 fix: enable FixAltGraph to fix Ctrl+Alt accelerators on Windows (#15378) 2018-10-30 02:33:44 +11:00
Roller Bot
b2763cad9f chore: bump libcc (3-0-x) (#15420)
* chore: bump libcc submodule to d2c3189f30cfb39f888a917671024733fe5cffcc

* chore: bump libcc in DEPS to d2c3189f30cfb39f888a917671024733fe5cffcc
2018-10-29 10:37:37 -04:00
trop[bot]
b6b9966162 fix: use gio as default linux trash impl (backport: 3-0-x) (#15421)
* fix: use gio as default linux trash impl

* doc: add ELECTRON_TRASH env var
2018-10-26 11:10:35 -07:00
trop[bot]
a41e919b95 doc: correct ipcRenderer sendTo windowId param (#15418) 2018-10-26 08:36:29 -07:00
Heilig Benedek
bdda248194 fix: check for shared memory handle validity before closing, remove DebugDumpData call (#15402) 2018-10-26 09:57:03 -05:00
trop[bot]
41e86efda0 fix: folder open not working in devtools (#15396) 2018-10-25 10:01:29 -07:00
trop[bot]
88b1f7d9c8 fix: set NSResizableWindowMask at init time (#15384) 2018-10-25 15:30:16 +09:00
Electron Bot
dcdbc87ef4 Bump v3.0.6 2018-10-24 15:40:18 -07:00
Alexey Kuzmin
9e03783781 chore: bump libcc (3-0-x) (#15374)
Resolves #15344
2018-10-24 22:40:38 +02:00
John Kleinschmidt
8208296143 Make sure node is set in path 2018-10-24 15:21:43 -04:00
Roller Bot
518467cf4c chore: bump libcc in DEPS to 82816abaad3930c3702cf23489f0506ba13b1529 2018-10-24 07:23:09 -07:00
Roller Bot
648bf54bb3 chore: bump libcc submodule to 82816abaad3930c3702cf23489f0506ba13b1529 2018-10-24 07:23:07 -07:00
trop[bot]
8dce40137c fix: honor dialog.showMessageBox()'s Icon argument on Linux (#15342)
* Don't call gtk_widget_show_all() on popup dialog.

Fixes #15317.

Notes: Fixed incorrect display of some GtkMessageDialog icons.

The issue is caused because GtkMessageDialog contains an icon widget
which is not shown when there's no associated icon. Our call to
`gtk_widget_show_all()` overrides this, showing the uninitialized
icon widget.

This PR fixes the issue by calling `gtk_widget_show()` where needed
and removing use of `gtk_widget_show_all()` in the message dialog.

* use gtk_dialog_set_default_response() for default

* fix: support icons on gtk+ messageboxes.
2018-10-23 12:01:05 -07:00
trop[bot]
dab77256d2 fix: Native window close crash (#15338) 2018-10-23 12:00:39 -07:00
trop[bot]
c7501bd7ca fix: correct reversed logic in NativeWindowMac::SetEnabled (#15324) 2018-10-23 23:22:19 +11:00
trop[bot]
203c47f038 docs: we don't emit an event object for session-created (#15308) 2018-10-21 10:18:08 -07:00
Shelley Vohr
02cd96875d fix: ability to fetch separators by id (#15299) 2018-10-19 21:58:07 -07:00
trop[bot]
9349b0a273 fix: correctly enable and disable windows on Windows and Linux (backport: 3-0-x) (#15255)
* fix: correctly enable and disable windows

* Move has_child_modal_ to NativeWindowViews

* Track modal children as an int instead of a bool

* Use correct types

* Move Increment/DecrementChildModals to NativeWindowViews

* Use parent() in NativeWindowViews

* Add test for not enabling disabled parent when modal child closes
2018-10-19 17:30:55 -07:00
trop[bot]
1c42715e1d spec: increase MAS timeout for login items (#15296) 2018-10-19 16:57:00 -07:00
Alexey Kuzmin
ef4a7e22fd test: asyncawaitify one of sandbox related tests (backport: 3-0-x) (#15281)
* test: asyncawaitify one of sandbox related tests (#15252)

(cherry picked from commit b3f134de06)

* test: backport "openTheWindow" function to "BrowserWindow module" specs
2018-10-19 09:14:36 -07:00
trop[bot]
ead294fe13 fix: trim app name and productName (#15286)
Fixes #15245
2018-10-19 09:13:10 -07:00
trop[bot]
f119e4cc4b chore: make macOS release builds higher priority to skip the queue (#15284)
Release builds should be run before branch builds on our limited macOS
infra.

Refs: https://docs.microsoft.com/en-us/rest/api/vsts/build/builds/queue?view=vsts-rest-4.1#queuepriority
2018-10-19 09:12:21 -07:00
trop[bot]
00489e6106 fix: make release-artifact-cleanup executable (backport: 3-0-x) (#15272)
* fix: make release-artifact-cleanup executable

* fix misc issues in cleanup script
2018-10-18 20:27:53 -07:00
trop[bot]
a7c34b8a0a fix: Convert to lower case in upload symbols script (backport: 3-0-x) (#15261)
* fix: Convert to lower case in upload symbols script

* fix: Convert to lower case in upload symbols script
2018-10-18 19:17:15 -07:00
trop[bot]
906436f31b fix: loading of devtools extensions on startup (backport: 3-0-x) (#15264)
* Fix loading of devtools extensions on startup

The persisted DevTools Extensions were not being loaded correctly at startup. The `addDevToolsExtension` function was not defined when it was being called. An error was being thrown and ignored, so the whole thing would fail silently. I moved the code to load the extensions to the end of the event handler, so now it works.

* fixup: remove trailing spaces to unblock CI

* fixup: add logging when the Electron Enable Logging env var is set

* Fix linter error on undefined srcDirectory

* fixup: catch exception when loading extension

* Revert "fixup: catch exception when loading extension"

This reverts commit 42c2cf95bc.
2018-10-18 19:13:01 -07:00
Electron Bot
b208fcbf0d Bump v3.0.5 2018-10-18 17:03:53 -07:00
Samuel Attard
6899ac9bde Revert "Bump v3.0.5"
This reverts commit 72c033299f.
2018-10-18 23:46:35 +11:00
Electron Bot
72c033299f Bump v3.0.5 2018-10-17 22:56:11 -07:00
Samuel Attard
7fb6b3bda8 Revert "build: enable PIE when compiling Linux builds, fix #14961. (#15152)"
This reverts commit 70d4644742.
2018-10-18 14:09:34 +11:00
Samuel Attard
1d79840025 Revert "build: enable BIND_NOW when compiling Linux builds, fix #15149. (#15153)"
This reverts commit 049381c6ac.
2018-10-18 14:09:19 +11:00
Samuel Attard
07deaaa502 Revert "Bump v3.0.5"
This reverts commit 259f0a62e8.
2018-10-18 14:08:56 +11:00
Electron Bot
259f0a62e8 Bump v3.0.5 2018-10-17 19:33:27 -07:00
Samuel Attard
4f78df9cfa Revert "Bump v3.0.5"
This reverts commit b2be093bd3.
2018-10-18 13:26:20 +11:00
Electron Bot
b2be093bd3 Bump v3.0.5 2018-10-17 10:28:20 -07:00
Roller Bot
4f666bb6ac chore: bump libcc (3-0-x) (#15201)
* chore: bump libcc submodule to c110392d8556a6428679328f9075b3f4fb54aa3c

* chore: bump libcc in DEPS to c110392d8556a6428679328f9075b3f4fb54aa3c
2018-10-18 00:54:31 +11:00
trop[bot]
12f75832b8 add width to webview iframe (#15204) 2018-10-17 11:54:43 +09:00
Cheng Zhao
6f54d58e2a Merge pull request #15192 from electron/window-open-warn-leak-3-0-x
chore: warn memory leak when using nativeWindowOpen with nodeIntegration (3-0-x)
2018-10-17 11:54:21 +09:00
Cheng Zhao
8716f718a9 fix: print warning after DOM is created 2018-10-17 10:42:02 +09:00
Cheng Zhao
714f3ffd29 chore: warn memory leak when using nativeWindowOpen with nodeIntegration 2018-10-16 20:12:53 +09:00
Cheng Zhao
4a5d2117ba fix: do not enable node integration in child window if not enabled (#15108) 2018-10-16 18:10:31 +09:00
Nitish Sakhawalkar
5cb50b0e33 fix: Menu accelerators not working Unity (#15181) 2018-10-16 14:46:51 +11:00
Kevin Lynagh
7283b78aa2 fix: simpleFullscreen window should be on top of other OS X menu bars. (#15183)
If an app has no menu bar (because `app.dock.hide()` has been called),
OS X will still render the menu bar of the previously-focused app.

This commit ensures simpleFullscreen windows will be drawn on top of
that menu bar by setting their level to NSPopUpMenuWindowLevel while
simpleFullscreen mode is active.

Ref: #11468
2018-10-16 13:51:14 +11:00
#DeleteGithub
049381c6ac build: enable BIND_NOW when compiling Linux builds, fix #15149. (#15153)
We've hardened Linux builds by enabling PIE and RELRO,
and should continue to try hardening Linux builds by
enabling BIND_NOW. With both RELRO and BIND_NOW enabled,
we can stop all GOT overwrite attacks. The same hardening
option has been enabled in official Chrome/Chromium
builds since more than five years ago.

This helps to improve the security of a whole range of
applications built upon Electron, including sensetive ones
such as Signal-Desktop.

Signed-off-by: Tom Li <tomli@tomli.me>
2018-10-16 11:44:35 +11:00
Andy Dill
22597474e0 fix: preserve background color through reload (backport: 3-0-x) (#15175)
* fix: preserve background color through reload

* fix: only set backgroundColor on top-level frames
2018-10-15 12:56:05 -07:00
trop[bot]
760def6147 fix: Memory > Profiles > Load in DevTools (#15155) 2018-10-14 10:59:04 -07:00
#DeleteGithub
70d4644742 build: enable PIE when compiling Linux builds, fix #14961. (#15152)
PIE allows an application to utilize the full benefits of ASLR
to prevent itself from exploitations, but it was disabled for
all released versions of Electron (3.0 and prior).

Currently, PIE is already enabled since 9294fac but enabling it
for all released version is still an ongoing work (#14961). This
patch backports PIE to the 3.0.x branch.

Signed-off-by: Tom Li <tomli@tomli.me>
2018-10-14 12:47:55 +11:00
Shelley Vohr
f6b7f547bb fix: natively implement LoginItems methods (#15128)
* fix: natively implement LoginItems methods

* fix flaky spec on MAS builds
2018-10-12 20:50:03 -07:00
trop[bot]
9bb3701f7e spec: re-enable app.getAppMetric API (#15123) 2018-10-12 10:30:56 -07:00
trop[bot]
d7fe65b9bd docs: app.getLoginItemStatus -> app.getLoginItemSettings (#15113) 2018-10-13 01:19:23 +11:00
Charles Kerr
eb8546c8d1 fix: check dbus response for null before use. (#15033)
* fix: backport #15030 to fix #14958 dbus crash

* chore: re-enable power spec tests

* chore: undo changes made to power monitor tests.

The Linux failures on that are gone in master / 4-0-x.  Whatever
resolved it there is unrelated to this PR's changes, so I'm not
going to block this fix on an unrelated issue.
2018-10-11 22:40:22 -07:00
Electron Bot
6719f66d5a Bump v3.0.4 2018-10-10 20:51:33 -07:00
Roller Bot
b78fb5aa93 chore: bump libcc (3-0-x) (#15072)
* chore: bump libcc submodule to 42e375e8b0bf4d7e030237adbb9cf7122d9f3246

* chore: bump libcc in DEPS to 42e375e8b0bf4d7e030237adbb9cf7122d9f3246
2018-10-11 14:42:45 +11:00
Shelley Vohr
502b0b988e fix: handle shortcuts by default if no WebPreferences object exists (#15066) 2018-10-11 13:37:55 +11:00
trop[bot]
3d8af9d279 fix: Lifetime of auth_info_ in login handler (#15044) 2018-10-10 12:59:27 +11:00
trop[bot]
524bb99948 fix: Check minSize constraints before resizing (backport: 3-0-x) (#15038) 2018-10-09 10:52:00 -07:00
trop[bot]
8f743e6fbe Backport of #14648 (#15032) 2018-10-09 09:47:29 -04:00
Electron Bot
6c085cda74 Bump v3.0.3 2018-10-06 16:31:11 -07:00
trop[bot]
73935bc5dd fix: support ASAR in fs.copyFile (#14953) 2018-10-04 09:23:19 +10:00
Cheng Zhao
bf928ee443 fix: use white background for non-OSR renderer by default (#14934) 2018-10-03 13:41:37 +09:00
trop[bot]
ee6de82c08 fix: check guest view's devtools window size (#14928) 2018-10-03 09:31:34 +09:00
trop[bot]
8d362150e0 fix: Disable new fade animation for BrowserViews (#14913) 2018-10-02 13:17:36 +10:00
Shelley Vohr
385b08881e fix: roll node deps for fs event patch (#14864) 2018-09-29 09:17:33 +10:00
trop[bot]
5cd24a4e81 fix: enable key accelerator flags for Windows and Linux (backport: 3-0-x) (#14859)
* Fix Accelerator Flags for Windows and Linux

* Lint fix

* Lint whitespace
2018-09-28 10:01:28 -07:00
200 changed files with 4703 additions and 3073 deletions

View File

@@ -1,5 +1,11 @@
build-steps: &build-steps
steps:
- run:
name: Fix Known Hosts on Linux
command: |
if [ "`uname`" == "Linux" ]; then
/home/builduser/fix-known-hosts.sh
fi
- checkout
- run:
name: Install Node.js 10 on MacOS
@@ -8,6 +14,7 @@ build-steps: &build-steps
echo 'Installing Node.js 10 for MacOS'
brew update
brew install node@10
echo 'export PATH="/usr/local/opt/node@10/bin:$PATH"' >> $BASH_ENV
fi
- run:
name: Check for release
@@ -69,6 +76,17 @@ build-steps: &build-steps
else
echo 'Headless testing not needed'
fi
- run:
name: Verify mksnapshot
command: |
if [ "$RUN_TESTS" == "true" ] && [ "$ELECTRON_RELEASE" == "1" ]; then
echo 'Verifying mksnapshot on release build'
script/verify-mksnapshot.py
else
echo 'Skipping mksnapshot tests due to configuration'
fi
- run:
name: Test
environment:
@@ -126,7 +144,7 @@ build-steps: &build-steps
build-defaults: &build-defaults
docker:
- image: electronbuilds/electron:0.0.8
- image: electronbuilds/electron:0.0.8.1
<<: *build-steps
version: 2
@@ -251,6 +269,7 @@ jobs:
TARGET_ARCH: x64
RUN_TESTS: true
INSTALL_MACOS_NODE: true
resource_class: large
macos:
xcode: "8.3.3"
<<: *build-steps
@@ -260,6 +279,7 @@ jobs:
TARGET_ARCH: x64
RUN_RELEASE_BUILD: true
INSTALL_MACOS_NODE: true
resource_class: large
macos:
xcode: "8.3.3"
<<: *build-steps
@@ -270,6 +290,7 @@ jobs:
MAS_BUILD: 1
RUN_TESTS: true
INSTALL_MACOS_NODE: true
resource_class: large
macos:
xcode: "8.3.3"
<<: *build-steps
@@ -280,6 +301,7 @@ jobs:
MAS_BUILD: 1
RUN_RELEASE_BUILD: true
INSTALL_MACOS_NODE: true
resource_class: large
macos:
xcode: "8.3.3"
<<: *build-steps

View File

@@ -0,0 +1,7 @@
#!/bin/bash
set -e
mkdir -p ~/.ssh
echo "|1|cVeiko0f+NcBdQ4UQvusKHo8sOA=|VIYt+cwPlbV0iP9VItsw/wlzrEk= ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==
|1|WDYl7KHWaZFGMa3eqg3iY4KmwzQ=|FWZq//rIJ3lr85ZeTr66c80iLiA= ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==" >> ~/.ssh/known_hosts

View File

@@ -1,3 +1,4 @@
*
!tools/xvfb-init.sh
!tools/run-electron.sh
!.circleci/fix-known-hosts.sh

View File

@@ -1,7 +1,7 @@
# These env vars are only necessary for creating Electron releases.
# See docs/development/releasing.md
APPVEYOR_TOKEN=
APPVEYOR_CLOUD_TOKEN=
CIRCLE_TOKEN=
ELECTRON_GITHUB_TOKEN=
VSTS_TOKEN=

2
DEPS
View File

@@ -2,7 +2,7 @@ vars = {
'chromium_version':
'63.0.3239.150',
'libchromiumcontent_revision':
'ecc87483bace2bce628bf5d02a73514ffa95f4bf',
'55625e1de5d34a815921975f4d5556133b8142af',
'node_version':
'v9.7.0-33-g538a5023af',
'native_mate_revision':

View File

@@ -3,8 +3,7 @@ FROM electronbuilds/libchromiumcontent:0.0.4
USER root
# Set up HOME directory
ENV HOME=/home
RUN chmod a+rwx /home
ENV HOME=/home/builduser
# Install node.js
RUN curl -sL https://deb.nodesource.com/setup_10.x | bash -
@@ -13,8 +12,9 @@ RUN apt-get install -y nodejs
# Install wget used by crash reporter
RUN apt-get install -y wget
# Install python-dbusmock
RUN apt-get install -y python-dbusmock
# Install python-dbus
RUN apt-get install -y python-dbus
RUN pip install python-dbusmock
# Install libnotify
RUN apt-get install -y libnotify-bin
@@ -22,3 +22,9 @@ RUN apt-get install -y libnotify-bin
# Add xvfb init script
ADD tools/xvfb-init.sh /etc/init.d/xvfb
RUN chmod a+x /etc/init.d/xvfb
COPY .circleci/fix-known-hosts.sh /home/builduser/fix-known-hosts.sh
RUN chmod a+x /home/builduser/fix-known-hosts.sh
USER builduser
WORKDIR /home/builduser

View File

@@ -5,7 +5,7 @@ build_script:
echo "Build worker image $env:APPVEYOR_BUILD_WORKER_IMAGE"
&"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe"
if($env:SKIP_GYP_BUILD -eq "true") {
Write-warning "Skipping debug build for older branch"; Exit-AppveyorBuild
} elseif(($env:APPVEYOR_PULL_REQUEST_HEAD_REPO_NAME -split "/")[0] -eq ($env:APPVEYOR_REPO_NAME -split "/")[0]) {
@@ -43,20 +43,13 @@ test_script:
if (Test-Path Env:\ELECTRON_RELEASE) {
Write-Output "Skipping tests for release build"
} else {
$env:RUN_TESTS="true"
Remove-Item Env:\ELECTRON_ENABLE_LOGGING
Remove-Item Env:\ELECTRON_ENABLE_STACK_DUMPING
Write-Output "Running tests for debug build"
python script\test.py --ci --rebuild_native_modules
if ($LASTEXITCODE -ne '0') {
throw "Tests failed with exit code $LASTEXITCODE"
} else {
Write-Output "Tests succeeded."
}
python script\verify-ffmpeg.py
if ($LASTEXITCODE -ne '0') {
throw "Verify ffmpeg failed with exit code $LASTEXITCODE"
} else {
"Verify ffmpeg succeeded."
}
}
- if "%RUN_TESTS%"=="true" ( echo Running test suite & python script\test.py --ci --rebuild_native_modules)
- if "%RUN_TESTS%"=="true" ( echo Running verify ffmpeg & python script\verify-ffmpeg.py)
artifacts:
- path: test-results.xml
name: test-results.xml

View File

@@ -24,10 +24,14 @@
#include "base/win/windows_version.h"
#include "content/public/app/sandbox_helper_win.h"
#include "sandbox/win/src/sandbox_types.h"
#elif defined(OS_LINUX) // defined(OS_WIN)
#elif defined(OS_LINUX) // defined(OS_WIN)
#include <unistd.h>
#include <cstdio>
#include "atom/app/atom_main_delegate.h" // NOLINT
#include "content/public/app/content_main.h"
#else // defined(OS_LINUX)
#include <unistd.h>
#include <cstdio>
#include "atom/app/atom_library_main.h"
#endif // defined(OS_MACOSX)
@@ -55,6 +59,25 @@ bool IsEnvSet(const char* name) {
}
#endif
#if defined(OS_POSIX)
void FixStdioStreams() {
// libuv may mark stdin/stdout/stderr as close-on-exec, which interferes
// with chromium's subprocess spawning. As a workaround, we detect if these
// streams are closed on startup, and reopen them as /dev/null if necessary.
// Otherwise, an unrelated file descriptor will be assigned as stdout/stderr
// which may cause various errors when attempting to write to them.
//
// For details see https://github.com/libuv/libuv/issues/2062
struct stat st;
if (fstat(STDIN_FILENO, &st) < 0 && errno == EBADF)
freopen("/dev/null", "r", stdin);
if (fstat(STDOUT_FILENO, &st) < 0 && errno == EBADF)
freopen("/dev/null", "w", stdout);
if (fstat(STDERR_FILENO, &st) < 0 && errno == EBADF)
freopen("/dev/null", "w", stderr);
}
#endif
} // namespace
#if defined(OS_WIN)
@@ -157,6 +180,8 @@ int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE, wchar_t* cmd, int) {
int main(int argc, char* argv[]) {
#ifdef ENABLE_RUN_AS_NODE
FixStdioStreams();
if (IsEnvSet(kRunAsNode)) {
base::i18n::InitializeICU();
base::AtExitManager atexit_manager;
@@ -176,6 +201,8 @@ int main(int argc, char* argv[]) {
int main(int argc, char* argv[]) {
#ifdef ENABLE_RUN_AS_NODE
FixStdioStreams();
if (IsEnvSet(kRunAsNode)) {
return AtomInitializeICUandStartNode(argc, argv);
}

View File

@@ -183,7 +183,14 @@ bool BrowserWindow::OnMessageReceived(const IPC::Message& message,
}
void BrowserWindow::OnCloseContents() {
DCHECK(web_contents());
// On some machines it may happen that the window gets destroyed for twice,
// checking web_contents() can effectively guard against that.
// https://github.com/electron/electron/issues/16202.
//
// TODO(zcbenz): We should find out the root cause and improve the closing
// procedure of BrowserWindow.
if (!web_contents())
return;
// Close all child windows before closing current window.
v8::Locker locker(isolate());

View File

@@ -63,7 +63,12 @@ void BrowserWindow::OverrideNSWindowContentView(
NSView* webView = iwc->GetView()->GetNativeView();
NSView* contentView = [window()->GetNativeWindow() contentView];
[webView setFrame:[contentView bounds]];
[contentView addSubview:webView];
// ensure that buttons view is floated to top of view hierarchy
NSArray* subviews = [contentView subviews];
NSView* last = subviews.lastObject;
[contentView addSubview:webView positioned:NSWindowBelow relativeTo:last];
[contentView viewDidMoveToWindow];
}

View File

@@ -7,6 +7,7 @@
#include "atom/common/native_mate_converters/callback.h"
#include "atom/common/native_mate_converters/file_path_converter.h"
#include "atom/common/native_mate_converters/value_converter.h"
#include "base/bind.h"
#include "base/files/file_util.h"
#include "content/public/browser/tracing_controller.h"
@@ -23,15 +24,27 @@ struct Converter<base::trace_event::TraceConfig> {
static bool FromV8(v8::Isolate* isolate,
v8::Local<v8::Value> val,
base::trace_event::TraceConfig* out) {
// (alexeykuzmin): A combination of "categoryFilter" and "traceOptions"
// has to be checked first because none of the fields
// in the `memory_dump_config` dict below are mandatory
// and we cannot check the config format.
Dictionary options;
if (!ConvertFromV8(isolate, val, &options))
return false;
std::string category_filter, trace_options;
if (!options.Get("categoryFilter", &category_filter) ||
!options.Get("traceOptions", &trace_options))
return false;
*out = base::trace_event::TraceConfig(category_filter, trace_options);
return true;
if (ConvertFromV8(isolate, val, &options)) {
std::string category_filter, trace_options;
if (options.Get("categoryFilter", &category_filter) &&
options.Get("traceOptions", &trace_options)) {
*out = base::trace_event::TraceConfig(category_filter, trace_options);
return true;
}
}
base::DictionaryValue memory_dump_config;
if (ConvertFromV8(isolate, val, &memory_dump_config)) {
*out = base::trace_event::TraceConfig(memory_dump_config);
return true;
}
return false;
}
};

View File

@@ -5,7 +5,7 @@
#include "atom/browser/api/atom_api_cookies.h"
#include "atom/browser/atom_browser_context.h"
#include "atom/browser/request_context_delegate.h"
#include "atom/browser/cookie_change_notifier.h"
#include "atom/common/native_mate_converters/callback.h"
#include "atom/common/native_mate_converters/gurl_converter.h"
#include "atom/common/native_mate_converters/value_converter.h"
@@ -56,20 +56,21 @@ struct Converter<net::CanonicalCookie> {
};
template <>
struct Converter<net::CookieChangeCause> {
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
const net::CookieChangeCause& val) {
struct Converter<network::mojom::CookieChangeCause> {
static v8::Local<v8::Value> ToV8(
v8::Isolate* isolate,
const network::mojom::CookieChangeCause& val) {
switch (val) {
case net::CookieChangeCause::INSERTED:
case net::CookieChangeCause::EXPLICIT:
case network::mojom::CookieChangeCause::INSERTED:
case network::mojom::CookieChangeCause::EXPLICIT:
return mate::StringToV8(isolate, "explicit");
case net::CookieChangeCause::OVERWRITE:
case network::mojom::CookieChangeCause::OVERWRITE:
return mate::StringToV8(isolate, "overwrite");
case net::CookieChangeCause::EXPIRED:
case network::mojom::CookieChangeCause::EXPIRED:
return mate::StringToV8(isolate, "expired");
case net::CookieChangeCause::EVICTED:
case network::mojom::CookieChangeCause::EVICTED:
return mate::StringToV8(isolate, "evicted");
case net::CookieChangeCause::EXPIRED_OVERWRITE:
case network::mojom::CookieChangeCause::EXPIRED_OVERWRITE:
return mate::StringToV8(isolate, "expired-overwrite");
default:
return mate::StringToV8(isolate, "unknown");
@@ -255,9 +256,8 @@ Cookies::Cookies(v8::Isolate* isolate, AtomBrowserContext* browser_context)
: browser_context_(browser_context) {
Init(isolate);
cookie_change_subscription_ =
browser_context->GetRequestContextDelegate()
->RegisterCookieChangeCallback(
base::Bind(&Cookies::OnCookieChanged, base::Unretained(this)));
browser_context_->cookie_change_notifier()->RegisterCookieChangeCallback(
base::Bind(&Cookies::OnCookieChanged, base::Unretained(this)));
}
Cookies::~Cookies() {}

View File

@@ -55,7 +55,7 @@ class Cookies : public mate::TrackableObject<Cookies> {
void Set(const base::DictionaryValue& details, const SetCallback& callback);
void FlushStore(const base::Closure& callback);
// AtomBrowserContext::RegisterCookieChangeCallback subscription:
// CookieChangeNotifier subscription:
void OnCookieChanged(const CookieDetails*);
private:

View File

@@ -6,15 +6,45 @@
#include <string>
#include "atom/browser/api/atom_api_system_preferences.h"
#include "atom/common/native_mate_converters/accelerator_converter.h"
#include "atom/common/native_mate_converters/callback.h"
#include "base/stl_util.h"
#include "base/strings/utf_string_conversions.h"
#include "native_mate/dictionary.h"
#include "atom/common/node_includes.h"
#include "atom/common/platform_util.h"
#if defined(OS_MACOSX)
#include "base/mac/mac_util.h"
#endif
using extensions::GlobalShortcutListener;
namespace {
#if defined(OS_MACOSX)
bool RegisteringMediaKeyForUntrustedClient(const ui::Accelerator& accelerator) {
if (platform_util::IsAtLeastOS10_14()) {
constexpr ui::KeyboardCode mediaKeys[] = {
ui::VKEY_MEDIA_PLAY_PAUSE, ui::VKEY_MEDIA_NEXT_TRACK,
ui::VKEY_MEDIA_PREV_TRACK, ui::VKEY_MEDIA_STOP};
if (std::find(std::begin(mediaKeys), std::end(mediaKeys),
accelerator.key_code()) != std::end(mediaKeys)) {
bool trusted =
atom::api::SystemPreferences::IsTrustedAccessibilityClient(false);
if (!trusted)
return true;
}
}
return false;
}
#endif
} // namespace
namespace atom {
namespace api {
@@ -31,7 +61,7 @@ void GlobalShortcut::OnKeyPressed(const ui::Accelerator& accelerator) {
if (accelerator_callback_map_.find(accelerator) ==
accelerator_callback_map_.end()) {
// This should never occur, because if it does, GlobalGlobalShortcutListener
// notifes us with wrong accelerator.
// notifies us with wrong accelerator.
NOTREACHED();
return;
}
@@ -40,6 +70,11 @@ void GlobalShortcut::OnKeyPressed(const ui::Accelerator& accelerator) {
bool GlobalShortcut::Register(const ui::Accelerator& accelerator,
const base::Closure& callback) {
#if defined(OS_MACOSX)
if (RegisteringMediaKeyForUntrustedClient(accelerator))
return false;
#endif
if (!GlobalShortcutListener::GetInstance()->RegisterAccelerator(accelerator,
this)) {
return false;

View File

@@ -41,6 +41,8 @@ void Menu::AfterInit(v8::Isolate* isolate) {
delegate.Get("isCommandIdEnabled", &is_enabled_);
delegate.Get("isCommandIdVisible", &is_visible_);
delegate.Get("getAcceleratorForCommandId", &get_accelerator_);
delegate.Get("shouldRegisterAcceleratorForCommandId",
&should_register_accelerator_);
delegate.Get("executeCommand", &execute_command_);
delegate.Get("menuWillShow", &menu_will_show_);
}
@@ -74,6 +76,12 @@ bool Menu::GetAcceleratorForCommandIdWithParams(
return mate::ConvertFromV8(isolate(), val, accelerator);
}
bool Menu::ShouldRegisterAcceleratorForCommandId(int command_id) const {
v8::Locker locker(isolate());
v8::HandleScope handle_scope(isolate());
return should_register_accelerator_.Run(GetWrapper(), command_id);
}
void Menu::ExecuteCommand(int command_id, int flags) {
v8::Locker locker(isolate());
v8::HandleScope handle_scope(isolate());

View File

@@ -51,6 +51,7 @@ class Menu : public mate::TrackableObject<Menu>,
int command_id,
bool use_default_accelerator,
ui::Accelerator* accelerator) const override;
bool ShouldRegisterAcceleratorForCommandId(int command_id) const override;
void ExecuteCommand(int command_id, int event_flags) override;
void MenuWillShow(ui::SimpleMenuModel* source) override;
@@ -101,6 +102,7 @@ class Menu : public mate::TrackableObject<Menu>,
base::Callback<bool(v8::Local<v8::Value>, int)> is_visible_;
base::Callback<v8::Local<v8::Value>(v8::Local<v8::Value>, int, bool)>
get_accelerator_;
base::Callback<bool(v8::Local<v8::Value>, int)> should_register_accelerator_;
base::Callback<void(v8::Local<v8::Value>, v8::Local<v8::Value>, int)>
execute_command_;
base::Callback<void(v8::Local<v8::Value>)> menu_will_show_;

View File

@@ -3,13 +3,19 @@
// found in the LICENSE file.
#include "atom/browser/api/atom_api_net_log.h"
#include "atom/browser/atom_browser_client.h"
#include <utility>
#include "atom/browser/atom_browser_context.h"
#include "atom/browser/atom_browser_main_parts.h"
#include "atom/common/native_mate_converters/callback.h"
#include "atom/common/native_mate_converters/file_path_converter.h"
#include "base/callback.h"
#include "content/public/common/content_switches.h"
#include "base/command_line.h"
#include "components/net_log/chrome_net_log.h"
#include "content/public/browser/storage_partition.h"
#include "native_mate/dictionary.h"
#include "native_mate/handle.h"
#include "net/url_request/url_request_context_getter.h"
#include "atom/common/node_includes.h"
@@ -17,17 +23,17 @@ namespace atom {
namespace api {
NetLog::NetLog(v8::Isolate* isolate) {
NetLog::NetLog(v8::Isolate* isolate, AtomBrowserContext* browser_context)
: browser_context_(browser_context) {
Init(isolate);
net_log_ = atom::AtomBrowserClient::Get()->GetNetLog();
net_log_writer_ =
atom::AtomBrowserMainParts::Get()->net_log()->net_export_file_writer();
net_log_writer_->AddObserver(this);
}
NetLog::~NetLog() {}
// static
v8::Local<v8::Value> NetLog::Create(v8::Isolate* isolate) {
return mate::CreateHandle(isolate, new NetLog(isolate)).ToV8();
NetLog::~NetLog() {
net_log_writer_->RemoveObserver(this);
}
void NetLog::StartLogging(mate::Arguments* args) {
@@ -37,22 +43,82 @@ void NetLog::StartLogging(mate::Arguments* args) {
return;
}
net_log_->StartDynamicLogging(log_path);
net_log::NetExportFileWriter::URLRequestContextGetterList context_getters = {
browser_context_->GetRequestContext()};
// TODO(deepak1556): Provide more flexibility to this module
// by allowing customizations on the capturing options.
net_log_writer_->StartNetLog(
log_path, net::NetLogCaptureMode::Default(),
net_log::NetExportFileWriter::kNoLimit /* file size limit */,
base::CommandLine::ForCurrentProcess()->GetCommandLineString(),
std::string(), context_getters);
}
bool NetLog::IsCurrentlyLogging() {
return net_log_->IsDynamicLogging();
std::string NetLog::GetLoggingState() const {
if (!net_log_state_)
return std::string();
const base::Value* current_log_state =
net_log_state_->FindKeyOfType("state", base::Value::Type::STRING);
if (!current_log_state)
return std::string();
return current_log_state->GetString();
}
base::FilePath::StringType NetLog::GetCurrentlyLoggingPath() {
return net_log_->GetDynamicLoggingPath().value();
bool NetLog::IsCurrentlyLogging() const {
const std::string log_state = GetLoggingState();
return (log_state == "STARTING_LOG") || (log_state == "LOGGING");
}
std::string NetLog::GetCurrentlyLoggingPath() const {
// Net log exporter has a default path which will be used
// when no log path is provided, but since we don't allow
// net log capture without user provided file path, this
// check is completely safe.
if (IsCurrentlyLogging()) {
const base::Value* current_log_path =
net_log_state_->FindKeyOfType("file", base::Value::Type::STRING);
if (current_log_path)
return current_log_path->GetString();
}
return std::string();
}
void NetLog::StopLogging(mate::Arguments* args) {
base::OnceClosure callback;
args->GetNext(&callback);
net_log::NetExportFileWriter::FilePathCallback callback;
if (!args->GetNext(&callback)) {
args->ThrowError("Invalid callback function");
return;
}
net_log_->StopDynamicLogging(std::move(callback));
if (IsCurrentlyLogging()) {
stop_callback_queue_.emplace_back(callback);
net_log_writer_->StopNetLog(nullptr, nullptr);
} else {
callback.Run(base::FilePath());
}
}
void NetLog::OnNewState(const base::DictionaryValue& state) {
net_log_state_ = state.CreateDeepCopy();
if (stop_callback_queue_.empty())
return;
if (GetLoggingState() == "NOT_LOGGING") {
for (auto& callback : stop_callback_queue_) {
if (!callback.is_null())
net_log_writer_->GetFilePathToCompletedLog(callback);
}
stop_callback_queue_.clear();
}
}
// static
mate::Handle<NetLog> NetLog::Create(v8::Isolate* isolate,
AtomBrowserContext* browser_context) {
return mate::CreateHandle(isolate, new NetLog(isolate, browser_context));
}
// static
@@ -63,28 +129,9 @@ void NetLog::BuildPrototype(v8::Isolate* isolate,
.SetProperty("currentlyLogging", &NetLog::IsCurrentlyLogging)
.SetProperty("currentlyLoggingPath", &NetLog::GetCurrentlyLoggingPath)
.SetMethod("startLogging", &NetLog::StartLogging)
.SetMethod("_stopLogging", &NetLog::StopLogging);
.SetMethod("stopLogging", &NetLog::StopLogging);
}
} // namespace api
} // namespace atom
namespace {
using atom::api::NetLog;
void Initialize(v8::Local<v8::Object> exports,
v8::Local<v8::Value> unused,
v8::Local<v8::Context> context,
void* priv) {
v8::Isolate* isolate = context->GetIsolate();
mate::Dictionary dict(isolate, exports);
dict.Set("netLog", NetLog::Create(isolate));
dict.Set("NetLog", NetLog::GetConstructor(isolate)->GetFunction());
}
} // namespace
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_net_log, Initialize)

View File

@@ -5,32 +5,50 @@
#ifndef ATOM_BROWSER_API_ATOM_API_NET_LOG_H_
#define ATOM_BROWSER_API_ATOM_API_NET_LOG_H_
#include <list>
#include <memory>
#include <string>
#include "brightray/browser/net_log.h"
#include "native_mate/wrappable.h"
#include "atom/browser/api/trackable_object.h"
#include "base/callback.h"
#include "base/values.h"
#include "components/net_log/net_export_file_writer.h"
#include "native_mate/handle.h"
namespace atom {
class AtomBrowserContext;
namespace api {
class NetLog : public mate::Wrappable<NetLog> {
class NetLog : public mate::TrackableObject<NetLog>,
public net_log::NetExportFileWriter::StateObserver {
public:
static v8::Local<v8::Value> Create(v8::Isolate* isolate);
static mate::Handle<NetLog> Create(v8::Isolate* isolate,
AtomBrowserContext* browser_context);
static void BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype);
void StartLogging(mate::Arguments* args);
bool IsCurrentlyLogging();
base::FilePath::StringType GetCurrentlyLoggingPath();
std::string GetLoggingState() const;
bool IsCurrentlyLogging() const;
std::string GetCurrentlyLoggingPath() const;
void StopLogging(mate::Arguments* args);
protected:
explicit NetLog(v8::Isolate* isolate);
explicit NetLog(v8::Isolate* isolate, AtomBrowserContext* browser_context);
~NetLog() override;
// net_log::NetExportFileWriter::StateObserver implementation
void OnNewState(const base::DictionaryValue& state) override;
private:
brightray::NetLog* net_log_;
AtomBrowserContext* browser_context_;
net_log::NetExportFileWriter* net_log_writer_;
std::list<net_log::NetExportFileWriter::FilePathCallback>
stop_callback_queue_;
std::unique_ptr<base::DictionaryValue> net_log_state_;
DISALLOW_COPY_AND_ASSIGN(NetLog);
};

View File

@@ -83,7 +83,8 @@ void Protocol::UnregisterProtocol(const std::string& scheme,
mate::Arguments* args) {
CompletionCallback callback;
args->GetNext(&callback);
auto* getter = browser_context_->GetRequestContext();
auto* getter = static_cast<URLRequestContextGetter*>(
browser_context_->GetRequestContext());
content::BrowserThread::PostTaskAndReplyWithResult(
content::BrowserThread::IO, FROM_HERE,
base::BindOnce(&Protocol::UnregisterProtocolInIO,
@@ -93,10 +94,9 @@ void Protocol::UnregisterProtocol(const std::string& scheme,
// static
Protocol::ProtocolError Protocol::UnregisterProtocolInIO(
scoped_refptr<brightray::URLRequestContextGetter> request_context_getter,
scoped_refptr<URLRequestContextGetter> request_context_getter,
const std::string& scheme) {
auto* job_factory = static_cast<AtomURLRequestJobFactory*>(
request_context_getter->job_factory());
auto* job_factory = request_context_getter->job_factory();
if (!job_factory->HasProtocolHandler(scheme))
return PROTOCOL_NOT_REGISTERED;
job_factory->SetProtocolHandler(scheme, nullptr);
@@ -105,7 +105,8 @@ Protocol::ProtocolError Protocol::UnregisterProtocolInIO(
void Protocol::IsProtocolHandled(const std::string& scheme,
const BooleanCallback& callback) {
auto* getter = browser_context_->GetRequestContext();
auto* getter = static_cast<URLRequestContextGetter*>(
browser_context_->GetRequestContext());
content::BrowserThread::PostTaskAndReplyWithResult(
content::BrowserThread::IO, FROM_HERE,
base::Bind(&Protocol::IsProtocolHandledInIO, base::RetainedRef(getter),
@@ -115,7 +116,7 @@ void Protocol::IsProtocolHandled(const std::string& scheme,
// static
bool Protocol::IsProtocolHandledInIO(
scoped_refptr<brightray::URLRequestContextGetter> request_context_getter,
scoped_refptr<URLRequestContextGetter> request_context_getter,
const std::string& scheme) {
return request_context_getter->job_factory()->IsHandledProtocol(scheme);
}
@@ -124,7 +125,8 @@ void Protocol::UninterceptProtocol(const std::string& scheme,
mate::Arguments* args) {
CompletionCallback callback;
args->GetNext(&callback);
auto* getter = browser_context_->GetRequestContext();
auto* getter = static_cast<URLRequestContextGetter*>(
browser_context_->GetRequestContext());
content::BrowserThread::PostTaskAndReplyWithResult(
content::BrowserThread::IO, FROM_HERE,
base::BindOnce(&Protocol::UninterceptProtocolInIO,
@@ -134,11 +136,9 @@ void Protocol::UninterceptProtocol(const std::string& scheme,
// static
Protocol::ProtocolError Protocol::UninterceptProtocolInIO(
scoped_refptr<brightray::URLRequestContextGetter> request_context_getter,
scoped_refptr<URLRequestContextGetter> request_context_getter,
const std::string& scheme) {
return static_cast<AtomURLRequestJobFactory*>(
request_context_getter->job_factory())
->UninterceptProtocol(scheme)
return request_context_getter->job_factory()->UninterceptProtocol(scheme)
? PROTOCOL_OK
: PROTOCOL_NOT_INTERCEPTED;
}

View File

@@ -100,7 +100,8 @@ class Protocol : public mate::TrackableObject<Protocol> {
mate::Arguments* args) {
CompletionCallback callback;
args->GetNext(&callback);
auto* getter = browser_context_->GetRequestContext();
auto* getter = static_cast<URLRequestContextGetter*>(
browser_context_->GetRequestContext());
content::BrowserThread::PostTaskAndReplyWithResult(
content::BrowserThread::IO, FROM_HERE,
base::BindOnce(&Protocol::RegisterProtocolInIO<RequestJob>,
@@ -109,12 +110,11 @@ class Protocol : public mate::TrackableObject<Protocol> {
}
template <typename RequestJob>
static ProtocolError RegisterProtocolInIO(
scoped_refptr<brightray::URLRequestContextGetter> request_context_getter,
scoped_refptr<URLRequestContextGetter> request_context_getter,
v8::Isolate* isolate,
const std::string& scheme,
const Handler& handler) {
auto* job_factory = static_cast<AtomURLRequestJobFactory*>(
request_context_getter->job_factory());
auto* job_factory = request_context_getter->job_factory();
if (job_factory->IsHandledProtocol(scheme))
return PROTOCOL_REGISTERED;
auto protocol_handler = std::make_unique<CustomProtocolHandler<RequestJob>>(
@@ -128,14 +128,14 @@ class Protocol : public mate::TrackableObject<Protocol> {
// Unregister the protocol handler that handles |scheme|.
void UnregisterProtocol(const std::string& scheme, mate::Arguments* args);
static ProtocolError UnregisterProtocolInIO(
scoped_refptr<brightray::URLRequestContextGetter> request_context_getter,
scoped_refptr<URLRequestContextGetter> request_context_getter,
const std::string& scheme);
// Whether the protocol has handler registered.
void IsProtocolHandled(const std::string& scheme,
const BooleanCallback& callback);
static bool IsProtocolHandledInIO(
scoped_refptr<brightray::URLRequestContextGetter> request_context_getter,
scoped_refptr<URLRequestContextGetter> request_context_getter,
const std::string& scheme);
// Replace the protocol handler with a new one.
@@ -145,7 +145,8 @@ class Protocol : public mate::TrackableObject<Protocol> {
mate::Arguments* args) {
CompletionCallback callback;
args->GetNext(&callback);
auto* getter = browser_context_->GetRequestContext();
auto* getter = static_cast<URLRequestContextGetter*>(
browser_context_->GetRequestContext());
content::BrowserThread::PostTaskAndReplyWithResult(
content::BrowserThread::IO, FROM_HERE,
base::BindOnce(&Protocol::InterceptProtocolInIO<RequestJob>,
@@ -154,12 +155,11 @@ class Protocol : public mate::TrackableObject<Protocol> {
}
template <typename RequestJob>
static ProtocolError InterceptProtocolInIO(
scoped_refptr<brightray::URLRequestContextGetter> request_context_getter,
scoped_refptr<URLRequestContextGetter> request_context_getter,
v8::Isolate* isolate,
const std::string& scheme,
const Handler& handler) {
auto* job_factory = static_cast<AtomURLRequestJobFactory*>(
request_context_getter->job_factory());
auto* job_factory = request_context_getter->job_factory();
if (!job_factory->IsHandledProtocol(scheme))
return PROTOCOL_NOT_REGISTERED;
// It is possible a protocol is handled but can not be intercepted.
@@ -175,7 +175,7 @@ class Protocol : public mate::TrackableObject<Protocol> {
// Restore the |scheme| to its original protocol handler.
void UninterceptProtocol(const std::string& scheme, mate::Arguments* args);
static ProtocolError UninterceptProtocolInIO(
scoped_refptr<brightray::URLRequestContextGetter> request_context_getter,
scoped_refptr<URLRequestContextGetter> request_context_getter,
const std::string& scheme);
// Convert error code to JS exception and call the callback.

View File

@@ -10,6 +10,7 @@
#include "atom/browser/api/atom_api_cookies.h"
#include "atom/browser/api/atom_api_download_item.h"
#include "atom/browser/api/atom_api_net_log.h"
#include "atom/browser/api/atom_api_protocol.h"
#include "atom/browser/api/atom_api_web_request.h"
#include "atom/browser/atom_browser_context.h"
@@ -29,12 +30,14 @@
#include "base/guid.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/threading/thread_task_runner_handle.h"
#include "brightray/browser/media/media_device_id_salt.h"
#include "chrome/browser/browser_process.h"
#include "chrome/common/pref_names.h"
#include "components/download/public/common/download_danger_type.h"
#include "components/prefs/pref_service.h"
#include "components/prefs/value_map_pref_store.h"
#include "components/proxy_config/proxy_config_dictionary.h"
#include "components/proxy_config/proxy_config_pref_names.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/download_item_utils.h"
#include "content/public/browser/download_manager_delegate.h"
@@ -46,8 +49,8 @@
#include "net/dns/host_cache.h"
#include "net/http/http_auth_handler_factory.h"
#include "net/http/http_auth_preferences.h"
#include "net/proxy_resolution/proxy_config_service_fixed.h"
#include "net/proxy_resolution/proxy_service.h"
#include "net/http/http_cache.h"
#include "net/http/http_transaction_factory.h"
#include "net/url_request/static_http_user_agent_settings.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_context_getter.h"
@@ -179,37 +182,6 @@ struct Converter<ClearAuthCacheOptions> {
}
};
template <>
struct Converter<net::ProxyConfig> {
static bool FromV8(v8::Isolate* isolate,
v8::Local<v8::Value> val,
net::ProxyConfig* out) {
std::string proxy_rules, proxy_bypass_rules;
GURL pac_url;
mate::Dictionary options;
// Fallback to previous API when passed String.
// https://git.io/vuhjj
if (ConvertFromV8(isolate, val, &proxy_rules)) {
pac_url = GURL(proxy_rules); // Assume it is PAC script if it is URL.
} else if (ConvertFromV8(isolate, val, &options)) {
options.Get("pacScript", &pac_url);
options.Get("proxyRules", &proxy_rules);
options.Get("proxyBypassRules", &proxy_bypass_rules);
} else {
return false;
}
// pacScript takes precedence over proxyRules.
if (!pac_url.is_empty() && pac_url.is_valid()) {
out->set_pac_url(pac_url);
} else {
out->proxy_rules().ParseFromString(proxy_rules);
out->proxy_rules().bypass_rules.ParseFromString(proxy_bypass_rules);
}
return true;
}
};
template <>
struct Converter<atom::VerifyRequestParams> {
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
@@ -236,56 +208,6 @@ const char kPersistPrefix[] = "persist:";
// Referenced session objects.
std::map<uint32_t, v8::Global<v8::Object>> g_sessions;
class ResolveProxyHelper {
public:
ResolveProxyHelper(AtomBrowserContext* browser_context,
const GURL& url,
const Session::ResolveProxyCallback& callback)
: callback_(callback),
original_thread_(base::ThreadTaskRunnerHandle::Get()) {
scoped_refptr<net::URLRequestContextGetter> context_getter =
browser_context->GetRequestContext();
context_getter->GetNetworkTaskRunner()->PostTask(
FROM_HERE, base::BindOnce(&ResolveProxyHelper::ResolveProxy,
base::Unretained(this), context_getter, url));
}
void OnResolveProxyCompleted(int result) {
std::string proxy;
if (result == net::OK)
proxy = proxy_info_.ToPacString();
original_thread_->PostTask(FROM_HERE, base::BindOnce(callback_, proxy));
delete this;
}
private:
void ResolveProxy(scoped_refptr<net::URLRequestContextGetter> context_getter,
const GURL& url) {
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
net::ProxyResolutionService* proxy_service =
context_getter->GetURLRequestContext()->proxy_resolution_service();
net::CompletionCallback completion_callback = base::Bind(
&ResolveProxyHelper::OnResolveProxyCompleted, base::Unretained(this));
// Start the request.
int result = proxy_service->ResolveProxy(url, "GET", &proxy_info_,
completion_callback, &pac_req_,
nullptr, net::NetLogWithSource());
// Completed synchronously.
if (result != net::ERR_IO_PENDING)
completion_callback.Run(result);
}
Session::ResolveProxyCallback callback_;
net::ProxyInfo proxy_info_;
net::ProxyResolutionService::Request* pac_req_;
scoped_refptr<base::SingleThreadTaskRunner> original_thread_;
DISALLOW_COPY_AND_ASSIGN(ResolveProxyHelper);
};
// Runs the callback in UI thread.
void RunCallbackInUI(const base::Callback<void()>& callback) {
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, callback);
@@ -343,18 +265,6 @@ void DoCacheActionInIO(
on_get_backend.Run(net::OK);
}
void SetProxyInIO(scoped_refptr<net::URLRequestContextGetter> getter,
const net::ProxyConfig& config,
const base::Closure& callback) {
auto* proxy_service =
getter->GetURLRequestContext()->proxy_resolution_service();
proxy_service->ResetConfigService(
base::WrapUnique(new net::ProxyConfigServiceFixed(config)));
// Refetches and applies the new pac script if provided.
proxy_service->ForceReloadProxyConfig();
RunCallbackInUI(callback);
}
void SetCertVerifyProcInIO(
const scoped_refptr<net::URLRequestContextGetter>& context_getter,
const AtomCertVerifier::VerifyProc& proc) {
@@ -442,7 +352,7 @@ void DownloadIdCallback(content::DownloadManager* download_manager,
}
void SetDevToolsNetworkEmulationClientIdInIO(
brightray::URLRequestContextGetter* url_request_context_getter,
net::URLRequestContextGetter* url_request_context_getter,
const std::string& client_id) {
if (!url_request_context_getter)
return;
@@ -491,6 +401,7 @@ Session::~Session() {
DestroyGlobalHandle(isolate(), cookies_);
DestroyGlobalHandle(isolate(), web_request_);
DestroyGlobalHandle(isolate(), protocol_);
DestroyGlobalHandle(isolate(), net_log_);
g_sessions.erase(weak_map_id());
}
@@ -513,8 +424,10 @@ void Session::OnDownloadCreated(content::DownloadManager* manager,
}
}
void Session::ResolveProxy(const GURL& url, ResolveProxyCallback callback) {
new ResolveProxyHelper(browser_context(), url, callback);
void Session::ResolveProxy(
const GURL& url,
const ResolveProxyHelper::ResolveProxyCallback& callback) {
browser_context_->GetResolveProxyHelper()->ResolveProxy(url, callback);
}
template <Session::CacheAction action>
@@ -552,13 +465,34 @@ void Session::FlushStorageData() {
storage_partition->Flush();
}
void Session::SetProxy(const net::ProxyConfig& config,
void Session::SetProxy(const mate::Dictionary& options,
const base::Closure& callback) {
auto* getter = browser_context_->GetRequestContext();
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::BindOnce(&SetProxyInIO, base::RetainedRef(getter), config,
callback));
if (!browser_context_->in_memory_pref_store()) {
callback.Run();
return;
}
std::string proxy_rules, bypass_list, pac_url;
options.Get("pacScript", &pac_url);
options.Get("proxyRules", &proxy_rules);
options.Get("proxyBypassRules", &bypass_list);
// pacScript takes precedence over proxyRules.
if (!pac_url.empty()) {
browser_context_->in_memory_pref_store()->SetValue(
proxy_config::prefs::kProxy,
ProxyConfigDictionary::CreatePacScript(pac_url,
true /* pac_mandatory */),
WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
} else {
browser_context_->in_memory_pref_store()->SetValue(
proxy_config::prefs::kProxy,
ProxyConfigDictionary::CreateFixedServers(proxy_rules, bypass_list),
WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
}
base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, callback);
}
void Session::SetDownloadPath(const base::FilePath& path) {
@@ -669,7 +603,7 @@ void Session::SetUserAgent(const std::string& user_agent,
std::string accept_lang = g_browser_process->GetApplicationLocale();
args->GetNext(&accept_lang);
scoped_refptr<brightray::URLRequestContextGetter> getter(
scoped_refptr<net::URLRequestContextGetter> getter(
browser_context_->GetRequestContext());
getter->GetNetworkTaskRunner()->PostTask(
FROM_HERE,
@@ -760,6 +694,14 @@ v8::Local<v8::Value> Session::WebRequest(v8::Isolate* isolate) {
return v8::Local<v8::Value>::New(isolate, web_request_);
}
v8::Local<v8::Value> Session::NetLog(v8::Isolate* isolate) {
if (net_log_.IsEmpty()) {
auto handle = atom::api::NetLog::Create(isolate, browser_context());
net_log_.Reset(isolate, handle.ToV8());
}
return v8::Local<v8::Value>::New(isolate, net_log_);
}
// static
mate::Handle<Session> Session::CreateFrom(v8::Isolate* isolate,
AtomBrowserContext* browser_context) {
@@ -826,6 +768,7 @@ void Session::BuildPrototype(v8::Isolate* isolate,
.SetMethod("setPreloads", &Session::SetPreloads)
.SetMethod("getPreloads", &Session::GetPreloads)
.SetProperty("cookies", &Session::Cookies)
.SetProperty("netLog", &Session::NetLog)
.SetProperty("protocol", &Session::Protocol)
.SetProperty("webRequest", &Session::WebRequest);
}

View File

@@ -10,6 +10,7 @@
#include "atom/browser/api/trackable_object.h"
#include "atom/browser/atom_blob_reader.h"
#include "atom/browser/net/resolve_proxy_helper.h"
#include "base/values.h"
#include "content/public/browser/download_manager.h"
#include "native_mate/handle.h"
@@ -39,8 +40,6 @@ namespace api {
class Session : public mate::TrackableObject<Session>,
public content::DownloadManager::Observer {
public:
using ResolveProxyCallback = base::Callback<void(std::string)>;
enum class CacheAction {
CLEAR,
STATS,
@@ -63,12 +62,13 @@ class Session : public mate::TrackableObject<Session>,
v8::Local<v8::FunctionTemplate> prototype);
// Methods.
void ResolveProxy(const GURL& url, ResolveProxyCallback callback);
void ResolveProxy(const GURL& url,
const ResolveProxyHelper::ResolveProxyCallback& callback);
template <CacheAction action>
void DoCacheAction(const net::CompletionCallback& callback);
void ClearStorageData(mate::Arguments* args);
void FlushStorageData();
void SetProxy(const net::ProxyConfig& config, const base::Closure& callback);
void SetProxy(const mate::Dictionary& options, const base::Closure& callback);
void SetDownloadPath(const base::FilePath& path);
void EnableNetworkEmulation(const mate::Dictionary& options);
void DisableNetworkEmulation();
@@ -88,6 +88,7 @@ class Session : public mate::TrackableObject<Session>,
v8::Local<v8::Value> Cookies(v8::Isolate* isolate);
v8::Local<v8::Value> Protocol(v8::Isolate* isolate);
v8::Local<v8::Value> WebRequest(v8::Isolate* isolate);
v8::Local<v8::Value> NetLog(v8::Isolate* isolate);
protected:
Session(v8::Isolate* isolate, AtomBrowserContext* browser_context);
@@ -102,6 +103,7 @@ class Session : public mate::TrackableObject<Session>,
v8::Global<v8::Value> cookies_;
v8::Global<v8::Value> protocol_;
v8::Global<v8::Value> web_request_;
v8::Global<v8::Value> net_log_;
// The X-DevTools-Emulate-Network-Conditions-Client-Id.
std::string devtools_network_emulation_client_id_;

View File

@@ -93,6 +93,8 @@ class SystemPreferences : public mate::EventEmitter<SystemPreferences>
mate::Arguments* args);
void RemoveUserDefault(const std::string& name);
bool IsSwipeTrackingFromScrollEventsEnabled();
static bool IsTrustedAccessibilityClient(bool prompt);
#endif
bool IsDarkMode();
bool IsInvertedColorScheme();

View File

@@ -308,6 +308,12 @@ void SystemPreferences::SetUserDefault(const std::string& name,
}
}
// static
bool SystemPreferences::IsTrustedAccessibilityClient(bool prompt) {
NSDictionary* options = @{(id)kAXTrustedCheckOptionPrompt : @(prompt)};
return AXIsProcessTrustedWithOptions((CFDictionaryRef)options);
}
void SystemPreferences::RemoveUserDefault(const std::string& name) {
NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
[defaults removeObjectForKey:base::SysUTF8ToNSString(name)];

View File

@@ -376,8 +376,10 @@ gfx::Rect TopLevelWindow::GetContentBounds() {
void TopLevelWindow::SetSize(int width, int height, mate::Arguments* args) {
bool animate = false;
gfx::Size size = window_->GetMinimumSize();
size.SetToMax(gfx::Size(width, height));
args->GetNext(&animate);
window_->SetSize(gfx::Size(width, height), animate);
window_->SetSize(size, animate);
}
std::vector<int> TopLevelWindow::GetSize() {
@@ -662,8 +664,11 @@ void TopLevelWindow::SetBrowserView(v8::Local<v8::Value> value) {
}
v8::Local<v8::Value> TopLevelWindow::GetNativeWindowHandle() {
gfx::AcceleratedWidget handle = window_->GetAcceleratedWidget();
return ToBuffer(isolate(), static_cast<void*>(&handle), sizeof(handle));
// TODO(MarshallOfSound): Replace once
// https://chromium-review.googlesource.com/c/chromium/src/+/1253094/ has
// landed
NativeWindowHandle handle = window_->GetNativeWindowHandle();
return ToBuffer(isolate(), &handle, sizeof(handle));
}
void TopLevelWindow::SetProgressBar(double progress, mate::Arguments* args) {

View File

@@ -806,8 +806,10 @@ void WebContents::DidChangeThemeColor(SkColor theme_color) {
void WebContents::DocumentLoadedInFrame(
content::RenderFrameHost* render_frame_host) {
if (!render_frame_host->GetParent())
if (!render_frame_host->GetParent()) {
is_dom_ready_ = true;
Emit("dom-ready");
}
}
void WebContents::DidFinishLoad(content::RenderFrameHost* render_frame_host,
@@ -834,6 +836,7 @@ void WebContents::DidFailLoad(content::RenderFrameHost* render_frame_host,
}
void WebContents::DidStartLoading() {
is_dom_ready_ = false;
Emit("did-start-loading");
}
@@ -1147,6 +1150,9 @@ void WebContents::LoadURL(const GURL& url, const mate::Dictionary& options) {
params.transition_type = ui::PAGE_TRANSITION_TYPED;
params.should_clear_history_list = true;
params.override_user_agent = content::NavigationController::UA_OVERRIDE_TRUE;
// Discord non-committed entries to ensure that we don't re-use a pending
// entry
web_contents()->GetController().DiscardNonCommittedEntries();
web_contents()->GetController().LoadURLWithParams(params);
// Set the background color of RenderWidgetHostView.
@@ -1407,6 +1413,10 @@ bool WebContents::IsAudioMuted() {
return web_contents()->IsAudioMuted();
}
bool WebContents::IsDOMReady() const {
return is_dom_ready_;
}
void WebContents::Print(mate::Arguments* args) {
PrintSettings settings = {false, false, base::string16()};
if (args->Length() >= 1 && !args->GetNext(&settings)) {
@@ -2002,6 +2012,7 @@ void WebContents::BuildPrototype(v8::Isolate* isolate,
.SetMethod("setIgnoreMenuShortcuts", &WebContents::SetIgnoreMenuShortcuts)
.SetMethod("setAudioMuted", &WebContents::SetAudioMuted)
.SetMethod("isAudioMuted", &WebContents::IsAudioMuted)
.SetMethod("isDomReady", &WebContents::IsDOMReady)
.SetMethod("undo", &WebContents::Undo)
.SetMethod("redo", &WebContents::Redo)
.SetMethod("cut", &WebContents::Cut)

View File

@@ -142,6 +142,7 @@ class WebContents : public mate::TrackableObject<WebContents>,
void SetIgnoreMenuShortcuts(bool ignore);
void SetAudioMuted(bool muted);
bool IsAudioMuted();
bool IsDOMReady() const;
void Print(mate::Arguments* args);
std::vector<printing::PrinterBasicInfo> GetPrinterList();
void SetEmbedder(const WebContents* embedder);
@@ -462,6 +463,9 @@ class WebContents : public mate::TrackableObject<WebContents>,
// Whether to enable devtools.
bool enable_devtools_ = true;
// Whether page's document is ready.
bool is_dom_ready_ = false;
// Observers of this WebContents.
base::ObserverList<ExtendedWebContentsObserver> observers_;

View File

@@ -42,7 +42,7 @@ namespace {
template <typename Method, typename Event, typename Listener>
void CallNetworkDelegateMethod(
brightray::URLRequestContextGetter* url_request_context_getter,
URLRequestContextGetter* url_request_context_getter,
Method method,
Event type,
URLPatterns patterns,
@@ -94,8 +94,8 @@ void WebRequest::SetListener(Method method, Event type, mate::Arguments* args) {
return;
}
brightray::URLRequestContextGetter* url_request_context_getter =
browser_context_->GetRequestContext();
auto* url_request_context_getter = static_cast<URLRequestContextGetter*>(
browser_context_->GetRequestContext());
if (!url_request_context_getter)
return;
BrowserThread::PostTask(

View File

@@ -17,6 +17,7 @@
#include "atom/browser/atom_resource_dispatcher_host_delegate.h"
#include "atom/browser/atom_speech_recognition_manager_delegate.h"
#include "atom/browser/child_web_contents_tracker.h"
#include "atom/browser/io_thread.h"
#include "atom/browser/native_window.h"
#include "atom/browser/session_preferences.h"
#include "atom/browser/web_contents_permission_helper.h"
@@ -27,12 +28,16 @@
#include "base/command_line.h"
#include "base/environment.h"
#include "base/files/file_util.h"
#include "base/json/json_reader.h"
#include "base/no_destructor.h"
#include "base/stl_util.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/printing/printing_message_filter.h"
#include "chrome/browser/renderer_host/pepper/chrome_browser_pepper_host_factory.h"
#include "chrome/browser/speech/tts_message_filter.h"
#include "components/net_log/chrome_net_log.h"
#include "content/public/browser/browser_ppapi_host.h"
#include "content/public/browser/client_certificate_delegate.h"
#include "content/public/browser/render_frame_host.h"
@@ -43,12 +48,15 @@
#include "content/public/browser/web_contents.h"
#include "content/public/common/content_paths.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/service_names.mojom.h"
#include "content/public/common/url_constants.h"
#include "content/public/common/web_preferences.h"
#include "device/geolocation/public/cpp/location_provider.h"
#include "net/base/escape.h"
#include "net/ssl/ssl_cert_request_info.h"
#include "ppapi/host/ppapi_host.h"
#include "services/network/public/cpp/resource_request_body.h"
#include "services/proxy_resolver/public/mojom/proxy_resolver.mojom.h"
#include "ui/base/l10n/l10n_util.h"
#include "v8/include/v8.h"
@@ -504,10 +512,28 @@ AtomBrowserClient::OverrideSystemLocationProvider() {
#endif
}
network::mojom::NetworkContextPtr AtomBrowserClient::CreateNetworkContext(
content::BrowserContext* browser_context,
bool /*in_memory*/,
const base::FilePath& /*relative_partition_path*/) {
if (!browser_context)
return nullptr;
return static_cast<AtomBrowserContext*>(browser_context)->GetNetworkContext();
}
void AtomBrowserClient::RegisterOutOfProcessServices(
OutOfProcessServiceMap* services) {
(*services)[proxy_resolver::mojom::kProxyResolverServiceName] =
base::ASCIIToUTF16("V8 Proxy Resolver");
}
net::NetLog* AtomBrowserClient::GetNetLog() {
return AtomBrowserMainParts::Get()->net_log();
}
brightray::BrowserMainParts* AtomBrowserClient::OverrideCreateBrowserMainParts(
const content::MainFunctionParams&) {
v8::V8::Initialize(); // Init V8 before creating main parts.
return new AtomBrowserMainParts;
const content::MainFunctionParams& params) {
return new AtomBrowserMainParts(params);
}
void AtomBrowserClient::WebNotificationAllowed(

View File

@@ -108,6 +108,12 @@ class AtomBrowserClient : public brightray::BrowserClient,
content::ResourceContext* resource_context) override;
std::unique_ptr<device::LocationProvider> OverrideSystemLocationProvider()
override;
network::mojom::NetworkContextPtr CreateNetworkContext(
content::BrowserContext* browser_context,
bool in_memory,
const base::FilePath& relative_partition_path) override;
void RegisterOutOfProcessServices(OutOfProcessServiceMap* services) override;
net::NetLog* GetNetLog() override;
// brightray::BrowserClient:
brightray::BrowserMainParts* OverrideCreateBrowserMainParts(

View File

@@ -4,12 +4,16 @@
#include "atom/browser/atom_browser_context.h"
#include <utility>
#include "atom/browser/atom_blob_reader.h"
#include "atom/browser/atom_browser_main_parts.h"
#include "atom/browser/atom_download_manager_delegate.h"
#include "atom/browser/atom_permission_manager.h"
#include "atom/browser/browser.h"
#include "atom/browser/request_context_delegate.h"
#include "atom/browser/cookie_change_notifier.h"
#include "atom/browser/net/resolve_proxy_helper.h"
#include "atom/browser/pref_store_delegate.h"
#include "atom/browser/web_view_manager.h"
#include "atom/common/atom_version.h"
#include "atom/common/chrome_version.h"
@@ -17,12 +21,31 @@
#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/path_service.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/threading/sequenced_task_runner_handle.h"
#include "base/threading/thread_restrictions.h"
#include "brightray/browser/brightray_paths.h"
#include "brightray/browser/inspectable_web_contents_impl.h"
#include "brightray/browser/special_storage_policy.h"
#include "brightray/browser/zoom_level_delegate.h"
#include "brightray/common/application_info.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/pref_names.h"
#include "components/prefs/json_pref_store.h"
#include "components/prefs/pref_registry_simple.h"
#include "components/prefs/pref_service.h"
#include "components/prefs/pref_service_factory.h"
#include "components/prefs/value_map_pref_store.h"
#include "components/proxy_config/pref_proxy_config_tracker_impl.h"
#include "components/proxy_config/proxy_config_pref_names.h"
#include "content/browser/blob_storage/chrome_blob_storage_context.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/storage_partition.h"
#include "content/public/common/user_agent.h"
#include "net/base/escape.h"
using content::BrowserThread;
namespace atom {
@@ -36,13 +59,25 @@ std::string RemoveWhitespace(const std::string& str) {
return str;
}
// Convert string to lower case and escape it.
std::string MakePartitionName(const std::string& input) {
return net::EscapePath(base::ToLowerASCII(input));
}
} // namespace
// static
AtomBrowserContext::BrowserContextMap AtomBrowserContext::browser_context_map_;
AtomBrowserContext::AtomBrowserContext(const std::string& partition,
bool in_memory,
const base::DictionaryValue& options)
: brightray::BrowserContext(partition, in_memory),
url_request_context_getter_(nullptr) {
: base::RefCountedDeleteOnSequence<AtomBrowserContext>(
base::SequencedTaskRunnerHandle::Get()),
in_memory_pref_store_(nullptr),
storage_policy_(new brightray::SpecialStoragePolicy),
in_memory_(in_memory),
weak_factory_(this) {
// Construct user agent string.
Browser* browser = Browser::Get();
std::string name = RemoveWhitespace(browser->GetName());
@@ -59,23 +94,131 @@ AtomBrowserContext::AtomBrowserContext(const std::string& partition,
// Read options.
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
bool use_cache = !command_line->HasSwitch(switches::kDisableHttpCache);
options.GetBoolean("cache", &use_cache);
use_cache_ = !command_line->HasSwitch(switches::kDisableHttpCache);
options.GetBoolean("cache", &use_cache_);
request_context_delegate_.reset(new RequestContextDelegate(use_cache));
base::StringToInt(command_line->GetSwitchValueASCII(switches::kDiskCacheSize),
&max_cache_size_);
// Initialize Pref Registry in brightray.
if (!base::PathService::Get(brightray::DIR_USER_DATA, &path_)) {
base::PathService::Get(brightray::DIR_APP_DATA, &path_);
path_ = path_.Append(
base::FilePath::FromUTF8Unsafe(brightray::GetApplicationName()));
base::PathService::Override(brightray::DIR_USER_DATA, path_);
}
if (!in_memory && !partition.empty())
path_ = path_.Append(FILE_PATH_LITERAL("Partitions"))
.Append(base::FilePath::FromUTF8Unsafe(
MakePartitionName(partition)));
content::BrowserContext::Initialize(this, path_);
// Initialize Pref Registry.
InitPrefs();
proxy_config_monitor_ = std::make_unique<ProxyConfigMonitor>(prefs_.get());
io_handle_ = new URLRequestContextGetter::Handle(weak_factory_.GetWeakPtr());
cookie_change_notifier_ = std::make_unique<CookieChangeNotifier>(this);
}
AtomBrowserContext::~AtomBrowserContext() {
url_request_context_getter_->set_delegate(nullptr);
DCHECK_CURRENTLY_ON(BrowserThread::UI);
NotifyWillBeDestroyed(this);
ShutdownStoragePartitions();
io_handle_->ShutdownOnUIThread();
}
void AtomBrowserContext::InitPrefs() {
auto prefs_path = GetPath().Append(FILE_PATH_LITERAL("Preferences"));
base::ThreadRestrictions::ScopedAllowIO allow_io;
PrefServiceFactory prefs_factory;
scoped_refptr<JsonPrefStore> pref_store =
base::MakeRefCounted<JsonPrefStore>(prefs_path);
pref_store->ReadPrefs(); // Synchronous.
prefs_factory.set_user_prefs(pref_store);
auto registry = WrapRefCounted(new PrefRegistrySimple);
registry->RegisterFilePathPref(prefs::kSelectFileLastDirectory,
base::FilePath());
base::FilePath download_dir;
base::PathService::Get(chrome::DIR_DEFAULT_DOWNLOADS, &download_dir);
registry->RegisterFilePathPref(prefs::kDownloadDefaultDirectory,
download_dir);
registry->RegisterDictionaryPref(prefs::kDevToolsFileSystemPaths);
brightray::InspectableWebContentsImpl::RegisterPrefs(registry.get());
brightray::MediaDeviceIDSalt::RegisterPrefs(registry.get());
brightray::ZoomLevelDelegate::RegisterPrefs(registry.get());
PrefProxyConfigTrackerImpl::RegisterPrefs(registry.get());
prefs_ = prefs_factory.Create(
registry.get(),
std::make_unique<PrefStoreDelegate>(weak_factory_.GetWeakPtr()));
prefs_->UpdateCommandLinePrefStore(new ValueMapPrefStore);
}
void AtomBrowserContext::SetUserAgent(const std::string& user_agent) {
user_agent_ = user_agent;
}
net::URLRequestContextGetter* AtomBrowserContext::CreateRequestContext(
content::ProtocolHandlerMap* protocol_handlers,
content::URLRequestInterceptorScopedVector protocol_interceptors) {
return io_handle_
->CreateMainRequestContextGetter(protocol_handlers,
std::move(protocol_interceptors))
.get();
}
net::URLRequestContextGetter* AtomBrowserContext::CreateMediaRequestContext() {
return io_handle_->GetMainRequestContextGetter().get();
}
net::URLRequestContextGetter* AtomBrowserContext::GetRequestContext() {
return GetDefaultStoragePartition(this)->GetURLRequestContext();
}
network::mojom::NetworkContextPtr AtomBrowserContext::GetNetworkContext() {
return io_handle_->GetNetworkContext();
}
base::FilePath AtomBrowserContext::GetPath() const {
return path_;
}
bool AtomBrowserContext::IsOffTheRecord() const {
return in_memory_;
}
bool AtomBrowserContext::CanUseHttpCache() const {
return use_cache_;
}
int AtomBrowserContext::GetMaxCacheSize() const {
return max_cache_size_;
}
content::ResourceContext* AtomBrowserContext::GetResourceContext() {
return io_handle_->GetResourceContext();
}
std::string AtomBrowserContext::GetMediaDeviceIDSalt() {
if (!media_device_id_salt_.get())
media_device_id_salt_.reset(new brightray::MediaDeviceIDSalt(prefs_.get()));
return media_device_id_salt_->GetSalt();
}
std::unique_ptr<content::ZoomLevelDelegate>
AtomBrowserContext::CreateZoomLevelDelegate(
const base::FilePath& partition_path) {
if (!IsOffTheRecord()) {
return std::make_unique<brightray::ZoomLevelDelegate>(prefs(),
partition_path);
}
return std::unique_ptr<content::ZoomLevelDelegate>();
}
content::DownloadManagerDelegate*
AtomBrowserContext::GetDownloadManagerDelegate() {
if (!download_manager_delegate_.get()) {
@@ -98,26 +241,14 @@ content::PermissionManager* AtomBrowserContext::GetPermissionManager() {
return permission_manager_.get();
}
void AtomBrowserContext::RegisterPrefs(PrefRegistrySimple* pref_registry) {
pref_registry->RegisterFilePathPref(prefs::kSelectFileLastDirectory,
base::FilePath());
base::FilePath download_dir;
PathService::Get(chrome::DIR_DEFAULT_DOWNLOADS, &download_dir);
pref_registry->RegisterFilePathPref(prefs::kDownloadDefaultDirectory,
download_dir);
pref_registry->RegisterDictionaryPref(prefs::kDevToolsFileSystemPaths);
storage::SpecialStoragePolicy* AtomBrowserContext::GetSpecialStoragePolicy() {
return storage_policy_.get();
}
std::string AtomBrowserContext::GetUserAgent() const {
return user_agent_;
}
void AtomBrowserContext::OnMainRequestContextCreated(
brightray::URLRequestContextGetter* getter) {
getter->set_delegate(request_context_delegate_.get());
url_request_context_getter_ = getter;
}
AtomBlobReader* AtomBrowserContext::GetBlobReader() {
if (!blob_reader_.get()) {
content::ChromeBlobStorageContext* blob_context =
@@ -127,16 +258,67 @@ AtomBlobReader* AtomBrowserContext::GetBlobReader() {
return blob_reader_.get();
}
content::PushMessagingService* AtomBrowserContext::GetPushMessagingService() {
return nullptr;
}
content::SSLHostStateDelegate* AtomBrowserContext::GetSSLHostStateDelegate() {
return nullptr;
}
content::BackgroundFetchDelegate*
AtomBrowserContext::GetBackgroundFetchDelegate() {
return nullptr;
}
content::BackgroundSyncController*
AtomBrowserContext::GetBackgroundSyncController() {
return nullptr;
}
content::BrowsingDataRemoverDelegate*
AtomBrowserContext::GetBrowsingDataRemoverDelegate() {
return nullptr;
}
net::URLRequestContextGetter*
AtomBrowserContext::CreateRequestContextForStoragePartition(
const base::FilePath& partition_path,
bool in_memory,
content::ProtocolHandlerMap* protocol_handlers,
content::URLRequestInterceptorScopedVector request_interceptors) {
NOTREACHED();
return nullptr;
}
net::URLRequestContextGetter*
AtomBrowserContext::CreateMediaRequestContextForStoragePartition(
const base::FilePath& partition_path,
bool in_memory) {
NOTREACHED();
return nullptr;
}
ResolveProxyHelper* AtomBrowserContext::GetResolveProxyHelper() {
if (!resolve_proxy_helper_) {
resolve_proxy_helper_ = base::MakeRefCounted<ResolveProxyHelper>(this);
}
return resolve_proxy_helper_.get();
}
// static
scoped_refptr<AtomBrowserContext> AtomBrowserContext::From(
const std::string& partition,
bool in_memory,
const base::DictionaryValue& options) {
auto browser_context = brightray::BrowserContext::Get(partition, in_memory);
PartitionKey key(partition, in_memory);
auto* browser_context = browser_context_map_[key].get();
if (browser_context)
return static_cast<AtomBrowserContext*>(browser_context.get());
return scoped_refptr<AtomBrowserContext>(browser_context);
return new AtomBrowserContext(partition, in_memory, options);
auto* new_context = new AtomBrowserContext(partition, in_memory, options);
browser_context_map_[key] = new_context->GetWeakPtr();
return scoped_refptr<AtomBrowserContext>(new_context);
}
} // namespace atom

View File

@@ -5,20 +5,39 @@
#ifndef ATOM_BROWSER_ATOM_BROWSER_CONTEXT_H_
#define ATOM_BROWSER_ATOM_BROWSER_CONTEXT_H_
#include <map>
#include <memory>
#include <string>
#include <vector>
#include "brightray/browser/browser_context.h"
#include "atom/browser/net/url_request_context_getter.h"
#include "base/memory/ref_counted_delete_on_sequence.h"
#include "base/memory/weak_ptr.h"
#include "brightray/browser/media/media_device_id_salt.h"
#include "chrome/browser/net/proxy_config_monitor.h"
#include "content/public/browser/browser_context.h"
class PrefRegistrySimple;
class PrefService;
class ValueMapPrefStore;
namespace brightray {
class SpecialStoragePolicy;
}
namespace atom {
class AtomBlobReader;
class AtomBrowserContext;
class AtomDownloadManagerDelegate;
class AtomPermissionManager;
class RequestContextDelegate;
class CookieChangeNotifier;
class ResolveProxyHelper;
class WebViewManager;
class AtomBrowserContext : public brightray::BrowserContext {
class AtomBrowserContext
: public base::RefCountedDeleteOnSequence<AtomBrowserContext>,
public content::BrowserContext {
public:
// Get or create the BrowserContext according to its |partition| and
// |in_memory|. The |options| will be passed to constructor when there is no
@@ -29,21 +48,60 @@ class AtomBrowserContext : public brightray::BrowserContext {
const base::DictionaryValue& options = base::DictionaryValue());
void SetUserAgent(const std::string& user_agent);
std::string GetUserAgent() const;
bool CanUseHttpCache() const;
int GetMaxCacheSize() const;
AtomBlobReader* GetBlobReader();
network::mojom::NetworkContextPtr GetNetworkContext();
// Get the request context, if there is none, create it.
net::URLRequestContextGetter* GetRequestContext();
ResolveProxyHelper* GetResolveProxyHelper();
// content::BrowserContext:
base::FilePath GetPath() const override;
bool IsOffTheRecord() const override;
content::ResourceContext* GetResourceContext() override;
std::unique_ptr<content::ZoomLevelDelegate> CreateZoomLevelDelegate(
const base::FilePath& partition_path) override;
content::PushMessagingService* GetPushMessagingService() override;
content::SSLHostStateDelegate* GetSSLHostStateDelegate() override;
content::BackgroundFetchDelegate* GetBackgroundFetchDelegate() override;
content::BackgroundSyncController* GetBackgroundSyncController() override;
content::BrowsingDataRemoverDelegate* GetBrowsingDataRemoverDelegate()
override;
net::URLRequestContextGetter* CreateRequestContextForStoragePartition(
const base::FilePath& partition_path,
bool in_memory,
content::ProtocolHandlerMap* protocol_handlers,
content::URLRequestInterceptorScopedVector request_interceptors) override;
net::URLRequestContextGetter* CreateMediaRequestContextForStoragePartition(
const base::FilePath& partition_path,
bool in_memory) override;
std::string GetMediaDeviceIDSalt() override;
content::DownloadManagerDelegate* GetDownloadManagerDelegate() override;
content::BrowserPluginGuestManager* GetGuestManager() override;
content::PermissionManager* GetPermissionManager() override;
storage::SpecialStoragePolicy* GetSpecialStoragePolicy() override;
net::URLRequestContextGetter* CreateRequestContext(
content::ProtocolHandlerMap* protocol_handlers,
content::URLRequestInterceptorScopedVector request_interceptors) override;
net::URLRequestContextGetter* CreateMediaRequestContext() override;
// brightray::BrowserContext:
void RegisterPrefs(PrefRegistrySimple* pref_registry) override;
std::string GetUserAgent() const override;
void OnMainRequestContextCreated(
brightray::URLRequestContextGetter* getter) override;
RequestContextDelegate* GetRequestContextDelegate() const {
return request_context_delegate_.get();
CookieChangeNotifier* cookie_change_notifier() const {
return cookie_change_notifier_.get();
}
ProxyConfigMonitor* proxy_config_monitor() {
return proxy_config_monitor_.get();
}
PrefService* prefs() const { return prefs_.get(); }
void set_in_memory_pref_store(ValueMapPrefStore* pref_store) {
in_memory_pref_store_ = pref_store;
}
ValueMapPrefStore* in_memory_pref_store() const {
return in_memory_pref_store_;
}
base::WeakPtr<AtomBrowserContext> GetWeakPtr() {
return weak_factory_.GetWeakPtr();
}
protected:
@@ -53,14 +111,60 @@ class AtomBrowserContext : public brightray::BrowserContext {
~AtomBrowserContext() override;
private:
brightray::URLRequestContextGetter* url_request_context_getter_;
friend class base::RefCountedDeleteOnSequence<AtomBrowserContext>;
friend class base::DeleteHelper<AtomBrowserContext>;
// Initialize pref registry.
void InitPrefs();
// partition_id => browser_context
struct PartitionKey {
std::string partition;
bool in_memory;
PartitionKey(const std::string& partition, bool in_memory)
: partition(partition), in_memory(in_memory) {}
bool operator<(const PartitionKey& other) const {
if (partition == other.partition)
return in_memory < other.in_memory;
return partition < other.partition;
}
bool operator==(const PartitionKey& other) const {
return (partition == other.partition) && (in_memory == other.in_memory);
}
};
using BrowserContextMap =
std::map<PartitionKey, base::WeakPtr<AtomBrowserContext>>;
static BrowserContextMap browser_context_map_;
// Self-destructing class responsible for creating URLRequestContextGetter
// on the UI thread and deletes itself on the IO thread.
URLRequestContextGetter::Handle* io_handle_;
ValueMapPrefStore* in_memory_pref_store_;
std::unique_ptr<CookieChangeNotifier> cookie_change_notifier_;
std::unique_ptr<PrefService> prefs_;
std::unique_ptr<AtomDownloadManagerDelegate> download_manager_delegate_;
std::unique_ptr<WebViewManager> guest_manager_;
std::unique_ptr<AtomPermissionManager> permission_manager_;
std::unique_ptr<AtomBlobReader> blob_reader_;
std::unique_ptr<RequestContextDelegate> request_context_delegate_;
std::unique_ptr<brightray::MediaDeviceIDSalt> media_device_id_salt_;
scoped_refptr<ResolveProxyHelper> resolve_proxy_helper_;
scoped_refptr<storage::SpecialStoragePolicy> storage_policy_;
// Tracks the ProxyConfig to use, and passes any updates to a NetworkContext
// ProxyConfigClient.
std::unique_ptr<ProxyConfigMonitor> proxy_config_monitor_;
std::string user_agent_;
base::FilePath path_;
bool in_memory_ = false;
bool use_cache_ = true;
int max_cache_size_ = 0;
base::WeakPtrFactory<AtomBrowserContext> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(AtomBrowserContext);
};

View File

@@ -10,6 +10,7 @@
#include "atom/browser/atom_browser_context.h"
#include "atom/browser/bridge_task_runner.h"
#include "atom/browser/browser.h"
#include "atom/browser/io_thread.h"
#include "atom/browser/javascript_environment.h"
#include "atom/browser/node_debugger.h"
#include "atom/common/api/atom_bindings.h"
@@ -18,10 +19,15 @@
#include "base/command_line.h"
#include "base/threading/thread_task_runner_handle.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/net/chrome_net_log_helper.h"
#include "components/net_log/chrome_net_log.h"
#include "components/net_log/net_export_file_writer.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/child_process_security_policy.h"
#include "content/public/common/result_codes.h"
#include "content/public/common/service_manager_connection.h"
#include "services/device/public/mojom/constants.mojom.h"
#include "services/network/public/cpp/network_switches.h"
#include "services/service_manager/public/cpp/connector.h"
#include "ui/base/idle/idle.h"
#include "ui/base/l10n/l10n_util.h"
@@ -58,12 +64,14 @@ void Erase(T* container, typename T::iterator iter) {
// static
AtomBrowserMainParts* AtomBrowserMainParts::self_ = nullptr;
AtomBrowserMainParts::AtomBrowserMainParts()
AtomBrowserMainParts::AtomBrowserMainParts(
const content::MainFunctionParams& params)
: fake_browser_process_(new BrowserProcess),
browser_(new Browser),
node_bindings_(NodeBindings::Create(NodeBindings::BROWSER)),
atom_bindings_(new AtomBindings(uv_default_loop())),
gc_timer_(true, true) {
gc_timer_(true, true),
main_function_params_(params) {
DCHECK(!self_) << "Cannot have two AtomBrowserMainParts";
self_ = this;
// Register extension scheme as web safe scheme.
@@ -175,9 +183,34 @@ int AtomBrowserMainParts::PreCreateThreads() {
ui::InitIdleMonitor();
#endif
net_log_ = std::make_unique<net_log::ChromeNetLog>();
auto& command_line = main_function_params_.command_line;
// start net log trace if --log-net-log is passed in the command line.
if (command_line.HasSwitch(network::switches::kLogNetLog)) {
base::FilePath log_file =
command_line.GetSwitchValuePath(network::switches::kLogNetLog);
if (!log_file.empty()) {
net_log_->StartWritingToFile(
log_file, GetNetCaptureModeFromCommandLine(command_line),
command_line.GetCommandLineString(), std::string());
}
}
// Initialize net log file exporter.
net_log_->net_export_file_writer()->Initialize(
content::BrowserThread::GetTaskRunnerForThread(
content::BrowserThread::IO));
// Manage global state of net and other IO thread related.
io_thread_ = std::make_unique<IOThread>(net_log_.get());
return result;
}
void AtomBrowserMainParts::PostDestroyThreads() {
brightray::BrowserMainParts::PostDestroyThreads();
io_thread_.reset();
}
void AtomBrowserMainParts::ToolkitInitialized() {
brightray::BrowserMainParts::ToolkitInitialized();
#if defined(OS_MACOSX)

View File

@@ -12,6 +12,7 @@
#include "base/timer/timer.h"
#include "brightray/browser/browser_main_parts.h"
#include "content/public/browser/browser_context.h"
#include "content/public/common/main_function_params.h"
#include "services/device/public/mojom/geolocation_control.mojom.h"
class BrowserProcess;
@@ -22,10 +23,15 @@ class ViewsDelegate;
}
#endif
namespace net_log {
class ChromeNetLog;
}
namespace atom {
class AtomBindings;
class Browser;
class IOThread;
class JavascriptEnvironment;
class NodeBindings;
class NodeDebugger;
@@ -38,7 +44,7 @@ class ViewsDelegateMac;
class AtomBrowserMainParts : public brightray::BrowserMainParts {
public:
AtomBrowserMainParts();
explicit AtomBrowserMainParts(const content::MainFunctionParams& params);
~AtomBrowserMainParts() override;
static AtomBrowserMainParts* Get();
@@ -59,6 +65,8 @@ class AtomBrowserMainParts : public brightray::BrowserMainParts {
device::mojom::GeolocationControl* GetGeolocationControl();
Browser* browser() { return browser_.get(); }
IOThread* io_thread() const { return io_thread_.get(); }
net_log::ChromeNetLog* net_log() { return net_log_.get(); }
protected:
// content::BrowserMainParts:
@@ -73,6 +81,7 @@ class AtomBrowserMainParts : public brightray::BrowserMainParts {
#if defined(OS_MACOSX)
void PreMainMessageLoopStart() override;
#endif
void PostDestroyThreads() override;
private:
#if defined(OS_POSIX)
@@ -107,6 +116,8 @@ class AtomBrowserMainParts : public brightray::BrowserMainParts {
std::unique_ptr<AtomBindings> atom_bindings_;
std::unique_ptr<NodeEnvironment> node_env_;
std::unique_ptr<NodeDebugger> node_debugger_;
std::unique_ptr<IOThread> io_thread_;
std::unique_ptr<net_log::ChromeNetLog> net_log_;
base::Timer gc_timer_;
@@ -115,6 +126,8 @@ class AtomBrowserMainParts : public brightray::BrowserMainParts {
device::mojom::GeolocationControlPtr geolocation_control_;
const content::MainFunctionParams main_function_params_;
static AtomBrowserMainParts* self_;
DISALLOW_COPY_AND_ASSIGN(AtomBrowserMainParts);

View File

@@ -217,6 +217,65 @@ Browser::LoginItemSettings Browser::GetLoginItemSettings(
return settings;
}
// copied from GetLoginItemForApp in base/mac/mac_util.mm
LSSharedFileListItemRef GetLoginItemForApp() {
base::ScopedCFTypeRef<LSSharedFileListRef> login_items(
LSSharedFileListCreate(NULL, kLSSharedFileListSessionLoginItems, NULL));
if (!login_items.get()) {
LOG(ERROR) << "Couldn't get a Login Items list.";
return NULL;
}
base::scoped_nsobject<NSArray> login_items_array(
base::mac::CFToNSCast(LSSharedFileListCopySnapshot(login_items, NULL)));
NSURL* url = [NSURL fileURLWithPath:[base::mac::MainBundle() bundlePath]];
for (NSUInteger i = 0; i < [login_items_array count]; ++i) {
LSSharedFileListItemRef item =
reinterpret_cast<LSSharedFileListItemRef>(login_items_array[i]);
CFURLRef item_url_ref = NULL;
if (LSSharedFileListItemResolve(item, 0, &item_url_ref, NULL) == noErr &&
item_url_ref) {
base::ScopedCFTypeRef<CFURLRef> item_url(item_url_ref);
if (CFEqual(item_url, url)) {
CFRetain(item);
return item;
}
}
}
return NULL;
}
void RemoveFromLoginItems() {
base::ScopedCFTypeRef<LSSharedFileListRef> list(
LSSharedFileListCreate(NULL, kLSSharedFileListSessionLoginItems, NULL));
if (!list) {
LOG(ERROR) << "Unable to access shared file list";
return;
}
if (GetLoginItemForApp() != NULL) {
base::scoped_nsobject<NSArray> login_items_array(
base::mac::CFToNSCast(LSSharedFileListCopySnapshot(list, NULL)));
if (!login_items_array) {
LOG(ERROR) << "No items in list of auto-loaded apps";
return;
}
for (NSUInteger i = 0; i < [login_items_array count]; ++i) {
LSSharedFileListItemRef item =
reinterpret_cast<LSSharedFileListItemRef>(login_items_array[i]);
CFURLRef url_ref = NULL;
if (LSSharedFileListItemResolve(item, 0, &url_ref, NULL) == noErr &&
item) {
base::ScopedCFTypeRef<CFURLRef> url(url_ref);
if ([[base::mac::CFToNSCast(url.get()) path]
hasPrefix:[[NSBundle mainBundle] bundlePath]])
LSSharedFileListItemRemove(list, item);
}
}
}
}
void Browser::SetLoginItemSettings(LoginItemSettings settings) {
#if defined(MAS_BUILD)
platform_util::SetLoginItemEnabled(settings.open_at_login);
@@ -224,7 +283,7 @@ void Browser::SetLoginItemSettings(LoginItemSettings settings) {
if (settings.open_at_login)
base::mac::AddToLoginItems(settings.open_as_hidden);
else
base::mac::RemoveFromLoginItems();
RemoveFromLoginItems();
#endif
}

View File

@@ -163,11 +163,11 @@ void CommonWebContentsDelegate::InitWithWebContents(
// Determien whether the WebContents is offscreen.
auto* web_preferences = WebContentsPreferences::From(web_contents);
offscreen_ =
!web_preferences || web_preferences->IsEnabled(options::kOffscreen);
web_preferences && web_preferences->IsEnabled(options::kOffscreen);
// Create InspectableWebContents.
web_contents_.reset(
brightray::InspectableWebContents::Create(web_contents, is_guest));
web_contents_.reset(brightray::InspectableWebContents::Create(
web_contents, browser_context->prefs(), is_guest));
web_contents_->SetDelegate(this);
}
@@ -194,8 +194,17 @@ void CommonWebContentsDelegate::SetOwnerWindow(
void CommonWebContentsDelegate::ResetManagedWebContents(bool async) {
if (async) {
base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE,
web_contents_.release());
// Browser context should be destroyed only after the WebContents,
// this is guaranteed in the sync mode by the order of declaration,
// in the async version we maintain a reference until the WebContents
// is destroyed.
base::ThreadTaskRunnerHandle::Get()->PostNonNestableTask(
FROM_HERE,
base::BindOnce([](scoped_refptr<AtomBrowserContext> browser_context,
std::unique_ptr<brightray::InspectableWebContents>
web_contents) { web_contents.reset(); },
base::RetainedRef(browser_context_),
std::move(web_contents_)));
} else {
web_contents_.reset();
}

View File

@@ -28,18 +28,20 @@ void CommonWebContentsDelegate::HandleKeyboardEvent(
if (event.windows_key_code == ui::VKEY_ESCAPE && is_html_fullscreen())
ExitFullscreenModeForTab(source);
if (auto* web_preferences = WebContentsPreferences::From(source)) {
if (!web_preferences->IsEnabled("ignoreMenuShortcuts", false)) {
// Send the event to the menu before sending it to the window
if (event.os_event.type == NSKeyDown &&
[[NSApp mainMenu] performKeyEquivalent:event.os_event])
return;
// Check if the webContents has preferences and to ignore shortcuts
auto* web_preferences = WebContentsPreferences::From(source);
if (web_preferences &&
web_preferences->IsEnabled("ignoreMenuShortcuts", false))
return;
if (event.os_event.window &&
[event.os_event.window isKindOfClass:[EventDispatchingWindow class]])
[event.os_event.window redispatchKeyEvent:event.os_event];
}
}
// Send the event to the menu before sending it to the window
if (event.os_event.type == NSKeyDown &&
[[NSApp mainMenu] performKeyEquivalent:event.os_event])
return;
if (event.os_event.window &&
[event.os_event.window isKindOfClass:[EventDispatchingWindow class]])
[event.os_event.window redispatchKeyEvent:event.os_event];
}
} // namespace atom

View File

@@ -24,12 +24,15 @@ void CommonWebContentsDelegate::HandleKeyboardEvent(
if (event.windows_key_code == ui::VKEY_ESCAPE && is_html_fullscreen())
ExitFullscreenModeForTab(source);
// Check if the webContents has preferences and to ignore shortcuts
auto* web_preferences = WebContentsPreferences::From(source);
if (web_preferences &&
web_preferences->IsEnabled("ignoreMenuShortcuts", false))
return;
// Let the NativeWindow handle other parts.
if (auto* web_preferences = WebContentsPreferences::From(source)) {
if (owner_window() &&
!web_preferences->IsEnabled("ignoreMenuShortcuts", false)) {
owner_window()->HandleKeyboardEvent(source, event);
}
if (owner_window()) {
owner_window()->HandleKeyboardEvent(source, event);
}
}

View File

@@ -0,0 +1,72 @@
// Copyright (c) 2018 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/browser/cookie_change_notifier.h"
#include <utility>
#include "atom/browser/atom_browser_context.h"
#include "atom/browser/net/cookie_details.h"
#include "base/bind.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/storage_partition.h"
#include "net/cookies/canonical_cookie.h"
using content::BrowserThread;
namespace atom {
CookieChangeNotifier::CookieChangeNotifier(AtomBrowserContext* browser_context)
: browser_context_(browser_context), binding_(this) {
StartListening();
}
CookieChangeNotifier::~CookieChangeNotifier() = default;
std::unique_ptr<base::CallbackList<void(const CookieDetails*)>::Subscription>
CookieChangeNotifier::RegisterCookieChangeCallback(
const base::Callback<void(const CookieDetails*)>& cb) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
return cookie_change_sub_list_.Add(cb);
}
void CookieChangeNotifier::StartListening() {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
DCHECK(!binding_.is_bound());
network::mojom::CookieManager* cookie_manager =
content::BrowserContext::GetDefaultStoragePartition(browser_context_)
->GetCookieManagerForBrowserProcess();
// Cookie manager should be created whenever network context is created,
// if this fails then there is something wrong with our context creation
// cycle.
CHECK(cookie_manager);
network::mojom::CookieChangeListenerPtr listener_ptr;
binding_.Bind(mojo::MakeRequest(&listener_ptr));
binding_.set_connection_error_handler(base::BindOnce(
&CookieChangeNotifier::OnConnectionError, base::Unretained(this)));
cookie_manager->AddGlobalChangeListener(std::move(listener_ptr));
}
void CookieChangeNotifier::OnConnectionError() {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
binding_.Close();
StartListening();
}
void CookieChangeNotifier::OnCookieChange(
const net::CanonicalCookie& cookie,
network::mojom::CookieChangeCause cause) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
CookieDetails cookie_details(
&cookie, cause != network::mojom::CookieChangeCause::INSERTED, cause);
cookie_change_sub_list_.Notify(&cookie_details);
}
} // namespace atom

View File

@@ -0,0 +1,48 @@
// Copyright (c) 2018 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef ATOM_BROWSER_COOKIE_CHANGE_NOTIFIER_H_
#define ATOM_BROWSER_COOKIE_CHANGE_NOTIFIER_H_
#include <memory>
#include "base/callback_list.h"
#include "base/macros.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "services/network/public/mojom/cookie_manager.mojom.h"
namespace atom {
class AtomBrowserContext;
struct CookieDetails;
// Sends cookie-change notifications on the UI thread.
class CookieChangeNotifier : public network::mojom::CookieChangeListener {
public:
explicit CookieChangeNotifier(AtomBrowserContext* browser_context);
~CookieChangeNotifier() override;
// Register callbacks that needs to notified on any cookie store changes.
std::unique_ptr<base::CallbackList<void(const CookieDetails*)>::Subscription>
RegisterCookieChangeCallback(
const base::Callback<void(const CookieDetails*)>& cb);
private:
void StartListening();
void OnConnectionError();
// network::mojom::CookieChangeListener implementation.
void OnCookieChange(const net::CanonicalCookie& cookie,
network::mojom::CookieChangeCause cause) override;
AtomBrowserContext* browser_context_;
base::CallbackList<void(const CookieDetails*)> cookie_change_sub_list_;
mojo::Binding<network::mojom::CookieChangeListener> binding_;
DISALLOW_COPY_AND_ASSIGN(CookieChangeNotifier);
};
} // namespace atom
#endif // ATOM_BROWSER_COOKIE_CHANGE_NOTIFIER_H_

80
atom/browser/io_thread.cc Normal file
View File

@@ -0,0 +1,80 @@
// Copyright (c) 2017 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/browser/io_thread.h"
#include "components/net_log/chrome_net_log.h"
#include "content/public/browser/browser_thread.h"
#include "net/proxy_resolution/proxy_service.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_context_builder.h"
#include "net/url_request/url_request_context_getter.h"
#if defined(USE_NSS_CERTS)
#include "net/cert_net/nss_ocsp.h"
#endif
#if defined(OS_LINUX) || defined(OS_MACOSX)
#include "net/cert/cert_net_fetcher.h"
#include "net/cert_net/cert_net_fetcher_impl.h"
#endif
using content::BrowserThread;
namespace atom {
IOThread::IOThread(net_log::ChromeNetLog* net_log) : net_log_(net_log) {
BrowserThread::SetIOThreadDelegate(this);
}
IOThread::~IOThread() {
BrowserThread::SetIOThreadDelegate(nullptr);
}
void IOThread::Init() {
net::URLRequestContextBuilder builder;
// TODO(deepak1556): We need to respoect user proxy configurations,
// the following initialization has to happen before any request
// contexts are utilized by the io thread, so that proper cert validation
// take place, solutions:
// 1) Use the request context from default partition, but since
// an app can completely run on a custom session without ever creating
// the default session, we will have to force create the default session
// in those scenarios.
// 2) Add a new api on app module that sets the proxy configuration
// for the global requests, like the cert fetchers below and
// geolocation requests.
// 3) There is also ongoing work in upstream which will eventually allow
// localizing these global fetchers to their own URLRequestContexts.
builder.set_proxy_resolution_service(
net::ProxyResolutionService::CreateDirect());
url_request_context_ = builder.Build();
url_request_context_getter_ = new net::TrivialURLRequestContextGetter(
url_request_context_.get(), base::ThreadTaskRunnerHandle::Get());
#if defined(USE_NSS_CERTS)
net::SetURLRequestContextForNSSHttpIO(url_request_context_.get());
#endif
#if defined(OS_LINUX) || defined(OS_MACOSX)
net::SetGlobalCertNetFetcher(
net::CreateCertNetFetcher(url_request_context_.get()));
#endif
}
void IOThread::CleanUp() {
#if defined(USE_NSS_CERTS)
net::SetURLRequestContextForNSSHttpIO(nullptr);
#endif
#if defined(OS_LINUX) || defined(OS_MACOSX)
net::ShutdownGlobalCertNetFetcher();
#endif
// Explicitly release before the IO thread gets destroyed.
url_request_context_.reset();
url_request_context_getter_ = nullptr;
if (net_log_)
net_log_->ShutDownBeforeTaskScheduler();
}
} // namespace atom

View File

@@ -2,12 +2,13 @@
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef BRIGHTRAY_BROWSER_IO_THREAD_H_
#define BRIGHTRAY_BROWSER_IO_THREAD_H_
#ifndef ATOM_BROWSER_IO_THREAD_H_
#define ATOM_BROWSER_IO_THREAD_H_
#include <memory>
#include "base/macros.h"
#include "base/memory/scoped_refptr.h"
#include "content/public/browser/browser_thread_delegate.h"
namespace net {
@@ -15,15 +16,19 @@ class URLRequestContext;
class URLRequestContextGetter;
} // namespace net
namespace brightray {
namespace net_log {
class ChromeNetLog;
}
namespace atom {
class IOThread : public content::BrowserThreadDelegate {
public:
IOThread();
explicit IOThread(net_log::ChromeNetLog* net_log);
~IOThread() override;
net::URLRequestContextGetter* GetRequestContext() {
return url_request_context_getter_;
return url_request_context_getter_.get();
}
protected:
@@ -32,12 +37,15 @@ class IOThread : public content::BrowserThreadDelegate {
void CleanUp() override;
private:
// The NetLog is owned by the browser process, to allow logging from other
// threads during shutdown, but is used most frequently on the IOThread.
net_log::ChromeNetLog* net_log_;
std::unique_ptr<net::URLRequestContext> url_request_context_;
net::URLRequestContextGetter* url_request_context_getter_;
scoped_refptr<net::URLRequestContextGetter> url_request_context_getter_;
DISALLOW_COPY_AND_ASSIGN(IOThread);
};
} // namespace brightray
} // namespace atom
#endif // BRIGHTRAY_BROWSER_IO_THREAD_H_
#endif // ATOM_BROWSER_IO_THREAD_H_

View File

@@ -32,21 +32,28 @@ namespace atom {
PowerObserverLinux::PowerObserverLinux()
: lock_owner_name_(get_executable_basename()), weak_ptr_factory_(this) {
auto* dbus_thread_manager = bluez::DBusThreadManagerLinux::Get();
if (dbus_thread_manager) {
bus_ = dbus_thread_manager->GetSystemBus();
if (bus_) {
logind_ = bus_->GetObjectProxy(kLogindServiceName,
dbus::ObjectPath(kLogindObjectPath));
logind_->WaitForServiceToBeAvailable(
base::Bind(&PowerObserverLinux::OnLoginServiceAvailable,
weak_ptr_factory_.GetWeakPtr()));
} else {
LOG(WARNING) << "Failed to get system bus connection";
}
} else {
LOG(WARNING) << "DBusThreadManagerLinux instance isn't available";
auto* bus = bluez::DBusThreadManagerLinux::Get()->GetSystemBus();
if (!bus) {
LOG(WARNING) << "Failed to get system bus connection";
return;
}
// set up the logind proxy
const auto weakThis = weak_ptr_factory_.GetWeakPtr();
logind_ = bus->GetObjectProxy(kLogindServiceName,
dbus::ObjectPath(kLogindObjectPath));
logind_->ConnectToSignal(
kLogindManagerInterface, "PrepareForShutdown",
base::BindRepeating(&PowerObserverLinux::OnPrepareForShutdown, weakThis),
base::BindRepeating(&PowerObserverLinux::OnSignalConnected, weakThis));
logind_->ConnectToSignal(
kLogindManagerInterface, "PrepareForSleep",
base::BindRepeating(&PowerObserverLinux::OnPrepareForSleep, weakThis),
base::BindRepeating(&PowerObserverLinux::OnSignalConnected, weakThis));
logind_->WaitForServiceToBeAvailable(base::BindRepeating(
&PowerObserverLinux::OnLoginServiceAvailable, weakThis));
}
PowerObserverLinux::~PowerObserverLinux() = default;
@@ -56,17 +63,6 @@ void PowerObserverLinux::OnLoginServiceAvailable(bool service_available) {
LOG(WARNING) << kLogindServiceName << " not available";
return;
}
// Connect to PrepareForShutdown/PrepareForSleep signals
logind_->ConnectToSignal(kLogindManagerInterface, "PrepareForShutdown",
base::Bind(&PowerObserverLinux::OnPrepareForShutdown,
weak_ptr_factory_.GetWeakPtr()),
base::Bind(&PowerObserverLinux::OnSignalConnected,
weak_ptr_factory_.GetWeakPtr()));
logind_->ConnectToSignal(kLogindManagerInterface, "PrepareForSleep",
base::Bind(&PowerObserverLinux::OnPrepareForSleep,
weak_ptr_factory_.GetWeakPtr()),
base::Bind(&PowerObserverLinux::OnSignalConnected,
weak_ptr_factory_.GetWeakPtr()));
// Take sleep inhibit lock
BlockSleep();
}
@@ -80,10 +76,10 @@ void PowerObserverLinux::BlockSleep() {
inhibit_writer.AppendString(lock_owner_name_); // who
inhibit_writer.AppendString("Application cleanup before suspend"); // why
inhibit_writer.AppendString("delay"); // mode
logind_->CallMethod(&sleep_inhibit_call,
dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
base::Bind(&PowerObserverLinux::OnInhibitResponse,
weak_ptr_factory_.GetWeakPtr(), &sleep_lock_));
logind_->CallMethod(
&sleep_inhibit_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
base::BindOnce(&PowerObserverLinux::OnInhibitResponse,
weak_ptr_factory_.GetWeakPtr(), &sleep_lock_));
}
void PowerObserverLinux::UnblockSleep() {
@@ -103,8 +99,8 @@ void PowerObserverLinux::BlockShutdown() {
inhibit_writer.AppendString("delay"); // mode
logind_->CallMethod(
&shutdown_inhibit_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
base::Bind(&PowerObserverLinux::OnInhibitResponse,
weak_ptr_factory_.GetWeakPtr(), &shutdown_lock_));
base::BindOnce(&PowerObserverLinux::OnInhibitResponse,
weak_ptr_factory_.GetWeakPtr(), &shutdown_lock_));
}
void PowerObserverLinux::UnblockShutdown() {
@@ -122,8 +118,10 @@ void PowerObserverLinux::SetShutdownHandler(base::Callback<bool()> handler) {
void PowerObserverLinux::OnInhibitResponse(base::ScopedFD* scoped_fd,
dbus::Response* response) {
dbus::MessageReader reader(response);
reader.PopFileDescriptor(scoped_fd);
if (response != nullptr) {
dbus::MessageReader reader(response);
reader.PopFileDescriptor(scoped_fd);
}
}
void PowerObserverLinux::OnPrepareForSleep(dbus::Signal* signal) {
@@ -158,7 +156,7 @@ void PowerObserverLinux::OnPrepareForShutdown(dbus::Signal* signal) {
}
}
void PowerObserverLinux::OnSignalConnected(const std::string& interface,
void PowerObserverLinux::OnSignalConnected(const std::string& /*interface*/,
const std::string& signal,
bool success) {
LOG_IF(WARNING, !success) << "Failed to connect to " << signal;

View File

@@ -40,7 +40,6 @@ class PowerObserverLinux : public base::PowerObserver {
base::Callback<bool()> should_shutdown_;
scoped_refptr<dbus::Bus> bus_;
scoped_refptr<dbus::ObjectProxy> logind_;
std::string lock_owner_name_;
base::ScopedFD sleep_lock_;

View File

@@ -22,7 +22,7 @@ LoginHandler::LoginHandler(
net::AuthCredentials* credentials,
const content::ResourceRequestInfo* resource_request_info)
: credentials_(credentials),
auth_info_(auth_info),
auth_info_(&auth_info),
auth_callback_(std::move(callback)),
weak_factory_(this) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);

View File

@@ -40,7 +40,7 @@ class LoginHandler : public base::RefCountedThreadSafe<LoginHandler> {
// thread.
content::WebContents* GetWebContents() const;
const net::AuthChallengeInfo* auth_info() const { return &auth_info_; }
const net::AuthChallengeInfo* auth_info() const { return auth_info_.get(); }
private:
friend class base::RefCountedThreadSafe<LoginHandler>;
@@ -56,7 +56,7 @@ class LoginHandler : public base::RefCountedThreadSafe<LoginHandler> {
net::AuthCredentials* credentials_;
// Who/where/what asked for the authentication.
const net::AuthChallengeInfo& auth_info_;
scoped_refptr<const net::AuthChallengeInfo> auth_info_;
// WebContents associated with the login request.
content::ResourceRequestInfo::WebContentsGetter web_contents_getter_;

View File

@@ -167,7 +167,7 @@ void FinishTransactionByDate(const std::string& date) {
std::string GetReceiptURL() {
NSURL* receiptURL = [[NSBundle mainBundle] appStoreReceiptURL];
if (receiptURL != nil) {
return [[receiptURL absoluteString] UTF8String];
return std::string([[receiptURL path] UTF8String]);
} else {
return "";
}

View File

@@ -8,6 +8,7 @@
#include <map>
#include <memory>
#include <string>
#include <tuple>
#include <vector>
#include "atom/browser/native_window_observer.h"
@@ -44,6 +45,12 @@ class NativeBrowserView;
struct DraggableRegion;
#if defined(OS_MACOSX)
typedef NSView* NativeWindowHandle;
#else
typedef gfx::AcceleratedWidget NativeWindowHandle;
#endif
class NativeWindow : public base::SupportsUserData,
public views::WidgetDelegate {
public:
@@ -150,6 +157,7 @@ class NativeWindow : public base::SupportsUserData,
virtual gfx::NativeView GetNativeView() const = 0;
virtual gfx::NativeWindow GetNativeWindow() const = 0;
virtual gfx::AcceleratedWidget GetAcceleratedWidget() const = 0;
virtual NativeWindowHandle GetNativeWindowHandle() const = 0;
// Taskbar/Dock APIs.
enum ProgressState {

View File

@@ -8,6 +8,7 @@
#import <Cocoa/Cocoa.h>
#include <string>
#include <tuple>
#include <vector>
#include "atom/browser/native_window.h"
@@ -103,6 +104,7 @@ class NativeWindowMac : public NativeWindow {
gfx::NativeView GetNativeView() const override;
gfx::NativeWindow GetNativeWindow() const override;
gfx::AcceleratedWidget GetAcceleratedWidget() const override;
NativeWindowHandle GetNativeWindowHandle() const override;
void SetProgressBar(double progress, const ProgressState state) override;
void SetOverlayIcon(const gfx::Image& overlay,
const std::string& description) override;
@@ -199,6 +201,7 @@ class NativeWindowMac : public NativeWindow {
bool was_maximizable_ = false;
bool was_movable_ = false;
NSRect original_frame_;
NSInteger original_level_;
NSUInteger simple_fullscreen_mask_;
base::scoped_nsobject<NSColor> background_color_before_vibrancy_;

View File

@@ -74,9 +74,7 @@
forStyleMask:NSTitledWindowMask];
NSButton* miniaturize_button =
[NSWindow standardWindowButton:NSWindowMiniaturizeButton
forStyleMask:NSTitledWindowMask];
NSButton* zoom_button = [NSWindow standardWindowButton:NSWindowZoomButton
forStyleMask:NSTitledWindowMask];
forStyleMask:NSWindowStyleMaskTitled];
CGFloat x = 0;
const CGFloat space_between = 20;
@@ -89,11 +87,7 @@
x += space_between;
[self addSubview:miniaturize_button];
[zoom_button setFrameOrigin:NSMakePoint(x, 0)];
x += space_between;
[self addSubview:zoom_button];
const auto last_button_frame = zoom_button.frame;
const auto last_button_frame = miniaturize_button.frame;
[self setFrameSize:NSMakeSize(last_button_frame.origin.x +
last_button_frame.size.width,
last_button_frame.size.height)];
@@ -339,6 +333,9 @@ NativeWindowMac::NativeWindowMac(const mate::Dictionary& options,
if (!useStandardWindow || transparent() || !has_frame()) {
styleMask |= NSTexturedBackgroundWindowMask;
}
if (resizable_) {
styleMask |= NSResizableWindowMask;
}
// Create views::Widget and assign window_ with it.
// TODO(zcbenz): Get rid of the window_ in future.
@@ -469,10 +466,14 @@ NativeWindowMac::NativeWindowMac(const mate::Dictionary& options,
// Default content view.
SetContentView(new views::View());
AddContentViewLayers();
original_frame_ = [window_ frame];
original_level_ = [window_ level];
}
NativeWindowMac::~NativeWindowMac() {
[NSEvent removeMonitor:wheel_event_monitor_];
if (wheel_event_monitor_)
[NSEvent removeMonitor:wheel_event_monitor_];
}
void NativeWindowMac::SetContentView(views::View* view) {
@@ -509,6 +510,18 @@ void NativeWindowMac::Close() {
}
void NativeWindowMac::CloseImmediately() {
// Remove event monitor before destroying window, otherwise the monitor may
// call its callback after window has been destroyed.
if (wheel_event_monitor_) {
[NSEvent removeMonitor:wheel_event_monitor_];
wheel_event_monitor_ = nil;
}
// Retain the child window before closing it. If the last reference to the
// NSWindow goes away inside -[NSWindow close], then bad stuff can happen.
// See e.g. http://crbug.com/616701.
base::scoped_nsobject<NSWindow> child_window(window_,
base::scoped_policy::RETAIN);
[window_ close];
}
@@ -580,13 +593,13 @@ bool NativeWindowMac::IsEnabled() {
void NativeWindowMac::SetEnabled(bool enable) {
if (enable) {
[window_ endSheet:[window_ attachedSheet]];
} else {
[window_ beginSheet:window_
completionHandler:^(NSModalResponse returnCode) {
NSLog(@"modal enabled");
return;
}];
} else {
[window_ endSheet:[window_ attachedSheet]];
}
}
@@ -859,8 +872,9 @@ void NativeWindowMac::SetSimpleFullScreen(bool simple_fullscreen) {
if (simple_fullscreen && !is_simple_fullscreen_) {
is_simple_fullscreen_ = true;
// Take note of the current window size
// Take note of the current window size and level
original_frame_ = [window frame];
original_level_ = [window level];
simple_fullscreen_options_ = [NSApp currentSystemPresentationOptions];
simple_fullscreen_mask_ = [window styleMask];
@@ -877,6 +891,13 @@ void NativeWindowMac::SetSimpleFullScreen(bool simple_fullscreen) {
NSRect fullscreenFrame = [window.screen frame];
// If our app has dock hidden, set the window level higher so another app's
// menu bar doesn't appear on top of our fullscreen app.
if ([[NSRunningApplication currentApplication] activationPolicy] !=
NSApplicationActivationPolicyRegular) {
window.level = NSPopUpMenuWindowLevel;
}
if (!fullscreen_window_title()) {
// Hide the titlebar
SetStyleMask(false, NSTitledWindowMask);
@@ -912,6 +933,7 @@ void NativeWindowMac::SetSimpleFullScreen(bool simple_fullscreen) {
}
[window setFrame:original_frame_ display:YES animate:YES];
window.level = original_level_;
[NSApp setPresentationOptions:simple_fullscreen_options_];
@@ -1019,6 +1041,9 @@ void NativeWindowMac::SetContentProtection(bool enable) {
}
void NativeWindowMac::SetBrowserView(NativeBrowserView* view) {
[CATransaction begin];
[CATransaction setDisableActions:YES];
if (browser_view()) {
[browser_view()->GetInspectableWebContentsView()->GetNativeView()
removeFromSuperview];
@@ -1026,6 +1051,7 @@ void NativeWindowMac::SetBrowserView(NativeBrowserView* view) {
}
if (!view) {
[CATransaction commit];
return;
}
@@ -1035,6 +1061,8 @@ void NativeWindowMac::SetBrowserView(NativeBrowserView* view) {
positioned:NSWindowAbove
relativeTo:nil];
native_view.hidden = NO;
[CATransaction commit];
}
void NativeWindowMac::SetParentWindow(NativeWindow* parent) {
@@ -1053,21 +1081,31 @@ gfx::AcceleratedWidget NativeWindowMac::GetAcceleratedWidget() const {
return gfx::kNullAcceleratedWidget;
}
NativeWindowHandle NativeWindowMac::GetNativeWindowHandle() const {
return [window_ contentView];
}
void NativeWindowMac::SetProgressBar(double progress,
const NativeWindow::ProgressState state) {
NSDockTile* dock_tile = [NSApp dockTile];
// Sometimes macOS would install a default contentView for dock, we must
// verify whether NSProgressIndicator has been installed.
bool first_time = !dock_tile.contentView ||
[[dock_tile.contentView subviews] count] == 0 ||
![[[dock_tile.contentView subviews] lastObject]
isKindOfClass:[NSProgressIndicator class]];
// For the first time API invoked, we need to create a ContentView in
// DockTile.
if (dock_tile.contentView == nullptr) {
NSImageView* image_view = [[NSImageView alloc] init];
if (first_time) {
NSImageView* image_view = [[[NSImageView alloc] init] autorelease];
[image_view setImage:[NSApp applicationIconImage]];
[dock_tile setContentView:image_view];
}
if ([[dock_tile.contentView subviews] count] == 0) {
NSProgressIndicator* progress_indicator = [[AtomProgressBar alloc]
initWithFrame:NSMakeRect(0.0f, 0.0f, dock_tile.size.width, 15.0)];
NSRect frame = NSMakeRect(0.0f, 0.0f, dock_tile.size.width, 15.0);
NSProgressIndicator* progress_indicator =
[[[AtomProgressBar alloc] initWithFrame:frame] autorelease];
[progress_indicator setStyle:NSProgressIndicatorBarStyle];
[progress_indicator setIndeterminate:NO];
[progress_indicator setBezeled:YES];
@@ -1078,7 +1116,7 @@ void NativeWindowMac::SetProgressBar(double progress,
}
NSProgressIndicator* progress_indicator = static_cast<NSProgressIndicator*>(
[[[dock_tile contentView] subviews] objectAtIndex:0]);
[[[dock_tile contentView] subviews] lastObject]);
if (progress < 0) {
[progress_indicator setHidden:YES];
} else if (progress > 1) {
@@ -1330,6 +1368,8 @@ void NativeWindowMac::AddContentViewLayers() {
if (title_bar_style_ == CUSTOM_BUTTONS_ON_HOVER) {
buttons_view_.reset(
[[CustomWindowButtonView alloc] initWithFrame:NSZeroRect]);
// NSWindowStyleMaskFullSizeContentView does not work with zoom button
SetFullScreenable(false);
[[window_ contentView] addSubview:buttons_view_];
} else {
if (title_bar_style_ != NORMAL) {

View File

@@ -9,6 +9,7 @@
#include <wrl/client.h>
#endif
#include <tuple>
#include <vector>
#include "atom/browser/api/atom_api_web_contents.h"
@@ -342,7 +343,7 @@ bool NativeWindowViews::IsFocused() {
void NativeWindowViews::Show() {
if (is_modal() && NativeWindow::parent() &&
!widget()->native_widget_private()->IsVisible())
NativeWindow::parent()->SetEnabled(false);
static_cast<NativeWindowViews*>(parent())->IncrementChildModals();
widget()->native_widget_private()->ShowWithWindowState(GetRestoredState());
@@ -367,7 +368,7 @@ void NativeWindowViews::ShowInactive() {
void NativeWindowViews::Hide() {
if (is_modal() && NativeWindow::parent())
NativeWindow::parent()->SetEnabled(true);
static_cast<NativeWindowViews*>(parent())->DecrementChildModals();
widget()->Hide();
@@ -391,16 +392,34 @@ bool NativeWindowViews::IsEnabled() {
#endif
}
void NativeWindowViews::IncrementChildModals() {
num_modal_children_++;
SetEnabledInternal(ShouldBeEnabled());
}
void NativeWindowViews::DecrementChildModals() {
if (num_modal_children_ > 0) {
num_modal_children_--;
}
SetEnabledInternal(ShouldBeEnabled());
}
void NativeWindowViews::SetEnabled(bool enable) {
// Handle multiple calls of SetEnabled correctly.
if (enable) {
--disable_count_;
if (disable_count_ != 0)
return;
} else {
++disable_count_;
if (disable_count_ != 1)
return;
if (enable != is_enabled_) {
is_enabled_ = enable;
SetEnabledInternal(ShouldBeEnabled());
}
}
bool NativeWindowViews::ShouldBeEnabled() {
return is_enabled_ && (num_modal_children_ == 0);
}
void NativeWindowViews::SetEnabledInternal(bool enable) {
if (enable && IsEnabled()) {
return;
} else if (!enable && !IsEnabled()) {
return;
}
#if defined(OS_WIN)
@@ -585,6 +604,7 @@ void NativeWindowViews::SetResizable(bool resizable) {
// both the minimum and maximum size to the window size to achieve it.
if (resizable) {
SetContentSizeConstraints(old_size_constraints_);
SetMaximizable(maximizable_);
} else {
old_size_constraints_ = GetContentSizeConstraints();
resizable_ = false;
@@ -872,14 +892,17 @@ void NativeWindowViews::SetFocusable(bool focusable) {
void NativeWindowViews::SetMenu(AtomMenuModel* menu_model) {
#if defined(USE_X11)
if (menu_model == nullptr)
if (menu_model == nullptr) {
global_menu_bar_.reset();
root_view_->UnregisterAcceleratorsWithFocusManager();
}
if (!global_menu_bar_ && ShouldUseGlobalMenuBar())
global_menu_bar_.reset(new GlobalMenuBarX11(this));
// Use global application menu bar when possible.
if (global_menu_bar_ && global_menu_bar_->IsServerStarted()) {
root_view_->RegisterAcceleratorsWithFocusManager(menu_model);
global_menu_bar_->SetMenu(menu_model);
return;
}
@@ -1024,6 +1047,10 @@ gfx::AcceleratedWidget NativeWindowViews::GetAcceleratedWidget() const {
return GetNativeWindow()->GetHost()->GetAcceleratedWidget();
}
NativeWindowHandle NativeWindowViews::GetNativeWindowHandle() const {
return GetAcceleratedWidget();
}
gfx::Rect NativeWindowViews::ContentBoundsToWindowBounds(
const gfx::Rect& bounds) const {
if (!has_frame())
@@ -1151,10 +1178,10 @@ void NativeWindowViews::OnWidgetBoundsChanged(views::Widget* changed_widget,
}
void NativeWindowViews::DeleteDelegate() {
if (is_modal() && NativeWindow::parent()) {
auto* parent = NativeWindow::parent();
if (is_modal() && this->parent()) {
auto* parent = this->parent();
// Enable parent window after current window gets closed.
parent->SetEnabled(true);
static_cast<NativeWindowViews*>(parent)->DecrementChildModals();
// Focus on parent window.
parent->Focus(true);
}

View File

@@ -9,6 +9,7 @@
#include <set>
#include <string>
#include <tuple>
#include "ui/views/widget/widget_observer.h"
@@ -123,12 +124,16 @@ class NativeWindowViews : public NativeWindow,
bool IsVisibleOnAllWorkspaces() override;
gfx::AcceleratedWidget GetAcceleratedWidget() const override;
NativeWindowHandle GetNativeWindowHandle() const override;
gfx::Rect ContentBoundsToWindowBounds(const gfx::Rect& bounds) const override;
gfx::Rect WindowBoundsToContentBounds(const gfx::Rect& bounds) const override;
void UpdateDraggableRegions(std::unique_ptr<SkRegion> region);
void IncrementChildModals();
void DecrementChildModals();
#if defined(OS_WIN)
void SetIcon(HICON small_icon, HICON app_icon);
#elif defined(USE_X11)
@@ -185,6 +190,10 @@ class NativeWindowViews : public NativeWindow,
LPARAM l_param);
#endif
// Enable/disable:
bool ShouldBeEnabled();
void SetEnabledInternal(bool enabled);
// NativeWindow:
void HandleKeyboardEvent(
content::WebContents*,
@@ -268,8 +277,11 @@ class NativeWindowViews : public NativeWindow,
// has to been explicitly provided.
std::unique_ptr<SkRegion> draggable_region_; // used in custom drag.
// How many times the Disable has been called.
int disable_count_ = 0;
// Whether the window should be enabled based on user calls to SetEnabled()
bool is_enabled_ = true;
// How many modal children this window has;
// used to determine enabled state
unsigned int num_modal_children_ = 0;
bool use_content_size_ = false;
bool movable_ = true;

View File

@@ -69,7 +69,7 @@ scoped_refptr<AtomURLRequest> AtomURLRequest::Create(
if (!browser_context || url.empty() || !delegate) {
return nullptr;
}
scoped_refptr<brightray::URLRequestContextGetter> request_context_getter(
scoped_refptr<net::URLRequestContextGetter> request_context_getter(
browser_context->GetRequestContext());
DCHECK(request_context_getter);
scoped_refptr<AtomURLRequest> atom_url_request(new AtomURLRequest(delegate));

View File

@@ -5,6 +5,8 @@
#include "atom/browser/net/atom_url_request_job_factory.h"
#include <utility>
#include "base/memory/ptr_util.h"
#include "base/stl_util.h"
#include "content/public/browser/browser_thread.h"
@@ -33,6 +35,11 @@ AtomURLRequestJobFactory::~AtomURLRequestJobFactory() {
Clear();
}
void AtomURLRequestJobFactory::Chain(
std::unique_ptr<net::URLRequestJobFactory> job_factory) {
job_factory_ = std::move(job_factory);
}
bool AtomURLRequestJobFactory::SetProtocolHandler(
const std::string& scheme,
std::unique_ptr<ProtocolHandler> protocol_handler) {
@@ -73,16 +80,6 @@ bool AtomURLRequestJobFactory::UninterceptProtocol(const std::string& scheme) {
return true;
}
ProtocolHandler* AtomURLRequestJobFactory::GetProtocolHandler(
const std::string& scheme) const {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
auto it = protocol_handler_map_.find(scheme);
if (it == protocol_handler_map_.end())
return nullptr;
return it->second;
}
bool AtomURLRequestJobFactory::HasProtocolHandler(
const std::string& scheme) const {
return base::ContainsKey(protocol_handler_map_, scheme);
@@ -101,11 +98,18 @@ net::URLRequestJob* AtomURLRequestJobFactory::MaybeCreateJobWithProtocolHandler(
net::NetworkDelegate* network_delegate) const {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
auto* job = job_factory_->MaybeCreateJobWithProtocolHandler(scheme, request,
network_delegate);
if (job)
return job;
auto it = protocol_handler_map_.find(scheme);
if (it == protocol_handler_map_.end())
return nullptr;
if (request->GetUserData(DisableProtocolInterceptFlagKey()))
return nullptr;
return it->second->MaybeCreateJob(request, network_delegate);
}
@@ -113,13 +117,14 @@ net::URLRequestJob* AtomURLRequestJobFactory::MaybeInterceptRedirect(
net::URLRequest* request,
net::NetworkDelegate* network_delegate,
const GURL& location) const {
return nullptr;
return job_factory_->MaybeInterceptRedirect(request, network_delegate,
location);
}
net::URLRequestJob* AtomURLRequestJobFactory::MaybeInterceptResponse(
net::URLRequest* request,
net::NetworkDelegate* network_delegate) const {
return nullptr;
return job_factory_->MaybeInterceptResponse(request, network_delegate);
}
bool AtomURLRequestJobFactory::IsHandledProtocol(

View File

@@ -23,6 +23,9 @@ class AtomURLRequestJobFactory : public net::URLRequestJobFactory {
AtomURLRequestJobFactory();
~AtomURLRequestJobFactory() override;
// Requests are forwarded to the chained job factory first.
void Chain(std::unique_ptr<net::URLRequestJobFactory> job_factory);
// Sets the ProtocolHandler for a scheme. Returns true on success, false on
// failure (a ProtocolHandler already exists for |scheme|). On success,
// URLRequestJobFactory takes ownership of |protocol_handler|.
@@ -34,9 +37,6 @@ class AtomURLRequestJobFactory : public net::URLRequestJobFactory {
std::unique_ptr<ProtocolHandler> protocol_handler);
bool UninterceptProtocol(const std::string& scheme);
// Returns the protocol handler registered with scheme.
ProtocolHandler* GetProtocolHandler(const std::string& scheme) const;
// Whether the protocol handler is registered by the job factory.
bool HasProtocolHandler(const std::string& scheme) const;
@@ -69,6 +69,8 @@ class AtomURLRequestJobFactory : public net::URLRequestJobFactory {
// Can only be accessed in IO thread.
OriginalProtocolsMap original_protocols_;
std::unique_ptr<net::URLRequestJobFactory> job_factory_;
DISALLOW_COPY_AND_ASSIGN(AtomURLRequestJobFactory);
};

View File

@@ -6,7 +6,11 @@
#define ATOM_BROWSER_NET_COOKIE_DETAILS_H_
#include "base/macros.h"
#include "net/cookies/cookie_change_dispatcher.h"
#include "services/network/public/mojom/cookie_manager.mojom.h"
namespace net {
class CanonicalCookie;
}
namespace atom {
@@ -14,12 +18,12 @@ struct CookieDetails {
public:
CookieDetails(const net::CanonicalCookie* cookie_copy,
bool is_removed,
net::CookieChangeCause cause)
network::mojom::CookieChangeCause cause)
: cookie(cookie_copy), removed(is_removed), cause(cause) {}
const net::CanonicalCookie* cookie;
bool removed;
net::CookieChangeCause cause;
network::mojom::CookieChangeCause cause;
};
} // namespace atom

View File

@@ -0,0 +1,87 @@
// Copyright (c) 2018 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/browser/net/resolve_proxy_helper.h"
#include "atom/browser/atom_browser_context.h"
#include "base/bind.h"
#include "base/threading/thread_task_runner_handle.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_context_getter.h"
namespace atom {
ResolveProxyHelper::ResolveProxyHelper(AtomBrowserContext* browser_context)
: context_getter_(browser_context->GetRequestContext()),
original_thread_(base::ThreadTaskRunnerHandle::Get()) {}
ResolveProxyHelper::~ResolveProxyHelper() {
// Clear all pending requests if the ProxyService is still alive.
pending_requests_.clear();
}
void ResolveProxyHelper::ResolveProxy(const GURL& url,
const ResolveProxyCallback& callback) {
// Enqueue the pending request.
pending_requests_.push_back(PendingRequest(url, callback));
// If nothing is in progress, start.
if (pending_requests_.size() == 1)
StartPendingRequest();
}
void ResolveProxyHelper::StartPendingRequest() {
auto& pending_request = pending_requests_.front();
context_getter_->GetNetworkTaskRunner()->PostTask(
FROM_HERE, base::BindOnce(&ResolveProxyHelper::StartPendingRequestInIO,
base::Unretained(this), pending_request.url));
}
void ResolveProxyHelper::StartPendingRequestInIO(const GURL& url) {
auto* proxy_service =
context_getter_->GetURLRequestContext()->proxy_resolution_service();
// Start the request.
int result = proxy_service->ResolveProxy(
url, std::string(), &proxy_info_,
base::Bind(&ResolveProxyHelper::OnProxyResolveComplete,
base::RetainedRef(this)),
nullptr, nullptr, net::NetLogWithSource());
// Completed synchronously.
if (result != net::ERR_IO_PENDING)
OnProxyResolveComplete(result);
}
void ResolveProxyHelper::OnProxyResolveComplete(int result) {
DCHECK(!pending_requests_.empty());
std::string proxy;
if (result == net::OK)
proxy = proxy_info_.ToPacString();
original_thread_->PostTask(
FROM_HERE, base::BindOnce(&ResolveProxyHelper::SendProxyResult,
base::RetainedRef(this), proxy));
}
void ResolveProxyHelper::SendProxyResult(const std::string& proxy) {
DCHECK(!pending_requests_.empty());
const auto& completed_request = pending_requests_.front();
if (!completed_request.callback.is_null())
completed_request.callback.Run(proxy);
// Clear the current (completed) request.
pending_requests_.pop_front();
// Start the next request.
if (!pending_requests_.empty())
StartPendingRequest();
}
ResolveProxyHelper::PendingRequest::PendingRequest(
const GURL& url,
const ResolveProxyCallback& callback)
: url(url), callback(callback) {}
} // namespace atom

View File

@@ -0,0 +1,61 @@
// Copyright (c) 2018 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef ATOM_BROWSER_NET_RESOLVE_PROXY_HELPER_H_
#define ATOM_BROWSER_NET_RESOLVE_PROXY_HELPER_H_
#include <deque>
#include <string>
#include "base/memory/ref_counted.h"
#include "net/proxy_resolution/proxy_service.h"
#include "url/gurl.h"
namespace net {
class URLRequestContextGetter;
}
namespace atom {
class AtomBrowserContext;
class ResolveProxyHelper
: public base::RefCountedThreadSafe<ResolveProxyHelper> {
public:
using ResolveProxyCallback = base::Callback<void(std::string)>;
explicit ResolveProxyHelper(AtomBrowserContext* browser_context);
void ResolveProxy(const GURL& url, const ResolveProxyCallback& callback);
private:
friend class base::RefCountedThreadSafe<ResolveProxyHelper>;
// A PendingRequest is a resolve request that is in progress, or queued.
struct PendingRequest {
public:
PendingRequest(const GURL& url, const ResolveProxyCallback& callback);
GURL url;
ResolveProxyCallback callback;
};
~ResolveProxyHelper();
// Starts the first pending request.
void StartPendingRequest();
void StartPendingRequestInIO(const GURL& url);
void OnProxyResolveComplete(int result);
void SendProxyResult(const std::string& proxy);
net::ProxyInfo proxy_info_;
std::deque<PendingRequest> pending_requests_;
scoped_refptr<net::URLRequestContextGetter> context_getter_;
scoped_refptr<base::SingleThreadTaskRunner> original_thread_;
DISALLOW_COPY_AND_ASSIGN(ResolveProxyHelper);
};
} // namespace atom
#endif // ATOM_BROWSER_NET_RESOLVE_PROXY_HELPER_H_

View File

@@ -0,0 +1,424 @@
// Copyright (c) 2018 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/browser/net/url_request_context_getter.h"
#include <algorithm>
#include <memory>
#include <utility>
#include "atom/browser/api/atom_api_protocol.h"
#include "atom/browser/atom_browser_client.h"
#include "atom/browser/atom_browser_context.h"
#include "atom/browser/net/about_protocol_handler.h"
#include "atom/browser/net/asar/asar_protocol_handler.h"
#include "atom/browser/net/atom_cert_verifier.h"
#include "atom/browser/net/atom_network_delegate.h"
#include "atom/browser/net/atom_url_request_job_factory.h"
#include "atom/browser/net/http_protocol_handler.h"
#include "atom/common/options_switches.h"
#include "base/command_line.h"
#include "base/strings/string_util.h"
#include "base/task_scheduler/post_task.h"
#include "brightray/browser/net/require_ct_delegate.h"
#include "chrome/browser/net/chrome_mojo_proxy_resolver_factory.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/pref_names.h"
#include "components/network_session_configurator/common/network_switches.h"
#include "components/prefs/value_map_pref_store.h"
#include "components/proxy_config/proxy_config_dictionary.h"
#include "components/proxy_config/proxy_config_pref_names.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/devtools_network_transaction_factory.h"
#include "content/public/browser/network_service_instance.h"
#include "content/public/browser/resource_context.h"
#include "content/public/common/content_switches.h"
#include "net/base/host_mapping_rules.h"
#include "net/cert/multi_log_ct_verifier.h"
#include "net/cookies/cookie_monster.h"
#include "net/dns/mapped_host_resolver.h"
#include "net/http/http_auth_handler_factory.h"
#include "net/http/http_auth_preferences.h"
#include "net/http/http_auth_scheme.h"
#include "net/http/http_transaction_factory.h"
#include "net/log/net_log.h"
#include "net/proxy_resolution/proxy_config.h"
#include "net/proxy_resolution/proxy_config_service.h"
#include "net/proxy_resolution/proxy_service.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
#include "net/url_request/data_protocol_handler.h"
#include "net/url_request/static_http_user_agent_settings.h"
#include "net/url_request/url_request_intercepting_job_factory.h"
#include "net/url_request/url_request_job_factory_impl.h"
#include "services/network/ignore_errors_cert_verifier.h"
#include "services/network/network_service.h"
#include "services/network/public/cpp/network_switches.h"
#include "services/network/url_request_context_builder_mojo.h"
#include "url/url_constants.h"
#if !BUILDFLAG(DISABLE_FTP_SUPPORT)
#include "net/url_request/ftp_protocol_handler.h"
#endif
using content::BrowserThread;
namespace atom {
namespace {
network::mojom::NetworkContextParamsPtr CreateDefaultNetworkContextParams(
const base::FilePath& base_path,
const std::string& user_agent,
bool in_memory,
bool use_cache,
int max_cache_size) {
network::mojom::NetworkContextParamsPtr network_context_params =
network::mojom::NetworkContextParams::New();
network_context_params->enable_brotli = true;
network_context_params->user_agent = user_agent;
network_context_params->http_cache_enabled = use_cache;
network_context_params->enable_data_url_support = false;
network_context_params->proxy_resolver_factory =
ChromeMojoProxyResolverFactory::CreateWithStrongBinding().PassInterface();
if (!in_memory) {
network_context_params->http_cache_path =
base_path.Append(chrome::kCacheDirname);
network_context_params->http_cache_max_size = max_cache_size;
network_context_params->http_server_properties_path =
base_path.Append(chrome::kNetworkPersistentStateFilename);
network_context_params->cookie_path =
base_path.Append(chrome::kCookieFilename);
network_context_params->channel_id_path =
base_path.Append(chrome::kChannelIDFilename);
network_context_params->restore_old_session_cookies = false;
network_context_params->persist_session_cookies = false;
}
// TODO(deepak1556): Decide the stand on chrome ct policy and
// enable it.
// See //net/docs/certificate-transparency.md
// network_context_params->enforce_chrome_ct_policy = true;
return network_context_params;
}
void SetupAtomURLRequestJobFactory(
content::ProtocolHandlerMap* protocol_handlers,
net::URLRequestContext* url_request_context,
AtomURLRequestJobFactory* job_factory) {
for (auto& protocol_handler : *protocol_handlers) {
job_factory->SetProtocolHandler(
protocol_handler.first,
base::WrapUnique(protocol_handler.second.release()));
}
protocol_handlers->clear();
job_factory->SetProtocolHandler(url::kAboutScheme,
std::make_unique<AboutProtocolHandler>());
job_factory->SetProtocolHandler(url::kDataScheme,
std::make_unique<net::DataProtocolHandler>());
job_factory->SetProtocolHandler(
url::kFileScheme,
std::make_unique<asar::AsarProtocolHandler>(
base::CreateTaskRunnerWithTraits(
{base::MayBlock(), base::TaskPriority::USER_BLOCKING,
base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN})));
job_factory->SetProtocolHandler(
url::kHttpScheme,
std::make_unique<HttpProtocolHandler>(url::kHttpScheme));
job_factory->SetProtocolHandler(
url::kHttpsScheme,
std::make_unique<HttpProtocolHandler>(url::kHttpsScheme));
job_factory->SetProtocolHandler(
url::kWsScheme, std::make_unique<HttpProtocolHandler>(url::kWsScheme));
job_factory->SetProtocolHandler(
url::kWssScheme, std::make_unique<HttpProtocolHandler>(url::kWssScheme));
#if !BUILDFLAG(DISABLE_FTP_SUPPORT)
auto* host_resolver = url_request_context->host_resolver();
job_factory->SetProtocolHandler(
url::kFtpScheme, net::FtpProtocolHandler::Create(host_resolver));
#endif
}
void ApplyProxyModeFromCommandLine(ValueMapPrefStore* pref_store) {
if (!pref_store)
return;
auto* command_line = base::CommandLine::ForCurrentProcess();
if (command_line->HasSwitch(::switches::kNoProxyServer)) {
pref_store->SetValue(proxy_config::prefs::kProxy,
ProxyConfigDictionary::CreateDirect(),
WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
} else if (command_line->HasSwitch(::switches::kProxyPacUrl)) {
std::string pac_script_url =
command_line->GetSwitchValueASCII(::switches::kProxyPacUrl);
pref_store->SetValue(proxy_config::prefs::kProxy,
ProxyConfigDictionary::CreatePacScript(
pac_script_url, false /* pac_mandatory */),
WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
} else if (command_line->HasSwitch(::switches::kProxyAutoDetect)) {
pref_store->SetValue(proxy_config::prefs::kProxy,
ProxyConfigDictionary::CreateAutoDetect(),
WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
} else if (command_line->HasSwitch(::switches::kProxyServer)) {
std::string proxy_server =
command_line->GetSwitchValueASCII(::switches::kProxyServer);
std::string bypass_list =
command_line->GetSwitchValueASCII(::switches::kProxyBypassList);
pref_store->SetValue(
proxy_config::prefs::kProxy,
ProxyConfigDictionary::CreateFixedServers(proxy_server, bypass_list),
WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
}
}
} // namespace
class ResourceContext : public content::ResourceContext {
public:
ResourceContext() = default;
~ResourceContext() override = default;
net::HostResolver* GetHostResolver() override {
if (request_context_)
return request_context_->host_resolver();
return nullptr;
}
net::URLRequestContext* GetRequestContext() override {
return request_context_;
}
private:
friend class URLRequestContextGetter;
net::URLRequestContext* request_context_ = nullptr;
DISALLOW_COPY_AND_ASSIGN(ResourceContext);
};
URLRequestContextGetter::Handle::Handle(
base::WeakPtr<AtomBrowserContext> browser_context)
: resource_context_(new ResourceContext),
browser_context_(browser_context),
initialized_(false) {}
URLRequestContextGetter::Handle::~Handle() {}
content::ResourceContext*
URLRequestContextGetter::Handle::GetResourceContext() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
LazyInitialize();
return resource_context_.get();
}
scoped_refptr<URLRequestContextGetter>
URLRequestContextGetter::Handle::CreateMainRequestContextGetter(
content::ProtocolHandlerMap* protocol_handlers,
content::URLRequestInterceptorScopedVector protocol_interceptors) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
DCHECK(!main_request_context_getter_.get());
LazyInitialize();
main_request_context_getter_ = new URLRequestContextGetter(
AtomBrowserClient::Get()->GetNetLog(), this, protocol_handlers,
std::move(protocol_interceptors));
return main_request_context_getter_;
}
scoped_refptr<URLRequestContextGetter>
URLRequestContextGetter::Handle::GetMainRequestContextGetter() {
return main_request_context_getter_;
}
network::mojom::NetworkContextPtr
URLRequestContextGetter::Handle::GetNetworkContext() {
if (!main_network_context_) {
main_network_context_request_ = mojo::MakeRequest(&main_network_context_);
}
return std::move(main_network_context_);
}
void URLRequestContextGetter::Handle::LazyInitialize() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
if (initialized_)
return;
initialized_ = true;
main_network_context_params_ = CreateDefaultNetworkContextParams(
browser_context_->GetPath(), browser_context_->GetUserAgent(),
browser_context_->IsOffTheRecord(), browser_context_->CanUseHttpCache(),
browser_context_->GetMaxCacheSize());
browser_context_->proxy_config_monitor()->AddToNetworkContextParams(
main_network_context_params_.get());
ApplyProxyModeFromCommandLine(browser_context_->in_memory_pref_store());
if (!main_network_context_request_.is_pending()) {
main_network_context_request_ = mojo::MakeRequest(&main_network_context_);
}
content::BrowserContext::EnsureResourceContextInitialized(
browser_context_.get());
}
void URLRequestContextGetter::Handle::ShutdownOnUIThread() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
if (main_request_context_getter_.get()) {
if (BrowserThread::IsThreadInitialized(BrowserThread::IO)) {
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::BindOnce(&URLRequestContextGetter::NotifyContextShuttingDown,
base::RetainedRef(main_request_context_getter_),
std::move(resource_context_)));
}
}
if (!BrowserThread::DeleteSoon(BrowserThread::IO, FROM_HERE, this))
delete this;
}
URLRequestContextGetter::URLRequestContextGetter(
net::NetLog* net_log,
URLRequestContextGetter::Handle* context_handle,
content::ProtocolHandlerMap* protocol_handlers,
content::URLRequestInterceptorScopedVector protocol_interceptors)
: net_log_(net_log),
context_handle_(context_handle),
url_request_context_(nullptr),
protocol_interceptors_(std::move(protocol_interceptors)),
context_shutting_down_(false) {
// Must first be created on the UI thread.
DCHECK_CURRENTLY_ON(BrowserThread::UI);
if (protocol_handlers)
std::swap(protocol_handlers_, *protocol_handlers);
}
URLRequestContextGetter::~URLRequestContextGetter() {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
// NotifyContextShuttingDown should have been called.
DCHECK(context_shutting_down_);
}
void URLRequestContextGetter::NotifyContextShuttingDown(
std::unique_ptr<ResourceContext> resource_context) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
context_shutting_down_ = true;
resource_context.reset();
http_auth_preferences_.reset();
net::URLRequestContextGetter::NotifyContextShuttingDown();
}
net::URLRequestContext* URLRequestContextGetter::GetURLRequestContext() {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (context_shutting_down_)
return nullptr;
if (!url_request_context_) {
auto& command_line = *base::CommandLine::ForCurrentProcess();
std::unique_ptr<network::URLRequestContextBuilderMojo> builder =
std::make_unique<network::URLRequestContextBuilderMojo>();
builder->set_network_delegate(std::make_unique<AtomNetworkDelegate>());
ct_delegate_.reset(new brightray::RequireCTDelegate);
auto cert_verifier = std::make_unique<AtomCertVerifier>(ct_delegate_.get());
builder->SetCertVerifier(std::move(cert_verifier));
builder->SetCreateHttpTransactionFactoryCallback(
base::BindOnce(&content::CreateDevToolsNetworkTransactionFactory));
std::unique_ptr<net::HostResolver> host_resolver =
net::HostResolver::CreateDefaultResolver(net_log_);
// --host-resolver-rules
if (command_line.HasSwitch(network::switches::kHostResolverRules)) {
auto remapped_resolver =
std::make_unique<net::MappedHostResolver>(std::move(host_resolver));
remapped_resolver->SetRulesFromString(command_line.GetSwitchValueASCII(
network::switches::kHostResolverRules));
host_resolver = std::move(remapped_resolver);
}
std::vector<std::string> supported_schemes = {
net::kBasicAuthScheme, net::kDigestAuthScheme,
net::kNegotiateAuthScheme, net::kNtlmAuthScheme};
http_auth_preferences_ =
std::make_unique<net::HttpAuthPreferences>(supported_schemes
#if defined(OS_POSIX)
,
std::string()
#endif
); // NOLINT(whitespace/parens)
// --auth-server-whitelist
if (command_line.HasSwitch(switches::kAuthServerWhitelist)) {
http_auth_preferences_->SetServerWhitelist(
command_line.GetSwitchValueASCII(switches::kAuthServerWhitelist));
}
// --auth-negotiate-delegate-whitelist
if (command_line.HasSwitch(switches::kAuthNegotiateDelegateWhitelist)) {
http_auth_preferences_->SetDelegateWhitelist(
command_line.GetSwitchValueASCII(
switches::kAuthNegotiateDelegateWhitelist));
}
auto http_auth_handler_factory =
net::HttpAuthHandlerRegistryFactory::Create(
http_auth_preferences_.get(), host_resolver.get());
builder->SetHttpAuthHandlerFactory(std::move(http_auth_handler_factory));
builder->set_host_resolver(std::move(host_resolver));
builder->set_ct_verifier(std::make_unique<net::MultiLogCTVerifier>());
network_context_ =
content::GetNetworkServiceImpl()->CreateNetworkContextWithBuilder(
std::move(context_handle_->main_network_context_request_),
std::move(context_handle_->main_network_context_params_),
std::move(builder), &url_request_context_);
net::TransportSecurityState* transport_security_state =
url_request_context_->transport_security_state();
transport_security_state->SetRequireCTDelegate(ct_delegate_.get());
// Add custom standard schemes to cookie schemes.
auto* cookie_monster =
static_cast<net::CookieMonster*>(url_request_context_->cookie_store());
std::vector<std::string> cookie_schemes(
{url::kHttpScheme, url::kHttpsScheme, url::kWsScheme, url::kWssScheme});
const auto& custom_standard_schemes = atom::api::GetStandardSchemes();
cookie_schemes.insert(cookie_schemes.end(), custom_standard_schemes.begin(),
custom_standard_schemes.end());
cookie_monster->SetCookieableSchemes(cookie_schemes);
// Setup handlers for custom job factory.
top_job_factory_.reset(new AtomURLRequestJobFactory);
SetupAtomURLRequestJobFactory(&protocol_handlers_, url_request_context_,
top_job_factory_.get());
std::unique_ptr<net::URLRequestJobFactory> inner_job_factory(
new net::URLRequestJobFactoryImpl);
if (!protocol_interceptors_.empty()) {
// Set up interceptors in the reverse order.
for (auto it = protocol_interceptors_.rbegin();
it != protocol_interceptors_.rend(); ++it) {
inner_job_factory.reset(new net::URLRequestInterceptingJobFactory(
std::move(inner_job_factory), std::move(*it)));
}
protocol_interceptors_.clear();
}
top_job_factory_->Chain(std::move(inner_job_factory));
url_request_context_->set_job_factory(top_job_factory_.get());
context_handle_->resource_context_->request_context_ = url_request_context_;
}
return url_request_context_;
}
scoped_refptr<base::SingleThreadTaskRunner>
URLRequestContextGetter::GetNetworkTaskRunner() const {
return BrowserThread::GetTaskRunnerForThread(BrowserThread::IO);
}
} // namespace atom

View File

@@ -0,0 +1,119 @@
// Copyright (c) 2018 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef ATOM_BROWSER_NET_URL_REQUEST_CONTEXT_GETTER_H_
#define ATOM_BROWSER_NET_URL_REQUEST_CONTEXT_GETTER_H_
#include <memory>
#include <string>
#include <vector>
#include "base/files/file_path.h"
#include "content/public/browser/browser_context.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_context_getter.h"
#include "services/network/public/mojom/network_service.mojom.h"
#if DCHECK_IS_ON()
#include "base/debug/leak_tracker.h"
#endif
namespace brightray {
class RequireCTDelegate;
} // namespace brightray
namespace net {
class HttpAuthPreferences;
class NetLog;
} // namespace net
namespace atom {
class AtomBrowserContext;
class AtomURLRequestJobFactory;
class ResourceContext;
class URLRequestContextGetter : public net::URLRequestContextGetter {
public:
// net::URLRequestContextGetter:
net::URLRequestContext* GetURLRequestContext() override;
scoped_refptr<base::SingleThreadTaskRunner> GetNetworkTaskRunner()
const override;
// Discard reference to URLRequestContext and inform observers to
// shutdown. Must be called only on IO thread.
void NotifyContextShuttingDown(std::unique_ptr<ResourceContext>);
AtomURLRequestJobFactory* job_factory() const {
return top_job_factory_.get();
}
private:
friend class AtomBrowserContext;
// Responsible for destroying URLRequestContextGetter
// on the IO thread.
class Handle {
public:
explicit Handle(base::WeakPtr<AtomBrowserContext> browser_context);
~Handle();
scoped_refptr<URLRequestContextGetter> CreateMainRequestContextGetter(
content::ProtocolHandlerMap* protocol_handlers,
content::URLRequestInterceptorScopedVector protocol_interceptors);
content::ResourceContext* GetResourceContext();
scoped_refptr<URLRequestContextGetter> GetMainRequestContextGetter();
network::mojom::NetworkContextPtr GetNetworkContext();
void ShutdownOnUIThread();
private:
friend class URLRequestContextGetter;
void LazyInitialize();
scoped_refptr<URLRequestContextGetter> main_request_context_getter_;
std::unique_ptr<ResourceContext> resource_context_;
base::WeakPtr<AtomBrowserContext> browser_context_;
// This is a NetworkContext interface that uses URLRequestContextGetter
// NetworkContext, ownership is passed to StoragePartition when
// CreateMainNetworkContext is called.
network::mojom::NetworkContextPtr main_network_context_;
// Request corresponding to |main_network_context_|. Ownership
// is passed to network service.
network::mojom::NetworkContextRequest main_network_context_request_;
network::mojom::NetworkContextParamsPtr main_network_context_params_;
bool initialized_;
DISALLOW_COPY_AND_ASSIGN(Handle);
};
URLRequestContextGetter(
net::NetLog* net_log,
URLRequestContextGetter::Handle* context_handle,
content::ProtocolHandlerMap* protocol_handlers,
content::URLRequestInterceptorScopedVector protocol_interceptors);
~URLRequestContextGetter() override;
#if DCHECK_IS_ON()
base::debug::LeakTracker<URLRequestContextGetter> leak_tracker_;
#endif
std::unique_ptr<brightray::RequireCTDelegate> ct_delegate_;
std::unique_ptr<AtomURLRequestJobFactory> top_job_factory_;
std::unique_ptr<net::HttpAuthPreferences> http_auth_preferences_;
std::unique_ptr<network::mojom::NetworkContext> network_context_;
net::NetLog* net_log_;
URLRequestContextGetter::Handle* context_handle_;
net::URLRequestContext* url_request_context_;
content::ProtocolHandlerMap protocol_handlers_;
content::URLRequestInterceptorScopedVector protocol_interceptors_;
bool context_shutting_down_;
DISALLOW_COPY_AND_ASSIGN(URLRequestContextGetter);
};
} // namespace atom
#endif // ATOM_BROWSER_NET_URL_REQUEST_CONTEXT_GETTER_H_

View File

@@ -167,6 +167,9 @@ void URLRequestFetchJob::StartAsync(std::unique_ptr<base::Value> options) {
request()->extra_request_headers().ToString());
fetcher_->Start();
// URLFetcher has a refernce to the context, which
// will be cleared when the request is destroyed.
url_request_context_getter_ = nullptr;
}
void URLRequestFetchJob::HeadersCompleted() {
@@ -199,6 +202,7 @@ int URLRequestFetchJob::DataAvailable(net::IOBuffer* buffer,
void URLRequestFetchJob::Kill() {
JsAsker<URLRequestJob>::Kill();
fetcher_.reset();
custom_browser_context_ = nullptr;
}
int URLRequestFetchJob::ReadRawData(net::IOBuffer* dest, int dest_size) {

View File

@@ -0,0 +1,30 @@
// Copyright (c) 2018 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/browser/pref_store_delegate.h"
#include <utility>
#include "atom/browser/atom_browser_context.h"
#include "components/prefs/value_map_pref_store.h"
namespace atom {
PrefStoreDelegate::PrefStoreDelegate(
base::WeakPtr<AtomBrowserContext> browser_context)
: browser_context_(std::move(browser_context)) {}
PrefStoreDelegate::~PrefStoreDelegate() {
if (browser_context_)
browser_context_->set_in_memory_pref_store(nullptr);
}
void PrefStoreDelegate::UpdateCommandLinePrefStore(
PrefStore* command_line_prefs) {
if (browser_context_)
browser_context_->set_in_memory_pref_store(
static_cast<ValueMapPrefStore*>(command_line_prefs));
}
} // namespace atom

View File

@@ -0,0 +1,52 @@
// Copyright (c) 2018 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef ATOM_BROWSER_PREF_STORE_DELEGATE_H_
#define ATOM_BROWSER_PREF_STORE_DELEGATE_H_
#include <vector>
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "components/prefs/persistent_pref_store.h"
#include "components/prefs/pref_value_store.h"
namespace atom {
class AtomBrowserContext;
// Retrieves handle to the in memory pref store that gets
// initialized with the pref service.
class PrefStoreDelegate : public PrefValueStore::Delegate {
public:
explicit PrefStoreDelegate(base::WeakPtr<AtomBrowserContext> browser_context);
~PrefStoreDelegate() override;
void Init(PrefStore* managed_prefs,
PrefStore* supervised_user_prefs,
PrefStore* extension_prefs,
PrefStore* command_line_prefs,
PrefStore* user_prefs,
PrefStore* recommended_prefs,
PrefStore* default_prefs,
PrefNotifier* pref_notifier) override {}
void InitIncognitoUserPrefs(
scoped_refptr<PersistentPrefStore> incognito_user_prefs_overlay,
scoped_refptr<PersistentPrefStore> incognito_user_prefs_underlay,
const std::vector<const char*>& overlay_pref_names) override {}
void InitPrefRegistry(PrefRegistry* pref_registry) override {}
void UpdateCommandLinePrefStore(PrefStore* command_line_prefs) override;
private:
base::WeakPtr<AtomBrowserContext> browser_context_;
DISALLOW_COPY_AND_ASSIGN(PrefStoreDelegate);
};
} // namespace atom
#endif // ATOM_BROWSER_PREF_STORE_DELEGATE_H_

View File

@@ -1,163 +0,0 @@
// Copyright (c) 2018 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/browser/request_context_delegate.h"
#include "atom/browser/api/atom_api_protocol.h"
#include "atom/browser/net/about_protocol_handler.h"
#include "atom/browser/net/asar/asar_protocol_handler.h"
#include "atom/browser/net/atom_cert_verifier.h"
#include "atom/browser/net/atom_network_delegate.h"
#include "atom/browser/net/atom_url_request_job_factory.h"
#include "atom/browser/net/cookie_details.h"
#include "atom/browser/net/http_protocol_handler.h"
#include "atom/common/options_switches.h"
#include "base/strings/string_number_conversions.h"
#include "base/task_scheduler/post_task.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/common/url_constants.h"
#include "net/ftp/ftp_network_layer.h"
#include "net/url_request/data_protocol_handler.h"
#include "net/url_request/ftp_protocol_handler.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_intercepting_job_factory.h"
#include "url/url_constants.h"
using content::BrowserThread;
namespace atom {
namespace {
class NoCacheBackend : public net::HttpCache::BackendFactory {
int CreateBackend(net::NetLog* net_log,
std::unique_ptr<disk_cache::Backend>* backend,
const net::CompletionCallback& callback) override {
return net::ERR_FAILED;
}
};
} // namespace
RequestContextDelegate::RequestContextDelegate(bool use_cache)
: use_cache_(use_cache), weak_factory_(this) {}
RequestContextDelegate::~RequestContextDelegate() {}
std::unique_ptr<base::CallbackList<void(const CookieDetails*)>::Subscription>
RequestContextDelegate::RegisterCookieChangeCallback(
const base::Callback<void(const CookieDetails*)>& cb) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
return cookie_change_sub_list_.Add(cb);
}
void RequestContextDelegate::NotifyCookieChange(
const net::CanonicalCookie& cookie,
net::CookieChangeCause cause) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
CookieDetails cookie_details(
&cookie, !(cause == net::CookieChangeCause::INSERTED), cause);
cookie_change_sub_list_.Notify(&cookie_details);
}
std::unique_ptr<net::NetworkDelegate>
RequestContextDelegate::CreateNetworkDelegate() {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
return std::make_unique<AtomNetworkDelegate>();
}
std::unique_ptr<net::URLRequestJobFactory>
RequestContextDelegate::CreateURLRequestJobFactory(
net::URLRequestContext* url_request_context,
content::ProtocolHandlerMap* protocol_handlers) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
std::unique_ptr<AtomURLRequestJobFactory> job_factory(
new AtomURLRequestJobFactory);
for (auto& it : *protocol_handlers) {
job_factory->SetProtocolHandler(it.first,
base::WrapUnique(it.second.release()));
}
protocol_handlers->clear();
job_factory->SetProtocolHandler(url::kAboutScheme,
base::WrapUnique(new AboutProtocolHandler));
job_factory->SetProtocolHandler(
url::kDataScheme, base::WrapUnique(new net::DataProtocolHandler));
job_factory->SetProtocolHandler(
url::kFileScheme,
base::WrapUnique(
new asar::AsarProtocolHandler(base::CreateTaskRunnerWithTraits(
{base::MayBlock(), base::TaskPriority::USER_VISIBLE,
base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN}))));
job_factory->SetProtocolHandler(
url::kHttpScheme,
base::WrapUnique(new HttpProtocolHandler(url::kHttpScheme)));
job_factory->SetProtocolHandler(
url::kHttpsScheme,
base::WrapUnique(new HttpProtocolHandler(url::kHttpsScheme)));
job_factory->SetProtocolHandler(
url::kWsScheme,
base::WrapUnique(new HttpProtocolHandler(url::kWsScheme)));
job_factory->SetProtocolHandler(
url::kWssScheme,
base::WrapUnique(new HttpProtocolHandler(url::kWssScheme)));
auto* host_resolver = url_request_context->host_resolver();
job_factory->SetProtocolHandler(
url::kFtpScheme, net::FtpProtocolHandler::Create(host_resolver));
return std::move(job_factory);
}
net::HttpCache::BackendFactory*
RequestContextDelegate::CreateHttpCacheBackendFactory(
const base::FilePath& base_path) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
if (!use_cache_) {
return new NoCacheBackend;
} else {
int max_size = 0;
base::StringToInt(
command_line->GetSwitchValueASCII(switches::kDiskCacheSize), &max_size);
base::FilePath cache_path = base_path.Append(FILE_PATH_LITERAL("Cache"));
return new net::HttpCache::DefaultBackend(
net::DISK_CACHE, net::CACHE_BACKEND_DEFAULT, cache_path, max_size);
}
}
std::unique_ptr<net::CertVerifier> RequestContextDelegate::CreateCertVerifier(
brightray::RequireCTDelegate* ct_delegate) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
return std::make_unique<AtomCertVerifier>(ct_delegate);
}
void RequestContextDelegate::GetCookieableSchemes(
std::vector<std::string>* cookie_schemes) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
const auto& standard_schemes = atom::api::GetStandardSchemes();
cookie_schemes->insert(cookie_schemes->end(), standard_schemes.begin(),
standard_schemes.end());
}
void RequestContextDelegate::OnCookieChanged(const net::CanonicalCookie& cookie,
net::CookieChangeCause cause) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
base::BindRepeating(&RequestContextDelegate::NotifyCookieChange,
weak_factory_.GetWeakPtr(), cookie, cause));
}
} // namespace atom

View File

@@ -1,58 +0,0 @@
// Copyright (c) 2018 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef ATOM_BROWSER_REQUEST_CONTEXT_DELEGATE_H_
#define ATOM_BROWSER_REQUEST_CONTEXT_DELEGATE_H_
#include <string>
#include <vector>
#include "base/callback_list.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "brightray/browser/url_request_context_getter.h"
namespace atom {
struct CookieDetails;
class RequestContextDelegate
: public brightray::URLRequestContextGetter::Delegate {
public:
explicit RequestContextDelegate(bool use_cache);
~RequestContextDelegate() override;
// Register callbacks that needs to notified on any cookie store changes.
std::unique_ptr<base::CallbackList<void(const CookieDetails*)>::Subscription>
RegisterCookieChangeCallback(
const base::Callback<void(const CookieDetails*)>& cb);
protected:
std::unique_ptr<net::NetworkDelegate> CreateNetworkDelegate() override;
std::unique_ptr<net::URLRequestJobFactory> CreateURLRequestJobFactory(
net::URLRequestContext* url_request_context,
content::ProtocolHandlerMap* protocol_handlers) override;
net::HttpCache::BackendFactory* CreateHttpCacheBackendFactory(
const base::FilePath& base_path) override;
std::unique_ptr<net::CertVerifier> CreateCertVerifier(
brightray::RequireCTDelegate* ct_delegate) override;
void GetCookieableSchemes(std::vector<std::string>* cookie_schemes) override;
void OnCookieChanged(const net::CanonicalCookie& cookie,
net::CookieChangeCause cause) override;
private:
void NotifyCookieChange(const net::CanonicalCookie& cookie,
net::CookieChangeCause cause);
base::CallbackList<void(const CookieDetails*)> cookie_change_sub_list_;
bool use_cache_ = true;
base::WeakPtrFactory<RequestContextDelegate> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(RequestContextDelegate);
};
} // namespace atom
#endif // ATOM_BROWSER_REQUEST_CONTEXT_DELEGATE_H_

View File

@@ -17,9 +17,9 @@
<key>CFBundleIconFile</key>
<string>electron.icns</string>
<key>CFBundleVersion</key>
<string>3.0.2</string>
<string>3.1.11</string>
<key>CFBundleShortVersionString</key>
<string>3.0.2</string>
<string>3.1.11</string>
<key>LSApplicationCategoryType</key>
<string>public.app-category.developer-tools</string>
<key>LSMinimumSystemVersion</key>

View File

@@ -56,8 +56,8 @@ END
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 3,0,2,0
PRODUCTVERSION 3,0,2,0
FILEVERSION 3,1,11,0
PRODUCTVERSION 3,1,11,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@@ -74,12 +74,12 @@ BEGIN
BEGIN
VALUE "CompanyName", "GitHub, Inc."
VALUE "FileDescription", "Electron"
VALUE "FileVersion", "3.0.2"
VALUE "FileVersion", "3.1.11"
VALUE "InternalName", "electron.exe"
VALUE "LegalCopyright", "Copyright (C) 2015 GitHub, Inc. All rights reserved."
VALUE "OriginalFilename", "electron.exe"
VALUE "ProductName", "Electron"
VALUE "ProductVersion", "3.0.2"
VALUE "ProductVersion", "3.1.11"
VALUE "SquirrelAwareVersion", "1"
END
END

View File

@@ -78,9 +78,11 @@ void GenerateAcceleratorTable(AcceleratorTable* table,
GenerateAcceleratorTable(table, submodel);
} else {
ui::Accelerator accelerator;
if (model->GetAcceleratorAtWithParams(i, true, &accelerator)) {
MenuItem item = {i, model};
(*table)[accelerator] = item;
if (model->ShouldRegisterAcceleratorAt(i)) {
if (model->GetAcceleratorAtWithParams(i, true, &accelerator)) {
MenuItem item = {i, model};
(*table)[accelerator] = item;
}
}
}
}
@@ -91,7 +93,9 @@ bool TriggerAcceleratorTableCommand(AcceleratorTable* table,
if (base::ContainsKey(*table, accelerator)) {
const accelerator_util::MenuItem& item = (*table)[accelerator];
if (item.model->IsEnabledAt(item.position)) {
item.model->ActivatedAt(item.position);
const auto event_flags =
accelerator.MaskOutKeyEventFlags(accelerator.modifiers());
item.model->ActivatedAt(item.position, event_flags);
return true;
}
}

View File

@@ -43,6 +43,14 @@ bool AtomMenuModel::GetAcceleratorAtWithParams(
return false;
}
bool AtomMenuModel::ShouldRegisterAcceleratorAt(int index) const {
if (delegate_) {
return delegate_->ShouldRegisterAcceleratorForCommandId(
GetCommandIdAt(index));
}
return true;
}
void AtomMenuModel::MenuWillClose() {
ui::SimpleMenuModel::MenuWillClose();
for (Observer& observer : observers_) {

View File

@@ -23,6 +23,9 @@ class AtomMenuModel : public ui::SimpleMenuModel {
bool use_default_accelerator,
ui::Accelerator* accelerator) const = 0;
virtual bool ShouldRegisterAcceleratorForCommandId(
int command_id) const = 0;
private:
// ui::SimpleMenuModel::Delegate:
bool GetAcceleratorForCommandId(
@@ -52,6 +55,7 @@ class AtomMenuModel : public ui::SimpleMenuModel {
bool GetAcceleratorAtWithParams(int index,
bool use_default_accelerator,
ui::Accelerator* accelerator) const;
bool ShouldRegisterAcceleratorAt(int index) const;
// ui::SimpleMenuModel:
void MenuWillClose() override;

View File

@@ -208,7 +208,15 @@ static base::scoped_nsobject<NSMenu> recentDocumentsMenuSwap_;
base::string16 role = model->GetRoleAt(index);
atom::AtomMenuModel::ItemType type = model->GetTypeAt(index);
if (type == atom::AtomMenuModel::TYPE_SUBMENU) {
if (role == base::ASCIIToUTF16("services")) {
base::string16 title = base::ASCIIToUTF16("Services");
NSString* label = l10n_util::FixUpWindowsStyleLabel(title);
[item setTarget:nil];
[item setAction:nil];
NSMenu* submenu = [[NSMenu alloc] initWithTitle:label];
[item setSubmenu:submenu];
[NSApp setServicesMenu:submenu];
} else if (type == atom::AtomMenuModel::TYPE_SUBMENU) {
// Recursively build a submenu from the sub-model at this index.
[item setTarget:nil];
[item setAction:nil];
@@ -223,8 +231,6 @@ static base::scoped_nsobject<NSMenu> recentDocumentsMenuSwap_;
[NSApp setWindowsMenu:submenu];
else if (role == base::ASCIIToUTF16("help"))
[NSApp setHelpMenu:submenu];
else if (role == base::ASCIIToUTF16("services"))
[NSApp setServicesMenu:submenu];
else if (role == base::ASCIIToUTF16("recentdocuments"))
[self replaceSubmenuShowingRecentDocuments:item];
} else {

View File

@@ -9,6 +9,7 @@
#include "atom/browser/ui/cocoa/atom_preview_item.h"
#include "atom/browser/ui/cocoa/atom_touch_bar.h"
#include "base/mac/mac_util.h"
#include "ui/views/cocoa/bridged_native_widget.h"
#include "ui/views/widget/native_widget_mac.h"
@implementation AtomNSWindowDelegate
@@ -238,7 +239,10 @@
// Clears the delegate when window is going to be closed, since EL Capitan it
// is possible that the methods of delegate would get called after the window
// has been closed.
[shell_->GetNativeWindow() setDelegate:nil];
views::BridgedNativeWidget* bridged_view =
views::NativeWidgetMac::GetBridgeForNativeWindow(
shell_->GetNativeWindow());
bridged_view->OnWindowWillClose();
}
- (BOOL)windowShouldClose:(id)window {

View File

@@ -623,9 +623,14 @@ static NSString* const ImageScrubberItemIdentifier = @"scrubber.image.item";
segments[i].Get("enabled", &enabled);
if (segments[i].Get("label", &label)) {
[control setLabel:base::SysUTF8ToNSString(label) forSegment:i];
} else if (segments[i].Get("icon", &image)) {
} else {
[control setLabel:@"" forSegment:i];
}
if (segments[i].Get("icon", &image)) {
[control setImage:image.AsNSImage() forSegment:i];
[control setImageScaling:NSImageScaleProportionallyUpOrDown forSegment:i];
} else {
[control setImage:nil forSegment:i];
}
[control setEnabled:enabled forSegment:i];
}

View File

@@ -40,7 +40,8 @@ class GtkMessageBox : public NativeWindowObserver {
const std::string& message,
const std::string& detail,
const std::string& checkbox_label,
bool checkbox_checked)
bool checkbox_checked,
const gfx::ImageSkia& icon)
: cancel_id_(cancel_id),
parent_(static_cast<NativeWindow*>(parent_window)) {
// Create dialog.
@@ -56,6 +57,21 @@ class GtkMessageBox : public NativeWindowObserver {
if (!title.empty())
gtk_window_set_title(GTK_WINDOW(dialog_), title.c_str());
if (!icon.isNull()) {
// No easy way to obtain this programmatically, but GTK+'s docs
// define GTK_ICON_SIZE_DIALOG to be 48 pixels
static constexpr int pixel_width = 48;
static constexpr int pixel_height = 48;
GdkPixbuf* pixbuf = libgtkui::GdkPixbufFromSkBitmap(*icon.bitmap());
GdkPixbuf* scaled_pixbuf = gdk_pixbuf_scale_simple(
pixbuf, pixel_width, pixel_height, GDK_INTERP_BILINEAR);
GtkWidget* w = gtk_image_new_from_pixbuf(scaled_pixbuf);
gtk_message_dialog_set_image(GTK_MESSAGE_DIALOG(dialog_), w);
gtk_widget_show(w);
g_clear_pointer(&scaled_pixbuf, gdk_pixbuf_unref);
g_clear_pointer(&pixbuf, gdk_pixbuf_unref);
}
if (!checkbox_label.empty()) {
GtkWidget* message_area =
gtk_message_dialog_get_message_area(GTK_MESSAGE_DIALOG(dialog_));
@@ -66,15 +82,15 @@ class GtkMessageBox : public NativeWindowObserver {
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_button),
checkbox_checked);
gtk_container_add(GTK_CONTAINER(message_area), check_button);
gtk_widget_show(check_button);
}
// Add buttons.
GtkDialog* dialog = GTK_DIALOG(dialog_);
for (size_t i = 0; i < buttons.size(); ++i) {
GtkWidget* button = gtk_dialog_add_button(
GTK_DIALOG(dialog_), TranslateToStock(i, buttons[i]), i);
if (static_cast<int>(i) == default_id)
gtk_widget_grab_focus(button);
gtk_dialog_add_button(dialog, TranslateToStock(i, buttons[i]), i);
}
gtk_dialog_set_default_response(dialog, default_id);
// Parent window.
if (parent_) {
@@ -122,7 +138,7 @@ class GtkMessageBox : public NativeWindowObserver {
}
void Show() {
gtk_widget_show_all(dialog_);
gtk_widget_show(dialog_);
// We need to call gtk_window_present after making the widgets visible to
// make sure window gets correctly raised and gets focus.
int time = ui::X11EventSource::GetInstance()->GetTimestamp();
@@ -195,9 +211,9 @@ int ShowMessageBox(NativeWindow* parent,
const std::string& title,
const std::string& message,
const std::string& detail,
const gfx::ImageSkia& /*icon*/) {
const gfx::ImageSkia& icon) {
return GtkMessageBox(parent, type, buttons, default_id, cancel_id, title,
message, detail, "", false)
message, detail, "", false, icon)
.RunSynchronous();
}
@@ -212,10 +228,10 @@ void ShowMessageBox(NativeWindow* parent,
const std::string& detail,
const std::string& checkbox_label,
bool checkbox_checked,
const gfx::ImageSkia& /*icon*/,
const gfx::ImageSkia& icon,
const MessageBoxCallback& callback) {
(new GtkMessageBox(parent, type, buttons, default_id, cancel_id, title,
message, detail, checkbox_label, checkbox_checked))
message, detail, checkbox_label, checkbox_checked, icon))
->RunAsynchronous(callback);
}
@@ -223,7 +239,8 @@ void ShowErrorBox(const base::string16& title, const base::string16& content) {
if (Browser::Get()->is_ready()) {
GtkMessageBox(nullptr, MESSAGE_BOX_TYPE_ERROR, {"OK"}, -1, 0, "Error",
base::UTF16ToUTF8(title).c_str(),
base::UTF16ToUTF8(content).c_str(), "", false)
base::UTF16ToUTF8(content).c_str(), "", false,
gfx::ImageSkia())
.RunSynchronous();
} else {
fprintf(stderr,

View File

@@ -5,7 +5,6 @@
#include "atom/browser/ui/views/menu_bar.h"
#include <memory>
#include <string>
#include "atom/browser/ui/views/menu_delegate.h"
#include "atom/browser/ui/views/submenu_button.h"
@@ -129,13 +128,11 @@ void MenuBar::RefreshColorCache(const ui::NativeTheme* theme) {
theme = ui::NativeTheme::GetInstanceForNativeUi();
if (theme) {
#if defined(USE_X11)
const std::string menubar_selector = "GtkMenuBar#menubar";
background_color_ = libgtkui::GetBgColor(menubar_selector);
enabled_color_ = theme->GetSystemColor(
ui::NativeTheme::kColorId_EnabledMenuItemForegroundColor);
disabled_color_ = theme->GetSystemColor(
ui::NativeTheme::kColorId_DisabledMenuItemForegroundColor);
background_color_ = libgtkui::GetBgColor("GtkMenuBar#menubar");
enabled_color_ = libgtkui::GetFgColor(
"GtkMenuBar#menubar GtkMenuItem#menuitem GtkLabel");
disabled_color_ = libgtkui::GetFgColor(
"GtkMenuBar#menubar GtkMenuItem#menuitem:disabled GtkLabel");
#else
background_color_ =
theme->GetSystemColor(ui::NativeTheme::kColorId_MenuBackgroundColor);

View File

@@ -44,15 +44,14 @@ RootView::~RootView() {}
void RootView::SetMenu(AtomMenuModel* menu_model) {
if (menu_model == nullptr) {
// Remove accelerators
accelerator_table_.clear();
GetFocusManager()->UnregisterAccelerators(this);
UnregisterAcceleratorsWithFocusManager();
// and menu bar.
SetMenuBarVisibility(false);
menu_bar_.reset();
return;
}
RegisterAccelerators(menu_model);
RegisterAcceleratorsWithFocusManager(menu_model);
// Do not show menu bar in frameless window.
if (!window_->has_frame())
@@ -178,12 +177,12 @@ bool RootView::AcceleratorPressed(const ui::Accelerator& accelerator) {
accelerator);
}
void RootView::RegisterAccelerators(AtomMenuModel* menu_model) {
void RootView::RegisterAcceleratorsWithFocusManager(AtomMenuModel* menu_model) {
if (!menu_model)
return;
// Clear previous accelerators.
UnregisterAcceleratorsWithFocusManager();
views::FocusManager* focus_manager = GetFocusManager();
accelerator_table_.clear();
focus_manager->UnregisterAccelerators(this);
// Register accelerators with focus manager.
accelerator_util::GenerateAcceleratorTable(&accelerator_table_, menu_model);
for (const auto& iter : accelerator_table_) {
@@ -192,4 +191,10 @@ void RootView::RegisterAccelerators(AtomMenuModel* menu_model) {
}
}
void RootView::UnregisterAcceleratorsWithFocusManager() {
views::FocusManager* focus_manager = GetFocusManager();
accelerator_table_.clear();
focus_manager->UnregisterAccelerators(this);
}
} // namespace atom

View File

@@ -34,6 +34,9 @@ class RootView : public views::View {
bool IsMenuBarVisible() const;
void HandleKeyEvent(const content::NativeWebKeyboardEvent& event);
void ResetAltState();
// Register/Unregister accelerators supported by the menu model.
void RegisterAcceleratorsWithFocusManager(AtomMenuModel* menu_model);
void UnregisterAcceleratorsWithFocusManager();
// views::View:
void Layout() override;
@@ -42,9 +45,6 @@ class RootView : public views::View {
bool AcceleratorPressed(const ui::Accelerator& accelerator) override;
private:
// Register accelerators supported by the menu model.
void RegisterAccelerators(AtomMenuModel* menu_model);
// Parent window, weak ref.
NativeWindow* window_;

View File

@@ -213,8 +213,13 @@ void WebContentsPreferences::AppendCommandLineSwitches(
// --background-color.
std::string s;
if (dict_.GetString(options::kBackgroundColor, &s))
if (dict_.GetString(options::kBackgroundColor, &s)) {
command_line->AppendSwitchASCII(switches::kBackgroundColor, s);
} else if (!(dict_.GetBoolean(options::kOffscreen, &b) && b)) {
// For non-OSR WebContents, we expect to have white background, see
// https://github.com/electron/electron/issues/13764 for more.
command_line->AppendSwitchASCII(switches::kBackgroundColor, "#fff");
}
// --guest-instance-id, which is used to identify guest WebContents.
int guest_instance_id = 0;
@@ -326,6 +331,10 @@ void WebContentsPreferences::OverrideWebkitPrefs(
std::string encoding;
if (dict_.GetString("defaultEncoding", &encoding))
prefs->default_encoding = encoding;
bool node_integration = false;
dict_.GetBoolean(options::kNodeIntegration, &node_integration);
prefs->node_integration = node_integration;
}
bool WebContentsPreferences::GetInteger(const base::StringPiece& attribute_name,

View File

@@ -79,49 +79,71 @@ float GetScaleFactorFromOptions(mate::Arguments* args) {
return scale_factor;
}
bool AddImageSkiaRep(gfx::ImageSkia* image,
const unsigned char* data,
size_t size,
int width,
int height,
double scale_factor) {
auto decoded = std::make_unique<SkBitmap>();
bool AddImageSkiaRepFromPNG(gfx::ImageSkia* image,
const unsigned char* data,
size_t size,
double scale_factor) {
SkBitmap bitmap;
if (!gfx::PNGCodec::Decode(data, size, &bitmap))
return false;
// Try PNG first.
if (!gfx::PNGCodec::Decode(data, size, decoded.get())) {
// Try JPEG.
decoded = gfx::JPEGCodec::Decode(data, size);
if (decoded) {
// `JPEGCodec::Decode()` doesn't tell `SkBitmap` instance it creates
// that all of its pixels are opaque, that's why the bitmap gets
// an alpha type `kPremul_SkAlphaType` instead of `kOpaque_SkAlphaType`.
// Let's fix it here.
// TODO(alexeykuzmin): This workaround should be removed
// when the `JPEGCodec::Decode()` code is fixed.
// See https://github.com/electron/electron/issues/11294.
decoded->setAlphaType(SkAlphaType::kOpaque_SkAlphaType);
}
}
if (!decoded) {
// Try Bitmap
if (width > 0 && height > 0) {
decoded.reset(new SkBitmap);
decoded->allocN32Pixels(width, height, false);
decoded->setPixels(
const_cast<void*>(reinterpret_cast<const void*>(data)));
} else {
return false;
}
}
image->AddRepresentation(gfx::ImageSkiaRep(*decoded, scale_factor));
image->AddRepresentation(gfx::ImageSkiaRep(bitmap, scale_factor));
return true;
}
bool AddImageSkiaRep(gfx::ImageSkia* image,
const base::FilePath& path,
double scale_factor) {
bool AddImageSkiaRepFromJPEG(gfx::ImageSkia* image,
const unsigned char* data,
size_t size,
double scale_factor) {
auto bitmap = gfx::JPEGCodec::Decode(data, size);
if (!bitmap)
return false;
// `JPEGCodec::Decode()` doesn't tell `SkBitmap` instance it creates
// that all of its pixels are opaque, that's why the bitmap gets
// an alpha type `kPremul_SkAlphaType` instead of `kOpaque_SkAlphaType`.
// Let's fix it here.
// TODO(alexeykuzmin): This workaround should be removed
// when the `JPEGCodec::Decode()` code is fixed.
// See https://github.com/electron/electron/issues/11294.
bitmap->setAlphaType(SkAlphaType::kOpaque_SkAlphaType);
image->AddRepresentation(gfx::ImageSkiaRep(*bitmap, scale_factor));
return true;
}
bool AddImageSkiaRepFromBuffer(gfx::ImageSkia* image,
const unsigned char* data,
size_t size,
int width,
int height,
double scale_factor) {
// Try PNG first.
if (AddImageSkiaRepFromPNG(image, data, size, scale_factor))
return true;
// Try JPEG second.
if (AddImageSkiaRepFromJPEG(image, data, size, scale_factor))
return true;
if (width == 0 || height == 0)
return false;
auto info = SkImageInfo::MakeN32(width, height, kPremul_SkAlphaType);
if (size < info.computeMinByteSize())
return false;
SkBitmap bitmap;
bitmap.allocN32Pixels(width, height, false);
bitmap.writePixels({info, data, bitmap.rowBytes()});
image->AddRepresentation(gfx::ImageSkiaRep(bitmap, scale_factor));
return true;
}
bool AddImageSkiaRepFromPath(gfx::ImageSkia* image,
const base::FilePath& path,
double scale_factor) {
std::string file_contents;
{
base::ThreadRestrictions::ScopedAllowIO allow_io;
@@ -132,7 +154,8 @@ bool AddImageSkiaRep(gfx::ImageSkia* image,
const unsigned char* data =
reinterpret_cast<const unsigned char*>(file_contents.data());
size_t size = file_contents.size();
return AddImageSkiaRep(image, data, size, 0, 0, scale_factor);
return AddImageSkiaRepFromBuffer(image, data, size, 0, 0, scale_factor);
}
bool PopulateImageSkiaRepsFromPath(gfx::ImageSkia* image,
@@ -141,12 +164,12 @@ bool PopulateImageSkiaRepsFromPath(gfx::ImageSkia* image,
std::string filename(path.BaseName().RemoveExtension().AsUTF8Unsafe());
if (base::MatchPattern(filename, "*@*x"))
// Don't search for other representations if the DPI has been specified.
return AddImageSkiaRep(image, path, GetScaleFactorFromPath(path));
return AddImageSkiaRepFromPath(image, path, GetScaleFactorFromPath(path));
else
succeed |= AddImageSkiaRep(image, path, 1.0f);
succeed |= AddImageSkiaRepFromPath(image, path, 1.0f);
for (const ScaleFactorPair& pair : kScaleFactorPairs)
succeed |= AddImageSkiaRep(
succeed |= AddImageSkiaRepFromPath(
image, path.InsertBeforeExtensionASCII(pair.name), pair.scale);
return succeed;
}
@@ -422,19 +445,20 @@ void NativeImage::AddRepresentation(const mate::Dictionary& options) {
v8::Local<v8::Value> buffer;
GURL url;
if (options.Get("buffer", &buffer) && node::Buffer::HasInstance(buffer)) {
AddImageSkiaRep(
&image_skia,
reinterpret_cast<unsigned char*>(node::Buffer::Data(buffer)),
node::Buffer::Length(buffer), width, height, scale_factor);
skia_rep_added = true;
auto* data = reinterpret_cast<unsigned char*>(node::Buffer::Data(buffer));
auto size = node::Buffer::Length(buffer);
skia_rep_added = AddImageSkiaRepFromBuffer(&image_skia, data, size, width,
height, scale_factor);
} else if (options.Get("dataURL", &url)) {
std::string mime_type, charset, data;
if (net::DataURL::Parse(url, &mime_type, &charset, &data)) {
if (mime_type == "image/png" || mime_type == "image/jpeg") {
AddImageSkiaRep(&image_skia,
reinterpret_cast<const unsigned char*>(data.c_str()),
data.size(), width, height, scale_factor);
skia_rep_added = true;
auto* data_ptr = reinterpret_cast<const unsigned char*>(data.c_str());
if (mime_type == "image/png") {
skia_rep_added = AddImageSkiaRepFromPNG(&image_skia, data_ptr,
data.size(), scale_factor);
} else if (mime_type == "image/jpeg") {
skia_rep_added = AddImageSkiaRepFromJPEG(&image_skia, data_ptr,
data.size(), scale_factor);
}
}
}
@@ -508,6 +532,11 @@ mate::Handle<NativeImage> NativeImage::CreateFromPath(
mate::Handle<NativeImage> NativeImage::CreateFromBuffer(
mate::Arguments* args,
v8::Local<v8::Value> buffer) {
if (!node::Buffer::HasInstance(buffer)) {
args->ThrowError("buffer must be a node Buffer");
return mate::Handle<NativeImage>();
}
int width = 0;
int height = 0;
double scale_factor = 1.;
@@ -520,9 +549,9 @@ mate::Handle<NativeImage> NativeImage::CreateFromBuffer(
}
gfx::ImageSkia image_skia;
AddImageSkiaRep(&image_skia,
reinterpret_cast<unsigned char*>(node::Buffer::Data(buffer)),
node::Buffer::Length(buffer), width, height, scale_factor);
AddImageSkiaRepFromBuffer(
&image_skia, reinterpret_cast<unsigned char*>(node::Buffer::Data(buffer)),
node::Buffer::Length(buffer), width, height, scale_factor);
return Create(args->isolate(), gfx::Image(image_skia));
}

View File

@@ -6,8 +6,8 @@
#define ATOM_COMMON_ATOM_VERSION_H_
#define ATOM_MAJOR_VERSION 3
#define ATOM_MINOR_VERSION 0
#define ATOM_PATCH_VERSION 2
#define ATOM_MINOR_VERSION 1
#define ATOM_PATCH_VERSION 11
// #define ATOM_PRE_RELEASE_VERSION
#ifndef ATOM_STRINGIFY

View File

@@ -39,7 +39,6 @@
V(atom_browser_in_app_purchase) \
V(atom_browser_menu) \
V(atom_browser_net) \
V(atom_browser_net_log) \
V(atom_browser_power_monitor) \
V(atom_browser_power_save_blocker) \
V(atom_browser_protocol) \

View File

@@ -7,6 +7,7 @@
#include <windows.h>
#include "base/logging.h"
#include "base/sys_info.h"
extern "C" {
#include "vendor/node/deps/uv/src/win/internal.h"
@@ -15,7 +16,20 @@ extern "C" {
namespace atom {
NodeBindingsWin::NodeBindingsWin(BrowserEnvironment browser_env)
: NodeBindings(browser_env) {}
: NodeBindings(browser_env) {
// on single-core the io comp port NumberOfConcurrentThreads needs to be 2
// to avoid cpu pegging likely caused by a busy loop in PollEvents
if (base::SysInfo::NumberOfProcessors() == 1) {
// the expectation is the uv_loop_ has just been initialized
// which makes iocp replacement safe
CHECK_EQ(0u, uv_loop_->active_handles);
CHECK_EQ(0u, uv_loop_->active_reqs.count);
if (uv_loop_->iocp && uv_loop_->iocp != INVALID_HANDLE_VALUE)
CloseHandle(uv_loop_->iocp);
uv_loop_->iocp = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 2);
}
}
NodeBindingsWin::~NodeBindingsWin() {}

View File

@@ -218,6 +218,13 @@ const char kDiskCacheSize[] = "disk-cache-size";
// Ignore the limit of 6 connections per host.
const char kIgnoreConnectionsLimit[] = "ignore-connections-limit";
// Whitelist containing servers for which Integrated Authentication is enabled.
const char kAuthServerWhitelist[] = "auth-server-whitelist";
// Whitelist containing servers for which Kerberos delegation is allowed.
const char kAuthNegotiateDelegateWhitelist[] =
"auth-negotiate-delegate-whitelist";
} // namespace switches
} // namespace atom

View File

@@ -113,6 +113,8 @@ extern const char kWidevineCdmVersion[];
extern const char kDiskCacheSize[];
extern const char kIgnoreConnectionsLimit[];
extern const char kAuthServerWhitelist[];
extern const char kAuthNegotiateDelegateWhitelist[];
} // namespace switches

View File

@@ -60,6 +60,7 @@ void Beep();
#if defined(OS_MACOSX)
bool GetLoginItemEnabled();
void SetLoginItemEnabled(bool enabled);
bool IsAtLeastOS10_14();
#endif
} // namespace platform_util

View File

@@ -15,7 +15,7 @@
#include "url/gurl.h"
#define ELECTRON_TRASH "ELECTRON_TRASH"
#define ELECTRON_DEFAULT_TRASH "gvfs-trash"
#define ELECTRON_DEFAULT_TRASH "gio"
namespace {
@@ -126,12 +126,13 @@ bool MoveItemToTrash(const base::FilePath& full_path) {
} else if (trash.compare("trash-cli") == 0) {
argv.push_back("trash-put");
argv.push_back(full_path.value());
} else if (trash.compare("gio") == 0) {
argv.push_back("gio");
argv.push_back("trash");
} else if (trash.compare("gvfs-trash") == 0) {
// retain support for deprecated gvfs-trash
argv.push_back("gvfs-trash");
argv.push_back(full_path.value());
} else {
argv.push_back(ELECTRON_DEFAULT_TRASH);
argv.push_back("trash");
argv.push_back(full_path.value());
}
return XDGUtilV(argv, true);

View File

@@ -8,6 +8,8 @@
#import <Cocoa/Cocoa.h>
#import <ServiceManagement/ServiceManagement.h>
#include "atom/common/platform_util.h"
#include "base/callback.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
@@ -18,6 +20,7 @@
#include "base/strings/stringprintf.h"
#include "base/strings/sys_string_conversions.h"
#include "net/base/mac/url_conversions.h"
#include "third_party/WebKit/Source/platform/mac/VersionUtilMac.h"
#include "url/gurl.h"
namespace {
@@ -166,6 +169,10 @@ void OpenExternal(const GURL& url,
});
}
bool IsAtLeastOS10_14() {
return blink::internal::MacOSXMinorVersion() >= 14;
}
bool MoveItemToTrash(const base::FilePath& full_path) {
NSString* path_string = base::SysUTF8ToNSString(full_path.value());
BOOL status = [[NSFileManager defaultManager]

View File

@@ -2,7 +2,10 @@
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/renderer/api/atom_api_web_frame.h"
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include "atom/common/api/api_messages.h"
#include "atom/common/api/event_emitter_caller.h"
@@ -109,15 +112,15 @@ class ScriptExecutionCallback : public blink::WebScriptExecutionCallback {
DISALLOW_COPY_AND_ASSIGN(ScriptExecutionCallback);
};
class FrameSpellChecker : public content::RenderFrameVisitor {
class FrameSetSpellChecker : public content::RenderFrameVisitor {
public:
explicit FrameSpellChecker(SpellCheckClient* spell_check_client,
content::RenderFrame* main_frame)
: spell_check_client_(spell_check_client), main_frame_(main_frame) {}
~FrameSpellChecker() override {
spell_check_client_ = nullptr;
main_frame_ = nullptr;
FrameSetSpellChecker(SpellCheckClient* spell_check_client,
content::RenderFrame* main_frame)
: spell_check_client_(spell_check_client), main_frame_(main_frame) {
content::RenderFrame::ForEach(this);
main_frame->GetWebFrame()->SetSpellCheckPanelHostClient(spell_check_client);
}
bool Visit(content::RenderFrame* render_frame) override {
auto* view = render_frame->GetRenderView();
if (view->GetMainRenderFrame() == main_frame_ ||
@@ -130,71 +133,128 @@ class FrameSpellChecker : public content::RenderFrameVisitor {
private:
SpellCheckClient* spell_check_client_;
content::RenderFrame* main_frame_;
DISALLOW_COPY_AND_ASSIGN(FrameSpellChecker);
DISALLOW_COPY_AND_ASSIGN(FrameSetSpellChecker);
};
class SpellCheckerHolder : public content::RenderFrameObserver {
public:
// Find existing holder for the |render_frame|.
static SpellCheckerHolder* FromRenderFrame(
content::RenderFrame* render_frame) {
for (auto* holder : instances_) {
if (holder->render_frame() == render_frame)
return holder;
}
return nullptr;
}
SpellCheckerHolder(content::RenderFrame* render_frame,
std::unique_ptr<SpellCheckClient> spell_check_client)
: content::RenderFrameObserver(render_frame),
spell_check_client_(std::move(spell_check_client)) {
DCHECK(!FromRenderFrame(render_frame));
instances_.insert(this);
}
~SpellCheckerHolder() final { instances_.erase(this); }
void UnsetAndDestroy() {
FrameSetSpellChecker set_spell_checker(nullptr, render_frame());
delete this;
}
// RenderFrameObserver implementation.
void OnDestruct() final {
// Since we delete this in WillReleaseScriptContext, this method is unlikely
// to be called, but override anyway since I'm not sure if there are some
// corner cases.
//
// Note that while there are two "delete this", it is totally fine as the
// observer unsubscribes automatically in destructor and the other one won't
// be called.
//
// Also note that we should not call UnsetAndDestroy here, as the render
// frame is going to be destroyed.
delete this;
}
void WillReleaseScriptContext(v8::Local<v8::Context> context,
int world_id) final {
// Unset spell checker when the script context is going to be released, as
// the spell check implementation lives there.
UnsetAndDestroy();
}
private:
static std::set<SpellCheckerHolder*> instances_;
std::unique_ptr<SpellCheckClient> spell_check_client_;
};
} // namespace
WebFrame::WebFrame(v8::Isolate* isolate)
: web_frame_(blink::WebLocalFrame::FrameForCurrentContext()) {
Init(isolate);
// static
std::set<SpellCheckerHolder*> SpellCheckerHolder::instances_;
void SetName(v8::Local<v8::Value> window, const std::string& name) {
GetRenderFrame(window)->GetWebFrame()->SetName(
blink::WebString::FromUTF8(name));
}
WebFrame::WebFrame(v8::Isolate* isolate, blink::WebLocalFrame* blink_frame)
: web_frame_(blink_frame) {
Init(isolate);
}
WebFrame::~WebFrame() {}
void WebFrame::SetName(const std::string& name) {
web_frame_->SetName(blink::WebString::FromUTF8(name));
}
double WebFrame::SetZoomLevel(double level) {
double SetZoomLevel(v8::Local<v8::Value> window, double level) {
double result = 0.0;
content::RenderFrame* render_frame =
content::RenderFrame::FromWebFrame(web_frame_);
content::RenderFrame* render_frame = GetRenderFrame(window);
render_frame->Send(new AtomFrameHostMsg_SetTemporaryZoomLevel(
render_frame->GetRoutingID(), level, &result));
return result;
}
double WebFrame::GetZoomLevel() const {
double GetZoomLevel(v8::Local<v8::Value> window) {
double result = 0.0;
content::RenderFrame* render_frame =
content::RenderFrame::FromWebFrame(web_frame_);
content::RenderFrame* render_frame = GetRenderFrame(window);
render_frame->Send(
new AtomFrameHostMsg_GetZoomLevel(render_frame->GetRoutingID(), &result));
return result;
}
double WebFrame::SetZoomFactor(double factor) {
double SetZoomFactor(v8::Local<v8::Value> window, double factor) {
return blink::WebView::ZoomLevelToZoomFactor(
SetZoomLevel(blink::WebView::ZoomFactorToZoomLevel(factor)));
SetZoomLevel(window, blink::WebView::ZoomFactorToZoomLevel(factor)));
}
double WebFrame::GetZoomFactor() const {
return blink::WebView::ZoomLevelToZoomFactor(GetZoomLevel());
double GetZoomFactor(v8::Local<v8::Value> window) {
return blink::WebView::ZoomLevelToZoomFactor(GetZoomLevel(window));
}
void WebFrame::SetVisualZoomLevelLimits(double min_level, double max_level) {
web_frame_->View()->SetDefaultPageScaleLimits(min_level, max_level);
web_frame_->View()->SetIgnoreViewportTagScaleLimits(true);
void SetVisualZoomLevelLimits(v8::Local<v8::Value> window,
double min_level,
double max_level) {
blink::WebFrame* web_frame = GetRenderFrame(window)->GetWebFrame();
web_frame->View()->SetDefaultPageScaleLimits(min_level, max_level);
web_frame->View()->SetIgnoreViewportTagScaleLimits(true);
}
void WebFrame::SetLayoutZoomLevelLimits(double min_level, double max_level) {
web_frame_->View()->ZoomLimitsChanged(min_level, max_level);
void SetLayoutZoomLevelLimits(v8::Local<v8::Value> window,
double min_level,
double max_level) {
blink::WebFrame* web_frame = GetRenderFrame(window)->GetWebFrame();
web_frame->View()->ZoomLimitsChanged(min_level, max_level);
}
v8::Local<v8::Value> WebFrame::RegisterEmbedderCustomElement(
v8::Local<v8::Value> RegisterEmbedderCustomElement(
v8::Local<v8::Value> window,
const base::string16& name,
v8::Local<v8::Object> options) {
return web_frame_->GetDocument().RegisterEmbedderCustomElement(
blink::WebString::FromUTF16(name), options);
return GetRenderFrame(window)
->GetWebFrame()
->GetDocument()
.RegisterEmbedderCustomElement(blink::WebString::FromUTF16(name),
options);
}
int WebFrame::GetWebFrameId(v8::Local<v8::Value> content_window) {
int GetWebFrameId(v8::Local<v8::Value> window,
v8::Local<v8::Value> content_window) {
// Get the WebLocalFrame before (possibly) executing any user-space JS while
// getting the |params|. We track the status of the RenderFrame via an
// observer in case it is deleted during user code execution.
@@ -213,34 +273,42 @@ int WebFrame::GetWebFrameId(v8::Local<v8::Value> content_window) {
return render_frame->GetRoutingID();
}
void WebFrame::SetSpellCheckProvider(mate::Arguments* args,
const std::string& language,
bool auto_spell_correct_turned_on,
v8::Local<v8::Object> provider) {
void SetSpellCheckProvider(mate::Arguments* args,
v8::Local<v8::Value> window,
const std::string& language,
bool auto_spell_correct_turned_on,
v8::Local<v8::Object> provider) {
if (!provider->Has(mate::StringToV8(args->isolate(), "spellCheck"))) {
args->ThrowError("\"spellCheck\" has to be defined");
return;
}
auto client = std::make_unique<SpellCheckClient>(
language, auto_spell_correct_turned_on, args->isolate(), provider);
// Remove the old client.
content::RenderFrame* render_frame = GetRenderFrame(window);
auto* existing = SpellCheckerHolder::FromRenderFrame(render_frame);
if (existing)
existing->UnsetAndDestroy();
// Set spellchecker for all live frames in the same process or
// in the sandbox mode for all live sub frames to this WebFrame.
FrameSpellChecker spell_checker(
client.get(), content::RenderFrame::FromWebFrame(web_frame_));
content::RenderFrame::ForEach(&spell_checker);
spell_check_client_.swap(client);
web_frame_->SetSpellCheckPanelHostClient(spell_check_client_.get());
auto spell_check_client = std::make_unique<SpellCheckClient>(
language, auto_spell_correct_turned_on, args->isolate(), provider);
FrameSetSpellChecker spell_checker(spell_check_client.get(), render_frame);
// Attach the spell checker to RenderFrame.
new SpellCheckerHolder(render_frame, std::move(spell_check_client));
}
void WebFrame::RegisterURLSchemeAsBypassingCSP(const std::string& scheme) {
void RegisterURLSchemeAsBypassingCSP(v8::Local<v8::Value> window,
const std::string& scheme) {
// Register scheme to bypass pages's Content Security Policy.
blink::SchemeRegistry::RegisterURLSchemeAsBypassingContentSecurityPolicy(
WTF::String::FromUTF8(scheme.data(), scheme.length()));
}
void WebFrame::RegisterURLSchemeAsPrivileged(const std::string& scheme,
mate::Arguments* args) {
void RegisterURLSchemeAsPrivileged(v8::Local<v8::Value> window,
const std::string& scheme,
mate::Arguments* args) {
// TODO(deepak1556): blink::SchemeRegistry methods should be called
// before any renderer threads are created. Fixing this would break
// current api. Change it with 2.0.
@@ -251,7 +319,7 @@ void WebFrame::RegisterURLSchemeAsPrivileged(const std::string& scheme,
bool allowServiceWorkers = true;
bool supportFetchAPI = true;
bool corsEnabled = true;
if (args->Length() == 2) {
if (args->Length() == 3) {
mate::Dictionary options;
if (args->GetNext(&options)) {
options.Get("secure", &secure);
@@ -281,30 +349,42 @@ void WebFrame::RegisterURLSchemeAsPrivileged(const std::string& scheme,
}
}
void WebFrame::InsertText(const std::string& text) {
web_frame_->FrameWidget()->GetActiveWebInputMethodController()->CommitText(
blink::WebString::FromUTF8(text),
blink::WebVector<blink::WebImeTextSpan>(), blink::WebRange(), 0);
void InsertText(v8::Local<v8::Value> window, const std::string& text) {
blink::WebFrame* web_frame = GetRenderFrame(window)->GetWebFrame();
if (web_frame->IsWebLocalFrame()) {
web_frame->ToWebLocalFrame()
->FrameWidget()
->GetActiveWebInputMethodController()
->CommitText(blink::WebString::FromUTF8(text),
blink::WebVector<blink::WebImeTextSpan>(),
blink::WebRange(), 0);
}
}
void WebFrame::InsertCSS(const std::string& css) {
web_frame_->GetDocument().InsertStyleSheet(blink::WebString::FromUTF8(css));
void InsertCSS(v8::Local<v8::Value> window, const std::string& css) {
blink::WebFrame* web_frame = GetRenderFrame(window)->GetWebFrame();
if (web_frame->IsWebLocalFrame()) {
web_frame->ToWebLocalFrame()->GetDocument().InsertStyleSheet(
blink::WebString::FromUTF8(css));
}
}
void WebFrame::ExecuteJavaScript(const base::string16& code,
mate::Arguments* args) {
void ExecuteJavaScript(v8::Local<v8::Value> window,
const base::string16& code,
mate::Arguments* args) {
bool has_user_gesture = false;
args->GetNext(&has_user_gesture);
ScriptExecutionCallback::CompletionCallback completion_callback;
args->GetNext(&completion_callback);
std::unique_ptr<blink::WebScriptExecutionCallback> callback(
new ScriptExecutionCallback(completion_callback));
web_frame_->RequestExecuteScriptAndReturnValue(
GetRenderFrame(window)->GetWebFrame()->RequestExecuteScriptAndReturnValue(
blink::WebScriptSource(blink::WebString::FromUTF16(code)),
has_user_gesture, callback.release());
}
void WebFrame::ExecuteJavaScriptInIsolatedWorld(
void ExecuteJavaScriptInIsolatedWorld(
v8::Local<v8::Value> window,
int world_id,
const std::vector<mate::Dictionary>& scripts,
mate::Arguments* args) {
@@ -339,186 +419,131 @@ void WebFrame::ExecuteJavaScriptInIsolatedWorld(
std::unique_ptr<blink::WebScriptExecutionCallback> callback(
new ScriptExecutionCallback(completion_callback));
web_frame_->RequestExecuteScriptInIsolatedWorld(
GetRenderFrame(window)->GetWebFrame()->RequestExecuteScriptInIsolatedWorld(
world_id, &sources.front(), sources.size(), has_user_gesture,
scriptExecutionType, callback.release());
}
void WebFrame::SetIsolatedWorldSecurityOrigin(int world_id,
const std::string& origin_url) {
web_frame_->SetIsolatedWorldSecurityOrigin(
void SetIsolatedWorldSecurityOrigin(v8::Local<v8::Value> window,
int world_id,
const std::string& origin_url) {
GetRenderFrame(window)->GetWebFrame()->SetIsolatedWorldSecurityOrigin(
world_id, blink::WebSecurityOrigin::CreateFromString(
blink::WebString::FromUTF8(origin_url)));
}
void WebFrame::SetIsolatedWorldContentSecurityPolicy(
int world_id,
const std::string& security_policy) {
web_frame_->SetIsolatedWorldContentSecurityPolicy(
void SetIsolatedWorldContentSecurityPolicy(v8::Local<v8::Value> window,
int world_id,
const std::string& security_policy) {
GetRenderFrame(window)->GetWebFrame()->SetIsolatedWorldContentSecurityPolicy(
world_id, blink::WebString::FromUTF8(security_policy));
}
void WebFrame::SetIsolatedWorldHumanReadableName(int world_id,
const std::string& name) {
web_frame_->SetIsolatedWorldHumanReadableName(
void SetIsolatedWorldHumanReadableName(v8::Local<v8::Value> window,
int world_id,
const std::string& name) {
GetRenderFrame(window)->GetWebFrame()->SetIsolatedWorldHumanReadableName(
world_id, blink::WebString::FromUTF8(name));
}
// static
mate::Handle<WebFrame> WebFrame::Create(v8::Isolate* isolate) {
return mate::CreateHandle(isolate, new WebFrame(isolate));
}
blink::WebCache::ResourceTypeStats WebFrame::GetResourceUsage(
v8::Isolate* isolate) {
blink::WebCache::ResourceTypeStats GetResourceUsage(v8::Isolate* isolate) {
blink::WebCache::ResourceTypeStats stats;
blink::WebCache::GetResourceTypeStats(&stats);
return stats;
}
void WebFrame::ClearCache(v8::Isolate* isolate) {
void ClearCache(v8::Isolate* isolate) {
isolate->IdleNotificationDeadline(0.5);
blink::WebCache::Clear();
base::MemoryPressureListener::NotifyMemoryPressure(
base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
}
v8::Local<v8::Value> WebFrame::Opener() const {
blink::WebFrame* frame = web_frame_->Opener();
if (frame && frame->IsWebLocalFrame())
return mate::CreateHandle(isolate(),
new WebFrame(isolate(), frame->ToWebLocalFrame()))
.ToV8();
else
return v8::Null(isolate());
}
v8::Local<v8::Value> WebFrame::Parent() const {
blink::WebFrame* frame = web_frame_->Parent();
if (frame && frame->IsWebLocalFrame())
return mate::CreateHandle(isolate(),
new WebFrame(isolate(), frame->ToWebLocalFrame()))
.ToV8();
else
return v8::Null(isolate());
}
v8::Local<v8::Value> WebFrame::Top() const {
blink::WebFrame* frame = web_frame_->Top();
if (frame && frame->IsWebLocalFrame())
return mate::CreateHandle(isolate(),
new WebFrame(isolate(), frame->ToWebLocalFrame()))
.ToV8();
else
return v8::Null(isolate());
}
v8::Local<v8::Value> WebFrame::FirstChild() const {
blink::WebFrame* frame = web_frame_->FirstChild();
if (frame && frame->IsWebLocalFrame())
return mate::CreateHandle(isolate(),
new WebFrame(isolate(), frame->ToWebLocalFrame()))
.ToV8();
else
return v8::Null(isolate());
}
v8::Local<v8::Value> WebFrame::NextSibling() const {
blink::WebFrame* frame = web_frame_->NextSibling();
if (frame && frame->IsWebLocalFrame())
return mate::CreateHandle(isolate(),
new WebFrame(isolate(), frame->ToWebLocalFrame()))
.ToV8();
else
return v8::Null(isolate());
}
v8::Local<v8::Value> WebFrame::GetFrameForSelector(
const std::string& selector) const {
blink::WebElement element = web_frame_->GetDocument().QuerySelector(
blink::WebString::FromUTF8(selector));
blink::WebLocalFrame* element_frame =
blink::WebLocalFrame::FromFrameOwnerElement(element);
if (element_frame)
return mate::CreateHandle(isolate(), new WebFrame(isolate(), element_frame))
.ToV8();
else
return v8::Null(isolate());
}
v8::Local<v8::Value> WebFrame::FindFrameByName(const std::string& name) const {
blink::WebLocalFrame* local_frame =
web_frame_->FindFrameByName(blink::WebString::FromUTF8(name))
->ToWebLocalFrame();
if (local_frame)
return mate::CreateHandle(isolate(), new WebFrame(isolate(), local_frame))
.ToV8();
else
return v8::Null(isolate());
}
v8::Local<v8::Value> WebFrame::FindFrameByRoutingId(int routing_id) const {
v8::Local<v8::Value> FindFrameByRoutingId(v8::Isolate* isolate,
v8::Local<v8::Value> window,
int routing_id) {
content::RenderFrame* render_frame =
content::RenderFrame::FromRoutingID(routing_id);
blink::WebLocalFrame* local_frame = nullptr;
if (render_frame)
local_frame = render_frame->GetWebFrame();
if (local_frame)
return mate::CreateHandle(isolate(), new WebFrame(isolate(), local_frame))
.ToV8();
return render_frame->GetWebFrame()->MainWorldScriptContext()->Global();
else
return v8::Null(isolate());
return v8::Null(isolate);
}
v8::Local<v8::Value> WebFrame::RoutingId() const {
int routing_id = content::RenderFrame::GetRoutingIdForWebFrame(web_frame_);
return v8::Number::New(isolate(), routing_id);
v8::Local<v8::Value> GetOpener(v8::Isolate* isolate,
v8::Local<v8::Value> window) {
blink::WebFrame* frame = GetRenderFrame(window)->GetWebFrame()->Opener();
if (frame && frame->IsWebLocalFrame())
return frame->ToWebLocalFrame()->MainWorldScriptContext()->Global();
else
return v8::Null(isolate);
}
// static
void WebFrame::BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype) {
prototype->SetClassName(mate::StringToV8(isolate, "WebFrame"));
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
.SetMethod("setName", &WebFrame::SetName)
.SetMethod("setZoomLevel", &WebFrame::SetZoomLevel)
.SetMethod("getZoomLevel", &WebFrame::GetZoomLevel)
.SetMethod("setZoomFactor", &WebFrame::SetZoomFactor)
.SetMethod("getZoomFactor", &WebFrame::GetZoomFactor)
.SetMethod("setVisualZoomLevelLimits",
&WebFrame::SetVisualZoomLevelLimits)
.SetMethod("setLayoutZoomLevelLimits",
&WebFrame::SetLayoutZoomLevelLimits)
.SetMethod("registerEmbedderCustomElement",
&WebFrame::RegisterEmbedderCustomElement)
.SetMethod("getWebFrameId", &WebFrame::GetWebFrameId)
.SetMethod("setSpellCheckProvider", &WebFrame::SetSpellCheckProvider)
.SetMethod("registerURLSchemeAsBypassingCSP",
&WebFrame::RegisterURLSchemeAsBypassingCSP)
.SetMethod("registerURLSchemeAsPrivileged",
&WebFrame::RegisterURLSchemeAsPrivileged)
.SetMethod("insertText", &WebFrame::InsertText)
.SetMethod("insertCSS", &WebFrame::InsertCSS)
.SetMethod("executeJavaScript", &WebFrame::ExecuteJavaScript)
.SetMethod("executeJavaScriptInIsolatedWorld",
&WebFrame::ExecuteJavaScriptInIsolatedWorld)
.SetMethod("setIsolatedWorldSecurityOrigin",
&WebFrame::SetIsolatedWorldSecurityOrigin)
.SetMethod("setIsolatedWorldContentSecurityPolicy",
&WebFrame::SetIsolatedWorldContentSecurityPolicy)
.SetMethod("setIsolatedWorldHumanReadableName",
&WebFrame::SetIsolatedWorldHumanReadableName)
.SetMethod("getResourceUsage", &WebFrame::GetResourceUsage)
.SetMethod("clearCache", &WebFrame::ClearCache)
.SetMethod("getFrameForSelector", &WebFrame::GetFrameForSelector)
.SetMethod("findFrameByName", &WebFrame::FindFrameByName)
.SetProperty("opener", &WebFrame::Opener)
.SetProperty("parent", &WebFrame::Parent)
.SetProperty("top", &WebFrame::Top)
.SetProperty("firstChild", &WebFrame::FirstChild)
.SetProperty("nextSibling", &WebFrame::NextSibling)
.SetProperty("routingId", &WebFrame::RoutingId)
.SetMethod("findFrameByRoutingId", &WebFrame::FindFrameByRoutingId);
v8::Local<v8::Value> GetFrameParent(v8::Isolate* isolate,
v8::Local<v8::Value> window) {
blink::WebFrame* frame = GetRenderFrame(window)->GetWebFrame()->Parent();
if (frame && frame->IsWebLocalFrame())
return frame->ToWebLocalFrame()->MainWorldScriptContext()->Global();
else
return v8::Null(isolate);
}
v8::Local<v8::Value> GetTop(v8::Isolate* isolate, v8::Local<v8::Value> window) {
blink::WebFrame* frame = GetRenderFrame(window)->GetWebFrame()->Top();
if (frame && frame->IsWebLocalFrame())
return frame->ToWebLocalFrame()->MainWorldScriptContext()->Global();
else
return v8::Null(isolate);
}
v8::Local<v8::Value> GetFirstChild(v8::Isolate* isolate,
v8::Local<v8::Value> window) {
blink::WebFrame* frame = GetRenderFrame(window)->GetWebFrame()->FirstChild();
if (frame && frame->IsWebLocalFrame())
return frame->ToWebLocalFrame()->MainWorldScriptContext()->Global();
else
return v8::Null(isolate);
}
v8::Local<v8::Value> GetNextSibling(v8::Isolate* isolate,
v8::Local<v8::Value> window) {
blink::WebFrame* frame = GetRenderFrame(window)->GetWebFrame()->NextSibling();
if (frame && frame->IsWebLocalFrame())
return frame->ToWebLocalFrame()->MainWorldScriptContext()->Global();
else
return v8::Null(isolate);
}
v8::Local<v8::Value> GetFrameForSelector(v8::Isolate* isolate,
v8::Local<v8::Value> window,
const std::string& selector) {
blink::WebElement element =
GetRenderFrame(window)->GetWebFrame()->GetDocument().QuerySelector(
blink::WebString::FromUTF8(selector));
if (element.IsNull()) // not found
return v8::Null(isolate);
blink::WebFrame* frame = blink::WebFrame::FromFrameOwnerElement(element);
if (frame && frame->IsWebLocalFrame())
return frame->ToWebLocalFrame()->MainWorldScriptContext()->Global();
else
return v8::Null(isolate);
}
v8::Local<v8::Value> FindFrameByName(v8::Isolate* isolate,
v8::Local<v8::Value> window,
const std::string& name) {
blink::WebFrame* frame =
GetRenderFrame(window)->GetWebFrame()->FindFrameByName(
blink::WebString::FromUTF8(name));
if (frame && frame->IsWebLocalFrame())
return frame->ToWebLocalFrame()->MainWorldScriptContext()->Global();
else
return v8::Null(isolate);
}
int GetRoutingId(v8::Local<v8::Value> window) {
return GetRenderFrame(window)->GetRoutingID();
}
} // namespace api
@@ -527,16 +552,51 @@ void WebFrame::BuildPrototype(v8::Isolate* isolate,
namespace {
using atom::api::WebFrame;
void Initialize(v8::Local<v8::Object> exports,
v8::Local<v8::Value> unused,
v8::Local<v8::Context> context,
void* priv) {
using namespace atom::api; // NOLINT(build/namespaces)
v8::Isolate* isolate = context->GetIsolate();
mate::Dictionary dict(isolate, exports);
dict.Set("webFrame", WebFrame::Create(isolate));
dict.Set("WebFrame", WebFrame::GetConstructor(isolate)->GetFunction());
dict.SetMethod("setName", &SetName);
dict.SetMethod("setZoomLevel", &SetZoomLevel);
dict.SetMethod("getZoomLevel", &GetZoomLevel);
dict.SetMethod("setZoomFactor", &SetZoomFactor);
dict.SetMethod("getZoomFactor", &GetZoomFactor);
dict.SetMethod("setVisualZoomLevelLimits", &SetVisualZoomLevelLimits);
dict.SetMethod("setLayoutZoomLevelLimits", &SetLayoutZoomLevelLimits);
dict.SetMethod("registerEmbedderCustomElement",
&RegisterEmbedderCustomElement);
dict.SetMethod("getWebFrameId", &GetWebFrameId);
dict.SetMethod("setSpellCheckProvider", &SetSpellCheckProvider);
dict.SetMethod("registerURLSchemeAsBypassingCSP",
&RegisterURLSchemeAsBypassingCSP);
dict.SetMethod("registerURLSchemeAsPrivileged",
&RegisterURLSchemeAsPrivileged);
dict.SetMethod("insertText", &InsertText);
dict.SetMethod("insertCSS", &InsertCSS);
dict.SetMethod("executeJavaScript", &ExecuteJavaScript);
dict.SetMethod("executeJavaScriptInIsolatedWorld",
&ExecuteJavaScriptInIsolatedWorld);
dict.SetMethod("setIsolatedWorldSecurityOrigin",
&SetIsolatedWorldSecurityOrigin);
dict.SetMethod("setIsolatedWorldContentSecurityPolicy",
&SetIsolatedWorldContentSecurityPolicy);
dict.SetMethod("setIsolatedWorldHumanReadableName",
&SetIsolatedWorldHumanReadableName);
dict.SetMethod("getResourceUsage", &GetResourceUsage);
dict.SetMethod("clearCache", &ClearCache);
dict.SetMethod("_findFrameByRoutingId", &FindFrameByRoutingId);
dict.SetMethod("_getFrameForSelector", &GetFrameForSelector);
dict.SetMethod("_findFrameByName", &FindFrameByName);
dict.SetMethod("_getOpener", &GetOpener);
dict.SetMethod("_getParent", &GetFrameParent);
dict.SetMethod("_getTop", &GetTop);
dict.SetMethod("_getFirstChild", &GetFirstChild);
dict.SetMethod("_getNextSibling", &GetNextSibling);
dict.SetMethod("_getRoutingId", &GetRoutingId);
}
} // namespace

View File

@@ -1,113 +0,0 @@
// Copyright (c) 2014 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef ATOM_RENDERER_API_ATOM_API_WEB_FRAME_H_
#define ATOM_RENDERER_API_ATOM_API_WEB_FRAME_H_
#include <memory>
#include <string>
#include <vector>
#include "native_mate/handle.h"
#include "native_mate/wrappable.h"
#include "third_party/WebKit/public/platform/WebCache.h"
namespace blink {
class WebLocalFrame;
}
namespace mate {
class Dictionary;
class Arguments;
} // namespace mate
namespace atom {
namespace api {
class SpellCheckClient;
class WebFrame : public mate::Wrappable<WebFrame> {
public:
static mate::Handle<WebFrame> Create(v8::Isolate* isolate);
static void BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype);
private:
explicit WebFrame(v8::Isolate* isolate);
explicit WebFrame(v8::Isolate* isolate, blink::WebLocalFrame* blink_frame);
~WebFrame() override;
void SetName(const std::string& name);
double SetZoomLevel(double level);
double GetZoomLevel() const;
double SetZoomFactor(double factor);
double GetZoomFactor() const;
void SetVisualZoomLevelLimits(double min_level, double max_level);
void SetLayoutZoomLevelLimits(double min_level, double max_level);
v8::Local<v8::Value> RegisterEmbedderCustomElement(
const base::string16& name,
v8::Local<v8::Object> options);
int GetWebFrameId(v8::Local<v8::Value> content_window);
// Set the provider that will be used by SpellCheckClient for spell check.
void SetSpellCheckProvider(mate::Arguments* args,
const std::string& language,
bool auto_spell_correct_turned_on,
v8::Local<v8::Object> provider);
void RegisterURLSchemeAsBypassingCSP(const std::string& scheme);
void RegisterURLSchemeAsPrivileged(const std::string& scheme,
mate::Arguments* args);
// Editing.
void InsertText(const std::string& text);
void InsertCSS(const std::string& css);
// Executing scripts.
void ExecuteJavaScript(const base::string16& code, mate::Arguments* args);
void ExecuteJavaScriptInIsolatedWorld(
int world_id,
const std::vector<mate::Dictionary>& scripts,
mate::Arguments* args);
// Isolated world related methods
void SetIsolatedWorldSecurityOrigin(int world_id,
const std::string& origin_url);
void SetIsolatedWorldContentSecurityPolicy(
int world_id,
const std::string& security_policy);
void SetIsolatedWorldHumanReadableName(int world_id, const std::string& name);
// Resource related methods
blink::WebCache::ResourceTypeStats GetResourceUsage(v8::Isolate* isolate);
void ClearCache(v8::Isolate* isolate);
// Frame navigation
v8::Local<v8::Value> Opener() const;
v8::Local<v8::Value> Parent() const;
v8::Local<v8::Value> Top() const;
v8::Local<v8::Value> FirstChild() const;
v8::Local<v8::Value> NextSibling() const;
v8::Local<v8::Value> GetFrameForSelector(const std::string& selector) const;
v8::Local<v8::Value> FindFrameByName(const std::string& name) const;
v8::Local<v8::Value> FindFrameByRoutingId(int routing_id) const;
v8::Local<v8::Value> RoutingId() const;
std::unique_ptr<SpellCheckClient> spell_check_client_;
blink::WebLocalFrame* web_frame_;
DISALLOW_COPY_AND_ASSIGN(WebFrame);
};
} // namespace api
} // namespace atom
#endif // ATOM_RENDERER_API_ATOM_API_WEB_FRAME_H_

View File

@@ -16,6 +16,7 @@
#include "atom/renderer/atom_render_frame_observer.h"
#include "atom/renderer/web_worker_observer.h"
#include "base/command_line.h"
#include "content/public/common/web_preferences.h"
#include "content/public/renderer/render_frame.h"
#include "native_mate/dictionary.h"
#include "third_party/WebKit/public/web/WebDocument.h"
@@ -86,6 +87,15 @@ void AtomRendererClient::DidCreateScriptContext(
if (!render_frame->IsMainFrame() && !IsDevToolsExtension(render_frame))
return;
// Don't allow node integration if this is a child window and it does not have
// node integration enabled. Otherwise we would have memory leak in the child
// window since we don't clean up node environments.
//
// TODO(zcbenz): We shouldn't allow node integration even for the top frame.
if (!render_frame->GetWebkitPreferences().node_integration &&
render_frame->GetWebFrame()->Opener())
return;
injected_frames_.insert(render_frame);
// Prepare the node bindings.

View File

@@ -125,8 +125,10 @@ class AtomSandboxedRenderFrameObserver : public AtomRenderFrameObserver {
auto* isolate = blink::MainThreadIsolate();
v8::HandleScope handle_scope(isolate);
auto context = frame->MainWorldScriptContext();
auto context = renderer_client_->GetContext(frame, isolate);
v8::Context::Scope context_scope(context);
v8::Local<v8::Value> argv[] = {mate::ConvertToV8(isolate, channel),
mate::ConvertToV8(isolate, args)};
renderer_client_->InvokeIpcCallback(
@@ -191,6 +193,8 @@ void AtomSandboxedRendererClient::DidCreateScriptContext(
// Execute the function with proper arguments
ignore_result(
func->Call(context, v8::Null(isolate), node::arraysize(args), args));
InvokeIpcCallback(context, "onLoaded", std::vector<v8::Local<v8::Value>>());
}
void AtomSandboxedRendererClient::WillReleaseScriptContext(

View File

@@ -173,22 +173,26 @@ void RendererClientBase::RenderFrameCreated(
blink::WebSecurityPolicy::AddOriginAccessWhitelistEntry(
GURL(kPdfViewerUIOrigin), "file", "", true);
#endif // defined(ENABLE_PDF_VIEWER)
content::RenderView* render_view = render_frame->GetRenderView();
if (render_frame->IsMainFrame() && render_view) {
blink::WebFrameWidget* web_frame_widget = render_view->GetWebFrameWidget();
if (web_frame_widget) {
base::CommandLine* cmd = base::CommandLine::ForCurrentProcess();
if (cmd->HasSwitch(switches::kGuestInstanceID)) { // webview.
web_frame_widget->SetBaseBackgroundColor(SK_ColorTRANSPARENT);
} else { // normal window.
std::string name = cmd->GetSwitchValueASCII(switches::kBackgroundColor);
SkColor color =
name.empty() ? SK_ColorTRANSPARENT : ParseHexColor(name);
web_frame_widget->SetBaseBackgroundColor(color);
}
}
}
}
void RendererClientBase::RenderViewCreated(content::RenderView* render_view) {
new AtomRenderViewObserver(render_view);
blink::WebFrameWidget* web_frame_widget = render_view->GetWebFrameWidget();
if (!web_frame_widget)
return;
base::CommandLine* cmd = base::CommandLine::ForCurrentProcess();
if (cmd->HasSwitch(switches::kGuestInstanceID)) { // webview.
web_frame_widget->SetBaseBackgroundColor(SK_ColorTRANSPARENT);
} else { // normal window.
std::string name = cmd->GetSwitchValueASCII(switches::kBackgroundColor);
SkColor color = name.empty() ? SK_ColorTRANSPARENT : ParseHexColor(name);
web_frame_widget->SetBaseBackgroundColor(color);
}
}
void RendererClientBase::DidClearWindowObject(

View File

@@ -4,6 +4,10 @@
#include "atom/utility/atom_content_utility_client.h"
#include "content/public/child/child_thread.h"
#include "services/proxy_resolver/proxy_resolver_service.h"
#include "services/proxy_resolver/public/mojom/proxy_resolver.mojom.h"
#if defined(OS_WIN)
#include "chrome/utility/printing_handler_win.h"
#endif
@@ -29,4 +33,14 @@ bool AtomContentUtilityClient::OnMessageReceived(const IPC::Message& message) {
return false;
}
void AtomContentUtilityClient::RegisterServices(StaticServiceMap* services) {
service_manager::EmbeddedServiceInfo proxy_resolver_info;
proxy_resolver_info.task_runner =
content::ChildThread::Get()->GetIOTaskRunner();
proxy_resolver_info.factory =
base::BindRepeating(&proxy_resolver::ProxyResolverService::CreateService);
services->emplace(proxy_resolver::mojom::kProxyResolverServiceName,
proxy_resolver_info);
}
} // namespace atom

View File

@@ -21,6 +21,7 @@ class AtomContentUtilityClient : public content::ContentUtilityClient {
~AtomContentUtilityClient() override;
bool OnMessageReceived(const IPC::Message& message) override;
void RegisterServices(StaticServiceMap* services) override;
private:
#if defined(OS_WIN)

View File

@@ -150,8 +150,8 @@
'<(libchromiumcontent_dir)/libfx_agg.a',
'<(libchromiumcontent_dir)/libfx_lcms2.a',
'<(libchromiumcontent_dir)/libfx_libopenjpeg.a',
'<(libchromiumcontent_dir)/libfx_zlib.a',
'-Wl,--no-whole-archive',
'<(libchromiumcontent_dir)/libchrome.a',
],
},
}, {
@@ -221,6 +221,7 @@
'<(libchromiumcontent_dir)/librenderer.a',
'<(libchromiumcontent_dir)/libsecurity_state.a',
'<(libchromiumcontent_dir)/libviz_service.a',
'<(libchromiumcontent_dir)/libchrome.a',
# services/device/wake_lock/power_save_blocker/
'<(libchromiumcontent_dir)/libpower_save_blocker.a',
# Friends of libpdf.a:
@@ -360,6 +361,7 @@
'<(libchromiumcontent_dir)/renderer.lib',
'<(libchromiumcontent_dir)/security_state.lib',
'<(libchromiumcontent_dir)/viz_service.lib',
'<(libchromiumcontent_dir)/chrome.lib',
# services/device/wake_lock/power_save_blocker/
'<(libchromiumcontent_dir)/power_save_blocker.lib',
# Friends of pdf.lib:

View File

@@ -6,7 +6,6 @@
#include "base/lazy_instance.h"
#include "base/path_service.h"
#include "brightray/browser/browser_context.h"
#include "brightray/browser/browser_main_parts.h"
#include "brightray/browser/devtools_manager_delegate.h"
#include "brightray/browser/media/media_capture_devices_dispatcher.h"
@@ -106,10 +105,6 @@ void BrowserClient::GetAdditionalWebUISchemes(
additional_schemes->push_back(content::kChromeDevToolsScheme);
}
NetLog* BrowserClient::GetNetLog() {
return &net_log_;
}
base::FilePath BrowserClient::GetDefaultDownloadDirectory() {
// ~/Downloads
base::FilePath path;

View File

@@ -8,7 +8,6 @@
#include <string>
#include <vector>
#include "brightray/browser/net_log.h"
#include "content/public/browser/content_browser_client.h"
namespace brightray {
@@ -45,7 +44,6 @@ class BrowserClient : public content::ContentBrowserClient {
std::vector<std::string>* additional_schemes) override;
void GetAdditionalWebUISchemes(
std::vector<std::string>* additional_schemes) override;
NetLog* GetNetLog() override;
base::FilePath GetDefaultDownloadDirectory() override;
content::DevToolsManagerDelegate* GetDevToolsManagerDelegate() override;
std::string GetApplicationLocale() override;
@@ -59,7 +57,6 @@ class BrowserClient : public content::ContentBrowserClient {
private:
BrowserMainParts* browser_main_parts_;
NetLog net_log_;
std::unique_ptr<PlatformNotificationService> notification_service_;
std::unique_ptr<NotificationPresenter> notification_presenter_;

View File

@@ -1,211 +0,0 @@
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE-CHROMIUM file.
#include "brightray/browser/browser_context.h"
#include "base/files/file_path.h"
#include "base/path_service.h"
#include "base/strings/string_util.h"
#include "base/threading/thread_restrictions.h"
#include "brightray/browser/brightray_paths.h"
#include "brightray/browser/browser_client.h"
#include "brightray/browser/inspectable_web_contents_impl.h"
#include "brightray/browser/special_storage_policy.h"
#include "brightray/browser/zoom_level_delegate.h"
#include "brightray/common/application_info.h"
#include "components/prefs/json_pref_store.h"
#include "components/prefs/pref_registry_simple.h"
#include "components/prefs/pref_service.h"
#include "components/prefs/pref_service_factory.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/storage_partition.h"
#include "net/base/escape.h"
using content::BrowserThread;
namespace brightray {
namespace {
// Convert string to lower case and escape it.
std::string MakePartitionName(const std::string& input) {
return net::EscapePath(base::ToLowerASCII(input));
}
} // namespace
// static
void BrowserContextDeleter::Destruct(const BrowserContext* browser_context) {
browser_context->OnDestruct();
}
// static
BrowserContext::BrowserContextMap BrowserContext::browser_context_map_;
// static
scoped_refptr<BrowserContext> BrowserContext::Get(const std::string& partition,
bool in_memory) {
PartitionKey key(partition, in_memory);
if (browser_context_map_[key].get())
return WrapRefCounted(browser_context_map_[key].get());
return nullptr;
}
BrowserContext::BrowserContext(const std::string& partition, bool in_memory)
: in_memory_(in_memory),
storage_policy_(new SpecialStoragePolicy),
weak_factory_(this) {
if (!PathService::Get(DIR_USER_DATA, &path_)) {
PathService::Get(DIR_APP_DATA, &path_);
path_ = path_.Append(base::FilePath::FromUTF8Unsafe(GetApplicationName()));
PathService::Override(DIR_USER_DATA, path_);
}
if (!in_memory_ && !partition.empty())
path_ = path_.Append(FILE_PATH_LITERAL("Partitions"))
.Append(base::FilePath::FromUTF8Unsafe(
MakePartitionName(partition)));
content::BrowserContext::Initialize(this, path_);
io_handle_ = new URLRequestContextGetter::Handle(GetWeakPtr());
browser_context_map_[PartitionKey(partition, in_memory)] = GetWeakPtr();
}
BrowserContext::~BrowserContext() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
NotifyWillBeDestroyed(this);
ShutdownStoragePartitions();
io_handle_->ShutdownOnUIThread();
}
void BrowserContext::OnDestruct() const {
if (BrowserThread::CurrentlyOn(BrowserThread::UI)) {
delete this;
} else {
BrowserThread::DeleteSoon(BrowserThread::UI, FROM_HERE, this);
}
}
void BrowserContext::InitPrefs() {
auto prefs_path = GetPath().Append(FILE_PATH_LITERAL("Preferences"));
base::ThreadRestrictions::ScopedAllowIO allow_io;
PrefServiceFactory prefs_factory;
scoped_refptr<JsonPrefStore> pref_store =
base::MakeRefCounted<JsonPrefStore>(prefs_path);
pref_store->ReadPrefs(); // Synchronous.
prefs_factory.set_user_prefs(pref_store);
auto registry = WrapRefCounted(new PrefRegistrySimple);
RegisterInternalPrefs(registry.get());
RegisterPrefs(registry.get());
prefs_ = prefs_factory.Create(registry.get());
}
void BrowserContext::RegisterInternalPrefs(PrefRegistrySimple* registry) {
InspectableWebContentsImpl::RegisterPrefs(registry);
MediaDeviceIDSalt::RegisterPrefs(registry);
ZoomLevelDelegate::RegisterPrefs(registry);
}
URLRequestContextGetter* BrowserContext::GetRequestContext() {
return static_cast<URLRequestContextGetter*>(
GetDefaultStoragePartition(this)->GetURLRequestContext());
}
net::URLRequestContextGetter* BrowserContext::CreateRequestContext(
content::ProtocolHandlerMap* protocol_handlers,
content::URLRequestInterceptorScopedVector protocol_interceptors) {
return io_handle_
->CreateMainRequestContextGetter(protocol_handlers,
std::move(protocol_interceptors))
.get();
}
std::string BrowserContext::GetMediaDeviceIDSalt() {
if (!media_device_id_salt_.get())
media_device_id_salt_.reset(new MediaDeviceIDSalt(prefs_.get()));
return media_device_id_salt_->GetSalt();
}
base::FilePath BrowserContext::GetPath() const {
return path_;
}
std::unique_ptr<content::ZoomLevelDelegate>
BrowserContext::CreateZoomLevelDelegate(const base::FilePath& partition_path) {
if (!IsOffTheRecord()) {
return std::make_unique<ZoomLevelDelegate>(prefs(), partition_path);
}
return std::unique_ptr<content::ZoomLevelDelegate>();
}
bool BrowserContext::IsOffTheRecord() const {
return in_memory_;
}
content::ResourceContext* BrowserContext::GetResourceContext() {
return io_handle_->GetResourceContext();
}
content::DownloadManagerDelegate* BrowserContext::GetDownloadManagerDelegate() {
return nullptr;
}
content::BrowserPluginGuestManager* BrowserContext::GetGuestManager() {
return nullptr;
}
storage::SpecialStoragePolicy* BrowserContext::GetSpecialStoragePolicy() {
return storage_policy_.get();
}
content::PushMessagingService* BrowserContext::GetPushMessagingService() {
return nullptr;
}
content::SSLHostStateDelegate* BrowserContext::GetSSLHostStateDelegate() {
return nullptr;
}
content::BackgroundFetchDelegate* BrowserContext::GetBackgroundFetchDelegate() {
return nullptr;
}
content::BackgroundSyncController*
BrowserContext::GetBackgroundSyncController() {
return nullptr;
}
content::BrowsingDataRemoverDelegate*
BrowserContext::GetBrowsingDataRemoverDelegate() {
return nullptr;
}
net::URLRequestContextGetter*
BrowserContext::CreateRequestContextForStoragePartition(
const base::FilePath& partition_path,
bool in_memory,
content::ProtocolHandlerMap* protocol_handlers,
content::URLRequestInterceptorScopedVector request_interceptors) {
NOTREACHED();
return nullptr;
}
net::URLRequestContextGetter* BrowserContext::CreateMediaRequestContext() {
return io_handle_->GetMainRequestContextGetter().get();
}
net::URLRequestContextGetter*
BrowserContext::CreateMediaRequestContextForStoragePartition(
const base::FilePath& partition_path,
bool in_memory) {
NOTREACHED();
return nullptr;
}
} // namespace brightray

View File

@@ -1,138 +0,0 @@
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE-CHROMIUM file.
#ifndef BRIGHTRAY_BROWSER_BROWSER_CONTEXT_H_
#define BRIGHTRAY_BROWSER_BROWSER_CONTEXT_H_
#include <map>
#include <string>
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "brightray/browser/media/media_device_id_salt.h"
#include "brightray/browser/url_request_context_getter.h"
#include "content/public/browser/browser_context.h"
class PrefRegistrySimple;
class PrefService;
namespace storage {
class SpecialStoragePolicy;
}
namespace brightray {
class BrowserContext;
struct BrowserContextDeleter {
static void Destruct(const BrowserContext* browser_context);
};
class BrowserContext
: public base::RefCountedThreadSafe<BrowserContext, BrowserContextDeleter>,
public content::BrowserContext {
public:
// Get the BrowserContext according to its |partition| and |in_memory|,
// empty pointer when be returned when there is no matching BrowserContext.
static scoped_refptr<BrowserContext> Get(const std::string& partition,
bool in_memory);
base::WeakPtr<BrowserContext> GetWeakPtr() {
return weak_factory_.GetWeakPtr();
}
// Get the request context, if there is no one, create it.
URLRequestContextGetter* GetRequestContext();
// content::BrowserContext:
std::unique_ptr<content::ZoomLevelDelegate> CreateZoomLevelDelegate(
const base::FilePath& partition_path) override;
bool IsOffTheRecord() const override;
content::ResourceContext* GetResourceContext() override;
content::DownloadManagerDelegate* GetDownloadManagerDelegate() override;
content::BrowserPluginGuestManager* GetGuestManager() override;
storage::SpecialStoragePolicy* GetSpecialStoragePolicy() override;
content::PushMessagingService* GetPushMessagingService() override;
content::SSLHostStateDelegate* GetSSLHostStateDelegate() override;
content::BackgroundFetchDelegate* GetBackgroundFetchDelegate() override;
content::BackgroundSyncController* GetBackgroundSyncController() override;
content::BrowsingDataRemoverDelegate* GetBrowsingDataRemoverDelegate()
override;
net::URLRequestContextGetter* CreateRequestContext(
content::ProtocolHandlerMap* protocol_handlers,
content::URLRequestInterceptorScopedVector request_interceptors) override;
net::URLRequestContextGetter* CreateRequestContextForStoragePartition(
const base::FilePath& partition_path,
bool in_memory,
content::ProtocolHandlerMap* protocol_handlers,
content::URLRequestInterceptorScopedVector request_interceptors) override;
net::URLRequestContextGetter* CreateMediaRequestContext() override;
net::URLRequestContextGetter* CreateMediaRequestContextForStoragePartition(
const base::FilePath& partition_path,
bool in_memory) override;
std::string GetMediaDeviceIDSalt() override;
base::FilePath GetPath() const override;
void InitPrefs();
PrefService* prefs() { return prefs_.get(); }
virtual std::string GetUserAgent() const = 0;
virtual void OnMainRequestContextCreated(URLRequestContextGetter* getter) {}
protected:
BrowserContext(const std::string& partition, bool in_memory);
~BrowserContext() override;
// Subclasses should override this to register custom preferences.
virtual void RegisterPrefs(PrefRegistrySimple* pref_registry) {}
private:
friend class base::RefCountedThreadSafe<BrowserContext,
BrowserContextDeleter>;
friend class base::DeleteHelper<BrowserContext>;
friend struct BrowserContextDeleter;
void RegisterInternalPrefs(PrefRegistrySimple* pref_registry);
void OnDestruct() const;
// partition_id => browser_context
struct PartitionKey {
std::string partition;
bool in_memory;
PartitionKey(const std::string& partition, bool in_memory)
: partition(partition), in_memory(in_memory) {}
bool operator<(const PartitionKey& other) const {
if (partition == other.partition)
return in_memory < other.in_memory;
return partition < other.partition;
}
bool operator==(const PartitionKey& other) const {
return (partition == other.partition) && (in_memory == other.in_memory);
}
};
using BrowserContextMap =
std::map<PartitionKey, base::WeakPtr<brightray::BrowserContext>>;
static BrowserContextMap browser_context_map_;
base::FilePath path_;
bool in_memory_;
scoped_refptr<storage::SpecialStoragePolicy> storage_policy_;
std::unique_ptr<PrefService> prefs_;
std::unique_ptr<MediaDeviceIDSalt> media_device_id_salt_;
// Self-destructing class responsible for creating URLRequestContextGetter
// on the UI thread and deletes itself on the IO thread.
URLRequestContextGetter::Handle* io_handle_;
base::WeakPtrFactory<BrowserContext> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(BrowserContext);
};
} // namespace brightray
#endif // BRIGHTRAY_BROWSER_BROWSER_CONTEXT_H_

View File

@@ -22,7 +22,6 @@
#include "base/strings/string_number_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "brightray/browser/browser_client.h"
#include "brightray/browser/browser_context.h"
#include "brightray/browser/devtools_manager_delegate.h"
#include "brightray/browser/media/media_capture_devices_dispatcher.h"
#include "brightray/browser/web_ui_controller_factory.h"
@@ -181,8 +180,15 @@ void OverrideAppLogsPath() {
void BrowserMainParts::InitializeFeatureList() {
auto* cmd_line = base::CommandLine::ForCurrentProcess();
const auto enable_features =
auto enable_features =
cmd_line->GetSwitchValueASCII(switches::kEnableFeatures);
#if defined(OS_WIN)
// On Windows, when you set an accelerator with Ctrl and Alt both added as
// a modifier, it screws with the event modifiers, and also sets AltGr as
// enabled. There is a fix for this in chromium, but it's not enabled by
// default in 3-0-x. http://crbug.com/25503
enable_features += std::string(",FixAltGraph");
#endif
auto disable_features =
cmd_line->GetSwitchValueASCII(switches::kDisableFeatures);
auto feature_list = std::make_unique<base::FeatureList>();
@@ -311,9 +317,6 @@ int BrowserMainParts::PreCreateThreads() {
BrowserClient::SetApplicationLocale(
l10n_util::GetApplicationLocale(custom_locale_));
// Manage global state of net and other IO thread related.
io_thread_ = std::make_unique<IOThread>();
return 0;
}
@@ -322,8 +325,6 @@ void BrowserMainParts::PostDestroyThreads() {
device::BluetoothAdapterFactory::Shutdown();
bluez::DBusBluezManagerWrapperLinux::Shutdown();
#endif
io_thread_.reset();
}
} // namespace brightray

Some files were not shown because too many files have changed in this diff Show More