mirror of
https://github.com/electron/electron.git
synced 2026-02-19 03:14:51 -05:00
Compare commits
315 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f1a914c0ba | ||
|
|
5eff97c890 | ||
|
|
0039e604a2 | ||
|
|
26176eb108 | ||
|
|
fb82bfa707 | ||
|
|
9b724dca49 | ||
|
|
b52a2aedf1 | ||
|
|
8e671dafc1 | ||
|
|
0491abf4cc | ||
|
|
1655976841 | ||
|
|
0b5a7379f2 | ||
|
|
a5ed8fb65e | ||
|
|
bb631892b2 | ||
|
|
64026ded95 | ||
|
|
e6178f83fe | ||
|
|
ee5403d3ec | ||
|
|
6b77e2ee14 | ||
|
|
075b085cb4 | ||
|
|
cbd017572a | ||
|
|
3f0c863225 | ||
|
|
a459cee938 | ||
|
|
783614a94c | ||
|
|
db1395628a | ||
|
|
5e33a5e778 | ||
|
|
ce502b19ba | ||
|
|
1cfd7160dc | ||
|
|
339174dca0 | ||
|
|
6964a8cd72 | ||
|
|
51a97917e0 | ||
|
|
3ca1cd4dd4 | ||
|
|
c2c0ee7a73 | ||
|
|
739f620152 | ||
|
|
fb379c3b6a | ||
|
|
237688abb3 | ||
|
|
94070cec53 | ||
|
|
e8ef52bc1d | ||
|
|
2f9876a3f9 | ||
|
|
5ca94a8715 | ||
|
|
ffd1d6d8ad | ||
|
|
33c86527e8 | ||
|
|
871f123080 | ||
|
|
3dcf66839e | ||
|
|
78a2237add | ||
|
|
be68c062d7 | ||
|
|
dbf8872817 | ||
|
|
a50e3b3f5f | ||
|
|
063bcb68f2 | ||
|
|
364e8b1a1d | ||
|
|
779f285777 | ||
|
|
4e1a5a210a | ||
|
|
98d78f2fb5 | ||
|
|
a8e70a8546 | ||
|
|
1ca76e8e74 | ||
|
|
16757d16e7 | ||
|
|
d2b2b97c29 | ||
|
|
6bc7bc11d8 | ||
|
|
f3d4daa9e5 | ||
|
|
6c0157aa29 | ||
|
|
a9e0aa22a4 | ||
|
|
56160e990e | ||
|
|
ab83309c7a | ||
|
|
c474ff101c | ||
|
|
54902e848f | ||
|
|
7bec7e6cee | ||
|
|
55224e385e | ||
|
|
75fecf4e4f | ||
|
|
f2f483fedb | ||
|
|
5614ae4241 | ||
|
|
55abf1f3a1 | ||
|
|
0f78f8a66c | ||
|
|
fa4a26a1db | ||
|
|
7ba29f1fa8 | ||
|
|
2f148fdaf4 | ||
|
|
19c31c684a | ||
|
|
c61a20c390 | ||
|
|
4ae3031faf | ||
|
|
72fee2ed78 | ||
|
|
cba1a946d5 | ||
|
|
c55bc8106f | ||
|
|
261f7fd3be | ||
|
|
53894d5ac2 | ||
|
|
c006a6db66 | ||
|
|
a306fdf512 | ||
|
|
825bd6d45e | ||
|
|
922a4d9ba6 | ||
|
|
f20d497f1c | ||
|
|
855bd92f6e | ||
|
|
60d36e1b74 | ||
|
|
9788089efb | ||
|
|
c0e9761b4b | ||
|
|
7e6617be18 | ||
|
|
38b6a7bf4f | ||
|
|
0aec64960b | ||
|
|
eab462f7cf | ||
|
|
5ccdb8c7cd | ||
|
|
dc38746b24 | ||
|
|
66c2bd2a02 | ||
|
|
cbfd276917 | ||
|
|
450a83d0f7 | ||
|
|
b7408e61d2 | ||
|
|
9d333a72e1 | ||
|
|
c5f4fe09aa | ||
|
|
38f2d11c39 | ||
|
|
3c852e79e6 | ||
|
|
019e60517f | ||
|
|
fb51509153 | ||
|
|
f3b9f58b7f | ||
|
|
a49307bc55 | ||
|
|
742292f082 | ||
|
|
bb0f4fdbdf | ||
|
|
5e2ca967c9 | ||
|
|
c8029d1696 | ||
|
|
08aa86e55e | ||
|
|
825c082535 | ||
|
|
4a073e4f7e | ||
|
|
adffa99e05 | ||
|
|
51f03033a4 | ||
|
|
733251866c | ||
|
|
41a7d9e42b | ||
|
|
ddbbf34433 | ||
|
|
6f65dec6a2 | ||
|
|
a66657112c | ||
|
|
f5c3394930 | ||
|
|
84bae64def | ||
|
|
4185b93abb | ||
|
|
b1e9f50fad | ||
|
|
6bd901d9ca | ||
|
|
1c2b8f8d9a | ||
|
|
cb9b288d8b | ||
|
|
69fe33a2b1 | ||
|
|
52b42546ed | ||
|
|
8a285f29ed | ||
|
|
92df6cc36c | ||
|
|
ab91656148 | ||
|
|
1fb1e5b2b2 | ||
|
|
54908b56e5 | ||
|
|
48bc247ef7 | ||
|
|
19d9955125 | ||
|
|
24d79d9e5c | ||
|
|
27d0a4d33d | ||
|
|
48226f71ad | ||
|
|
a4acc16e10 | ||
|
|
d8dd94e3a3 | ||
|
|
eb48dcf0a3 | ||
|
|
adfe537e32 | ||
|
|
0d5d54cbae | ||
|
|
988ad92415 | ||
|
|
5dbcdbc3d8 | ||
|
|
212c6b1266 | ||
|
|
74b06ab677 | ||
|
|
9a1c952ab6 | ||
|
|
f36f90b60f | ||
|
|
a603a4dde8 | ||
|
|
3e033b4f27 | ||
|
|
03be4c67d5 | ||
|
|
b20fe76db7 | ||
|
|
503da640f7 | ||
|
|
bd48dfe3cc | ||
|
|
9b47f587a6 | ||
|
|
3a186dad5d | ||
|
|
7959f2e887 | ||
|
|
4868c95425 | ||
|
|
7fa41e3302 | ||
|
|
f3346437be | ||
|
|
6de6d7f6c0 | ||
|
|
eb15be06e3 | ||
|
|
7748decc60 | ||
|
|
d75750ab01 | ||
|
|
152781226e | ||
|
|
7e3bbb6ace | ||
|
|
3c3eb2f65d | ||
|
|
5a83d9e64d | ||
|
|
97bec607fe | ||
|
|
b56ca98b72 | ||
|
|
eeccdc2d5c | ||
|
|
47827ed45c | ||
|
|
d3f7bdd0b3 | ||
|
|
438c50bf14 | ||
|
|
33d860bcea | ||
|
|
2401a2afe9 | ||
|
|
852f0be0b2 | ||
|
|
18ec438eaf | ||
|
|
f7042c8d1b | ||
|
|
bc73f93e6c | ||
|
|
7091508678 | ||
|
|
6d9d66b88a | ||
|
|
fc35b0f1be | ||
|
|
17f86b1223 | ||
|
|
271531f5ff | ||
|
|
9ef83cd8a0 | ||
|
|
f33517dfa7 | ||
|
|
c69f5d9366 | ||
|
|
7902c3ced4 | ||
|
|
21f033474d | ||
|
|
549ac1ed48 | ||
|
|
2dd8d1f150 | ||
|
|
26ee461c32 | ||
|
|
9905a4c328 | ||
|
|
09a22143d6 | ||
|
|
81e8f5c6c2 | ||
|
|
3c322b7349 | ||
|
|
b2ea1bc517 | ||
|
|
16250493b8 | ||
|
|
08887e016c | ||
|
|
aadcce0907 | ||
|
|
9b5353309d | ||
|
|
76303502a6 | ||
|
|
cf07904338 | ||
|
|
8f1e28b59c | ||
|
|
10d0268070 | ||
|
|
7871e18232 | ||
|
|
ceb3792f3c | ||
|
|
65a4bdd87a | ||
|
|
7094870a44 | ||
|
|
cee99b5f2d | ||
|
|
ac86d362ba | ||
|
|
2233a9eb5a | ||
|
|
af24a4f364 | ||
|
|
a78692f5b8 | ||
|
|
335178098d | ||
|
|
ddc0e8f7ba | ||
|
|
80fa2449a1 | ||
|
|
476abafefe | ||
|
|
f7d4d51261 | ||
|
|
7b08510075 | ||
|
|
14b62b28ce | ||
|
|
1c44ed0912 | ||
|
|
de1edf3f4d | ||
|
|
a21ffa027a | ||
|
|
899d42563c | ||
|
|
6eecbb5edd | ||
|
|
6a8e7a10ea | ||
|
|
85bb488732 | ||
|
|
c957215854 | ||
|
|
2ba3a26785 | ||
|
|
f0dc3bc79f | ||
|
|
28d3edcd92 | ||
|
|
8026dee591 | ||
|
|
197cda9e45 | ||
|
|
903fd4e5e9 | ||
|
|
621c86b4cf | ||
|
|
deda7c700f | ||
|
|
d225304370 | ||
|
|
fd22b7ec2a | ||
|
|
a2b1d394b5 | ||
|
|
7d4c78e73e | ||
|
|
b37ff2b822 | ||
|
|
5887f5aa4f | ||
|
|
a9176a2ac8 | ||
|
|
6ceb431942 | ||
|
|
508d131c95 | ||
|
|
ae36659f7a | ||
|
|
f970660766 | ||
|
|
43c5837cda | ||
|
|
a87e88df20 | ||
|
|
5a5d4b06b3 | ||
|
|
28ba88ba70 | ||
|
|
4f8ffe934e | ||
|
|
c5c0a7abc5 | ||
|
|
84b762f0b3 | ||
|
|
043838f9b6 | ||
|
|
a824e92628 | ||
|
|
1843411e79 | ||
|
|
da76c4d7c5 | ||
|
|
4468b86a81 | ||
|
|
8acbb9a3ad | ||
|
|
f5e28bc999 | ||
|
|
b45ad7f74e | ||
|
|
9e9238454e | ||
|
|
3f2aba69ee | ||
|
|
371e804c6b | ||
|
|
6131e89aa9 | ||
|
|
c54b67300e | ||
|
|
e847f048d7 | ||
|
|
b5955fa663 | ||
|
|
a648e6c06d | ||
|
|
e6216da031 | ||
|
|
5b7bd56367 | ||
|
|
01b1c0ca8b | ||
|
|
05ced19f9f | ||
|
|
b8ef669905 | ||
|
|
212ce1840f | ||
|
|
e090fa94d0 | ||
|
|
a431f1a663 | ||
|
|
ea6815c0f7 | ||
|
|
40e05eef23 | ||
|
|
a790e702f5 | ||
|
|
be16a195fb | ||
|
|
2f10c0fd6d | ||
|
|
276c07d3d7 | ||
|
|
57f7c8b6b9 | ||
|
|
2ce22ba0e9 | ||
|
|
7186c62a27 | ||
|
|
bf88a13f1e | ||
|
|
6e9c540baf | ||
|
|
24b14d55ef | ||
|
|
3b8eb6c061 | ||
|
|
f9b7f6389e | ||
|
|
8f30faacf8 | ||
|
|
f631890237 | ||
|
|
8982889a8d | ||
|
|
cd3539aaf8 | ||
|
|
275e277721 | ||
|
|
283b1241d5 | ||
|
|
7bdea26085 | ||
|
|
f1fa589779 | ||
|
|
7226ad1eba | ||
|
|
d92743f0f3 | ||
|
|
2c309efef4 | ||
|
|
0b418315a3 | ||
|
|
2f474867c7 | ||
|
|
0b5acd9569 | ||
|
|
3419c3c730 | ||
|
|
754200f1b1 | ||
|
|
37f4bd4dd0 |
1767
.circleci/config.yml
1767
.circleci/config.yml
File diff suppressed because it is too large
Load Diff
@@ -1,3 +1,4 @@
|
||||
*
|
||||
!tools/xvfb-init.sh
|
||||
!tools/run-electron.sh
|
||||
!build/install-build-deps.sh
|
||||
|
||||
@@ -6,11 +6,9 @@
|
||||
"browser": true
|
||||
},
|
||||
"rules": {
|
||||
"semi": ["error", "always"],
|
||||
"no-var": "error",
|
||||
"no-unused-vars": 0,
|
||||
"no-global-assign": 0,
|
||||
"guard-for-in": 2,
|
||||
"@typescript-eslint/no-unused-vars": ["error", {
|
||||
"vars": "all",
|
||||
"args": "after-used",
|
||||
@@ -19,34 +17,18 @@
|
||||
"prefer-const": ["error", {
|
||||
"destructuring": "all"
|
||||
}],
|
||||
"standard/no-callback-literal": "off",
|
||||
"node/no-deprecated-api": 0
|
||||
},
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 6,
|
||||
"sourceType": "module"
|
||||
},
|
||||
"globals": {
|
||||
"standardScheme": "readonly",
|
||||
"BUILDFLAG": "readonly",
|
||||
"ENABLE_DESKTOP_CAPTURER": "readonly",
|
||||
"ENABLE_REMOTE_MODULE": "readonly",
|
||||
"ENABLE_VIEWS_API": "readonly",
|
||||
"BigInt": "readonly"
|
||||
},
|
||||
"overrides": [
|
||||
{
|
||||
"files": "*.js",
|
||||
"rules": {
|
||||
"@typescript-eslint/no-unused-vars": "off"
|
||||
}
|
||||
},
|
||||
{
|
||||
"files": "*.d.ts",
|
||||
"rules": {
|
||||
"no-useless-constructor": "off",
|
||||
"@typescript-eslint/no-unused-vars": "off"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
1
.gitattributes
vendored
1
.gitattributes
vendored
@@ -1,4 +1,3 @@
|
||||
# `git apply` and friends don't understand CRLF, even on windows. Force those
|
||||
# files to be checked out with LF endings even if core.autocrlf is true.
|
||||
*.patch text eol=lf
|
||||
patches/**/.patches merge=union
|
||||
|
||||
12
.github/CODEOWNERS
vendored
12
.github/CODEOWNERS
vendored
@@ -3,10 +3,20 @@
|
||||
# https://help.github.com/articles/about-codeowners
|
||||
# https://git-scm.com/docs/gitignore
|
||||
|
||||
# Most stuff in here is owned by the Community & Safety WG...
|
||||
/.github/* @electron/wg-community
|
||||
|
||||
# ...except the Admin WG maintains this file.
|
||||
/.github/CODEOWNERS @electron/wg-admin
|
||||
|
||||
# Upgrades WG
|
||||
/patches/ @electron/wg-upgrades
|
||||
DEPS @electron/wg-upgrades
|
||||
|
||||
|
||||
# Docs & Tooling WG
|
||||
/default_app/ @electron/wg-docs-tools
|
||||
/docs/ @electron/wg-docs-tools
|
||||
|
||||
# Releases WG
|
||||
/npm/ @electron/wg-releases
|
||||
/script/release @electron/wg-releases
|
||||
|
||||
10
.github/ISSUE_TEMPLATE/Bug_report.md
vendored
10
.github/ISSUE_TEMPLATE/Bug_report.md
vendored
@@ -20,7 +20,7 @@ about: Create a report to help us improve Electron
|
||||
* <!-- (output of `node_modules/.bin/electron --version`) e.g. 4.0.3 -->
|
||||
* **Operating System:**
|
||||
* <!-- (Platform and Version) e.g. macOS 10.13.6 / Windows 10 (1803) / Ubuntu 18.04 x64 -->
|
||||
* **Last Known Working Electron version:**
|
||||
* **Last Known Working Electron version:**:
|
||||
* <!-- (if applicable) e.g. 3.1.0 -->
|
||||
|
||||
### Expected Behavior
|
||||
@@ -31,15 +31,11 @@ about: Create a report to help us improve Electron
|
||||
|
||||
### To Reproduce
|
||||
<!--
|
||||
Your best chance of getting this bug looked at quickly is to provide an example.
|
||||
Your best chance of getting this bug looked at quickly is to provide a REPOSITORY that can be cloned and run.
|
||||
-->
|
||||
|
||||
<!--
|
||||
For bugs that can be encapsulated in a small experiment, you can use Electron Fiddle (https://github.com/electron/fiddle) to publish your example to a GitHub Gist and link it your bug report.
|
||||
-->
|
||||
|
||||
<!--
|
||||
If Fiddle is insufficient to produce an example, please provide an example REPOSITORY that can be cloned and run. You can fork electron-quick-start (https://github.com/electron/electron-quick-start) and include a link to the branch with your changes.
|
||||
You can fork electron-quick-start (https://github.com/electron/electron-quick-start) and include a link to the branch with your changes.
|
||||
-->
|
||||
|
||||
<!--
|
||||
|
||||
10
.github/ISSUE_TEMPLATE/security_report.md
vendored
Normal file
10
.github/ISSUE_TEMPLATE/security_report.md
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
---
|
||||
name: Security report
|
||||
about: Do not create an issue for security reports, send an email to security@electronjs.org
|
||||
|
||||
---
|
||||
|
||||
### Notice
|
||||
|
||||
**DO NOT** create an issue for security reports.
|
||||
Send an email to: **security@electronjs.org**.
|
||||
2
.github/PULL_REQUEST_TEMPLATE.md
vendored
2
.github/PULL_REQUEST_TEMPLATE.md
vendored
@@ -18,4 +18,4 @@ Contributors guide: https://github.com/electron/electron/blob/master/CONTRIBUTIN
|
||||
|
||||
#### Release Notes
|
||||
|
||||
Notes: <!-- Please add a one-line description for app developers to read in the release notes, or 'none' if no notes relevant to app developers. Examples and help on special cases: https://github.com/electron/clerk/blob/master/README.md#examples -->
|
||||
Notes: <!-- Please add a one-line description for app developers to read in the release notes, or `no-notes` if no notes relevant to app developers. Examples and help on special cases: https://github.com/electron/clerk/blob/master/README.md#examples -->
|
||||
|
||||
3
.github/config.yml
vendored
3
.github/config.yml
vendored
@@ -29,12 +29,13 @@ firstPRMergeComment: >
|
||||
# Users authorized to run manual trop backports
|
||||
authorizedUsers:
|
||||
- alexeykuzmin
|
||||
- BinaryMuse
|
||||
- ckerr
|
||||
- codebytere
|
||||
- deepak1556
|
||||
- jkleinsc
|
||||
- loc
|
||||
- MarshallOfSound
|
||||
- miniak
|
||||
- nitsakh
|
||||
- nornagon
|
||||
- zcbenz
|
||||
|
||||
25
.github/stale.yml
vendored
Normal file
25
.github/stale.yml
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
# Number of days of inactivity before an issue becomes stale
|
||||
daysUntilStale: 45
|
||||
# Number of days of inactivity before a stale issue is closed
|
||||
daysUntilClose: 7
|
||||
# Issues with these labels will never be considered stale
|
||||
exemptLabels:
|
||||
- fixme/bug
|
||||
- fixme/crash
|
||||
- fixme/regression
|
||||
- fixme/security
|
||||
- blocked
|
||||
- blocking-stable
|
||||
- needs-review
|
||||
# Label to use when marking an issue as stale
|
||||
staleLabel: stale
|
||||
# Comment to post when marking an issue as stale. Set to `false` to disable
|
||||
markComment: >
|
||||
This issue has been automatically marked as stale because it has not had
|
||||
recent activity and is not currently prioritized. It will be closed
|
||||
in a week if no further activity occurs :)
|
||||
|
||||
# Comment to post when closing a stale issue. Set to `false` to disable
|
||||
closeComment: >
|
||||
If you still think this issue is relevant, please ping a maintainer or
|
||||
leave a comment!
|
||||
6
.gitignore
vendored
6
.gitignore
vendored
@@ -58,11 +58,7 @@ spec/.hash
|
||||
.eslintcache
|
||||
|
||||
# Generated native addon files
|
||||
/spec-main/fixtures/native-addon/echo/build/
|
||||
/spec/fixtures/native-addon/echo/build/
|
||||
|
||||
# If someone runs tsc this is where stuff will end up
|
||||
ts-gen
|
||||
|
||||
# Used to accelerate CI builds
|
||||
.depshash
|
||||
.depshash-target
|
||||
@@ -1,135 +1,46 @@
|
||||
# Code of Conduct
|
||||
# Contributor Covenant Code of Conduct:
|
||||
|
||||
As a member project of the OpenJS Foundation, Electron uses [Contributor Covenant v2.0](https://contributor-covenant.org/version/2/0/code_of_conduct) as their code of conduct. The full text is included [below](#contributor-covenant-code-of-conduct) in English, and translations are available from the Contributor Covenant organisation:
|
||||
## Our Pledge
|
||||
|
||||
- [contributor-covenant.org/translations](https://www.contributor-covenant.org/translations)
|
||||
- [github.com/ContributorCovenant](https://github.com/ContributorCovenant/contributor_covenant/tree/release/content/version/2/0)
|
||||
In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
|
||||
|
||||
## Contributor Covenant Code of Conduct
|
||||
## Our Standards
|
||||
|
||||
### Our Pledge
|
||||
Examples of behavior that contributes to creating a positive environment include:
|
||||
|
||||
We as members, contributors, and leaders pledge to make participation in our
|
||||
community a harassment-free experience for everyone, regardless of age, body
|
||||
size, visible or invisible disability, ethnicity, sex characteristics, gender
|
||||
identity and expression, level of experience, education, socio-economic status,
|
||||
nationality, personal appearance, race, religion, or sexual identity
|
||||
and orientation.
|
||||
* Using welcoming and inclusive language
|
||||
* Being respectful of differing viewpoints and experiences
|
||||
* Gracefully accepting constructive criticism
|
||||
* Focusing on what is best for the community
|
||||
* Showing empathy towards other community members
|
||||
|
||||
We pledge to act and interact in ways that contribute to an open, welcoming,
|
||||
diverse, inclusive, and healthy community.
|
||||
Examples of unacceptable behavior by participants include:
|
||||
|
||||
### Our Standards
|
||||
|
||||
Examples of behavior that contributes to a positive environment for our
|
||||
community include:
|
||||
|
||||
* Demonstrating empathy and kindness toward other people
|
||||
* Being respectful of differing opinions, viewpoints, and experiences
|
||||
* Giving and gracefully accepting constructive feedback
|
||||
* Accepting responsibility and apologizing to those affected by our mistakes,
|
||||
and learning from the experience
|
||||
* Focusing on what is best not just for us as individuals, but for the
|
||||
overall community
|
||||
|
||||
Examples of unacceptable behavior include:
|
||||
|
||||
* The use of sexualized language or imagery, and sexual attention or
|
||||
advances of any kind
|
||||
* Trolling, insulting or derogatory comments, and personal or political attacks
|
||||
* The use of sexualized language or imagery and unwelcome sexual attention or advances
|
||||
* Trolling, insulting/derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or email
|
||||
address, without their explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a
|
||||
professional setting
|
||||
* Publishing others' private information, such as a physical or electronic address, without explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a professional setting
|
||||
|
||||
### Enforcement Responsibilities
|
||||
## Our Responsibilities
|
||||
|
||||
Community leaders are responsible for clarifying and enforcing our standards of
|
||||
acceptable behavior and will take appropriate and fair corrective action in
|
||||
response to any behavior that they deem inappropriate, threatening, offensive,
|
||||
or harmful.
|
||||
Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
|
||||
|
||||
Community leaders have the right and responsibility to remove, edit, or reject
|
||||
comments, commits, code, wiki edits, issues, and other contributions that are
|
||||
not aligned to this Code of Conduct, and will communicate reasons for moderation
|
||||
decisions when appropriate.
|
||||
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
|
||||
|
||||
### Scope
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies within all community spaces, and also applies when
|
||||
an individual is officially representing the community in public spaces.
|
||||
Examples of representing our community include using an official e-mail address,
|
||||
posting via an official social media account, or acting as an appointed
|
||||
representative at an online or offline event.
|
||||
This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
|
||||
|
||||
### Enforcement
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported to the community leaders responsible for enforcement at
|
||||
[coc@electronjs.org](mailto:coc@electronjs.org).
|
||||
All complaints will be reviewed and investigated promptly and fairly.
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at [coc@electronjs.org](mailto:coc@electronjs.org). All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
|
||||
|
||||
All community leaders are obligated to respect the privacy and security of the
|
||||
reporter of any incident.
|
||||
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
|
||||
|
||||
### Enforcement Guidelines
|
||||
## Attribution
|
||||
|
||||
Community leaders will follow these Community Impact Guidelines in determining
|
||||
the consequences for any action they deem in violation of this Code of Conduct:
|
||||
This Code of Conduct is adapted from the [Contributor-Covenant][homepage], version 1.4, available at [https://contributor-covenant.org/version/1/4][version]
|
||||
|
||||
#### 1. Correction
|
||||
|
||||
**Community Impact**: Use of inappropriate language or other behavior deemed
|
||||
unprofessional or unwelcome in the community.
|
||||
|
||||
**Consequence**: A private, written warning from community leaders, providing
|
||||
clarity around the nature of the violation and an explanation of why the
|
||||
behavior was inappropriate. A public apology may be requested.
|
||||
|
||||
#### 2. Warning
|
||||
|
||||
**Community Impact**: A violation through a single incident or series
|
||||
of actions.
|
||||
|
||||
**Consequence**: A warning with consequences for continued behavior. No
|
||||
interaction with the people involved, including unsolicited interaction with
|
||||
those enforcing the Code of Conduct, for a specified period of time. This
|
||||
includes avoiding interactions in community spaces as well as external channels
|
||||
like social media. Violating these terms may lead to a temporary or
|
||||
permanent ban.
|
||||
|
||||
#### 3. Temporary Ban
|
||||
|
||||
**Community Impact**: A serious violation of community standards, including
|
||||
sustained inappropriate behavior.
|
||||
|
||||
**Consequence**: A temporary ban from any sort of interaction or public
|
||||
communication with the community for a specified period of time. No public or
|
||||
private interaction with the people involved, including unsolicited interaction
|
||||
with those enforcing the Code of Conduct, is allowed during this period.
|
||||
Violating these terms may lead to a permanent ban.
|
||||
|
||||
#### 4. Permanent Ban
|
||||
|
||||
**Community Impact**: Demonstrating a pattern of violation of community
|
||||
standards, including sustained inappropriate behavior, harassment of an
|
||||
individual, or aggression toward or disparagement of classes of individuals.
|
||||
|
||||
**Consequence**: A permanent ban from any sort of public interaction within
|
||||
the community.
|
||||
|
||||
### Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
|
||||
version 2.0, available at
|
||||
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
|
||||
|
||||
Community Impact Guidelines were inspired by [Mozilla's code of conduct
|
||||
enforcement ladder](https://github.com/mozilla/diversity).
|
||||
|
||||
[homepage]: https://www.contributor-covenant.org
|
||||
|
||||
For answers to common questions about this code of conduct, see the FAQ at
|
||||
https://www.contributor-covenant.org/faq. Translations are available at
|
||||
https://www.contributor-covenant.org/translations.
|
||||
[homepage]: https://contributor-covenant.org
|
||||
[version]: https://contributor-covenant.org/version/1/4/
|
||||
|
||||
@@ -20,23 +20,13 @@ Issues are created [here](https://github.com/electron/electron/issues/new).
|
||||
* [Triaging a Bug Report](https://electronjs.org/docs/development/issues#triaging-a-bug-report)
|
||||
* [Resolving a Bug Report](https://electronjs.org/docs/development/issues#resolving-a-bug-report)
|
||||
|
||||
### Issue Closure
|
||||
|
||||
Bug reports will be closed if the issue has been inactive and the latest affected version no longer receives support. At the moment, Electron maintains its three latest major versions, with a new major version being released every 12 weeks. (For more information on Electron's release cadence, see [this blog post](https://electronjs.org/blog/12-week-cadence).)
|
||||
|
||||
_If an issue has been closed and you still feel it's relevant, feel free to ping a maintainer or add a comment!_
|
||||
|
||||
### Languages
|
||||
|
||||
We accept issues in *any* language.
|
||||
When an issue is posted in a language besides English, it is acceptable and encouraged to post an English-translated copy as a reply.
|
||||
Anyone may post the translated reply.
|
||||
In most cases, a quick pass through translation software is sufficient.
|
||||
Having the original text _as well as_ the translation can help mitigate translation errors.
|
||||
|
||||
Responses to posted issues may or may not be in the original language.
|
||||
|
||||
**Please note** that using non-English as an attempt to circumvent our [Code of Conduct](https://github.com/electron/electron/blob/master/CODE_OF_CONDUCT.md) will be an immediate, and possibly indefinite, ban from the project.
|
||||
### Issue Maintenance and Closure
|
||||
* If an issue is inactive for 45 days (no activity of any kind), it will be
|
||||
marked for closure with `stale`.
|
||||
* If after this label is applied, no further activity occurs in the next 7 days,
|
||||
the issue will be closed.
|
||||
* If an issue has been closed and you still feel it's relevant, feel free to
|
||||
ping a maintainer or add a comment!
|
||||
|
||||
## [Pull Requests](https://electronjs.org/docs/development/pull-requests)
|
||||
|
||||
@@ -67,4 +57,4 @@ See [Coding Style](https://electronjs.org/docs/development/coding-style) for inf
|
||||
## Further Reading
|
||||
|
||||
For more in-depth guides on developing Electron, see
|
||||
[/docs/development](/docs/development/README.md)
|
||||
[/docs/development](/docs/development/README.md)
|
||||
62
DEPS
62
DEPS
@@ -5,20 +5,14 @@ gclient_gn_args = [
|
||||
'checkout_android_native_support',
|
||||
'checkout_libaom',
|
||||
'checkout_nacl',
|
||||
'checkout_pgo_profiles',
|
||||
'checkout_oculus_sdk',
|
||||
'checkout_openxr',
|
||||
'checkout_google_benchmark',
|
||||
'mac_xcode_version',
|
||||
'checkout_oculus_sdk'
|
||||
]
|
||||
|
||||
vars = {
|
||||
'chromium_version':
|
||||
'85.0.4183.84',
|
||||
'76.0.3809.138',
|
||||
'node_version':
|
||||
'v12.16.3',
|
||||
'nan_version':
|
||||
'2c4ee8a32a299eada3cd6e468bbd0a473bfea96d',
|
||||
'v12.4.0',
|
||||
|
||||
'boto_version': 'f7574aa6cc2c819430c1f05e9a1a1a666ef8169b',
|
||||
'pyyaml_version': '3.12',
|
||||
@@ -31,20 +25,21 @@ vars = {
|
||||
'requests_git': 'https://github.com/kennethreitz',
|
||||
'yaml_git': 'https://github.com/yaml',
|
||||
|
||||
# KEEP IN SYNC WITH utils.js FILE
|
||||
# KEEP IN SYNC WITH spec-runner FILE
|
||||
'yarn_version': '1.15.2',
|
||||
|
||||
# To be able to build clean Chromium from sources.
|
||||
'apply_patches': True,
|
||||
|
||||
# Apply the patches specific to windows on arm64
|
||||
'apply_win_arm64_patches': False,
|
||||
|
||||
# Python interface to Amazon Web Services. Is used for releases only.
|
||||
'checkout_boto': False,
|
||||
|
||||
# To allow in-house builds to checkout those manually.
|
||||
'checkout_chromium': True,
|
||||
'checkout_node': True,
|
||||
'checkout_nan': True,
|
||||
'checkout_pgo_profiles': True,
|
||||
|
||||
# It's only needed to parse the native tests configurations.
|
||||
'checkout_pyyaml': False,
|
||||
@@ -52,11 +47,6 @@ vars = {
|
||||
# Python "requests" module is used for releases only.
|
||||
'checkout_requests': False,
|
||||
|
||||
'mac_xcode_version': 'default',
|
||||
|
||||
# To allow running hooks without parsing the DEPS tree
|
||||
'process_deps': True,
|
||||
|
||||
# It is always needed for normal Electron builds,
|
||||
# but might be impossible for custom in-house builds.
|
||||
'download_external_binaries': True,
|
||||
@@ -67,54 +57,56 @@ vars = {
|
||||
True,
|
||||
'checkout_oculus_sdk':
|
||||
False,
|
||||
'checkout_openxr':
|
||||
False,
|
||||
'build_with_chromium':
|
||||
True,
|
||||
'checkout_android':
|
||||
False,
|
||||
'checkout_android_native_support':
|
||||
False,
|
||||
'checkout_google_benchmark':
|
||||
False,
|
||||
}
|
||||
|
||||
deps = {
|
||||
'src': {
|
||||
'url': (Var("chromium_git")) + '/chromium/src.git@' + (Var("chromium_version")),
|
||||
'condition': 'checkout_chromium and process_deps',
|
||||
},
|
||||
'src/third_party/nan': {
|
||||
'url': (Var("nodejs_git")) + '/nan.git@' + (Var("nan_version")),
|
||||
'condition': 'checkout_nan and process_deps',
|
||||
'condition': 'checkout_chromium',
|
||||
},
|
||||
'src/third_party/electron_node': {
|
||||
'url': (Var("nodejs_git")) + '/node.git@' + (Var("node_version")),
|
||||
'condition': 'checkout_node and process_deps',
|
||||
'condition': 'checkout_node',
|
||||
},
|
||||
'src/electron/vendor/pyyaml': {
|
||||
'url': (Var("yaml_git")) + '/pyyaml.git@' + (Var("pyyaml_version")),
|
||||
'condition': 'checkout_pyyaml and process_deps',
|
||||
'condition': 'checkout_pyyaml',
|
||||
},
|
||||
'src/electron/vendor/boto': {
|
||||
'url': Var('boto_git') + '/boto.git' + '@' + Var('boto_version'),
|
||||
'condition': 'checkout_boto and process_deps',
|
||||
'condition': 'checkout_boto',
|
||||
},
|
||||
'src/electron/vendor/requests': {
|
||||
'url': Var('requests_git') + '/requests.git' + '@' + Var('requests_version'),
|
||||
'condition': 'checkout_requests and process_deps',
|
||||
'condition': 'checkout_requests',
|
||||
},
|
||||
}
|
||||
|
||||
hooks = [
|
||||
{
|
||||
'name': 'patch_chromium',
|
||||
'condition': '(checkout_chromium and apply_patches) and process_deps',
|
||||
'condition': 'checkout_chromium and apply_patches',
|
||||
'pattern': 'src/electron',
|
||||
'action': [
|
||||
'python',
|
||||
'src/electron/script/apply_all_patches.py',
|
||||
'src/electron/patches/config.json',
|
||||
'src/electron/patches/common/config.json',
|
||||
],
|
||||
},
|
||||
{
|
||||
'name': 'patch_chromium',
|
||||
'condition': '(checkout_chromium and apply_patches) and apply_win_arm64_patches',
|
||||
'pattern': 'src/electron',
|
||||
'action': [
|
||||
'python',
|
||||
'src/electron/script/apply_all_patches.py',
|
||||
'src/electron/patches/win_arm64/config.json',
|
||||
],
|
||||
},
|
||||
{
|
||||
@@ -122,7 +114,7 @@ hooks = [
|
||||
'pattern': 'src/electron/script/update-external-binaries.py',
|
||||
'condition': 'download_external_binaries',
|
||||
'action': [
|
||||
'python3',
|
||||
'python',
|
||||
'src/electron/script/update-external-binaries.py',
|
||||
],
|
||||
},
|
||||
@@ -138,7 +130,7 @@ hooks = [
|
||||
{
|
||||
'name': 'setup_boto',
|
||||
'pattern': 'src/electron',
|
||||
'condition': 'checkout_boto and process_deps',
|
||||
'condition': 'checkout_boto',
|
||||
'action': [
|
||||
'python',
|
||||
'-c',
|
||||
@@ -148,7 +140,7 @@ hooks = [
|
||||
{
|
||||
'name': 'setup_requests',
|
||||
'pattern': 'src/electron',
|
||||
'condition': 'checkout_requests and process_deps',
|
||||
'condition': 'checkout_requests',
|
||||
'action': [
|
||||
'python',
|
||||
'-c',
|
||||
|
||||
47
Dockerfile
Normal file
47
Dockerfile
Normal file
@@ -0,0 +1,47 @@
|
||||
FROM ubuntu:18.04
|
||||
|
||||
RUN groupadd --gid 1000 builduser \
|
||||
&& useradd --uid 1000 --gid builduser --shell /bin/bash --create-home builduser
|
||||
|
||||
# Set up TEMP directory
|
||||
ENV TEMP=/tmp
|
||||
RUN chmod a+rwx /tmp
|
||||
|
||||
# Install Linux packages
|
||||
ADD build/install-build-deps.sh /setup/install-build-deps.sh
|
||||
RUN echo ttf-mscorefonts-installer msttcorefonts/accepted-mscorefonts-eula select true | debconf-set-selections
|
||||
RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y \
|
||||
curl \
|
||||
libnotify-bin \
|
||||
locales \
|
||||
lsb-release \
|
||||
nano \
|
||||
python-dbus \
|
||||
python-pip \
|
||||
python-setuptools \
|
||||
sudo \
|
||||
vim-nox \
|
||||
wget \
|
||||
&& /setup/install-build-deps.sh --syms --no-prompt --no-chromeos-fonts --lib32 --arm \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Install Node.js
|
||||
RUN curl -sL https://deb.nodesource.com/setup_10.x | bash - \
|
||||
&& DEBIAN_FRONTEND=noninteractive apt-get install -y nodejs \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# crcmod is required by gsutil, which is used for filling the gclient git cache
|
||||
RUN pip install -U crcmod
|
||||
|
||||
# dbusmock is needed for Electron tests
|
||||
RUN pip install python-dbusmock
|
||||
|
||||
RUN mkdir /tmp/workspace
|
||||
RUN chown builduser:builduser /tmp/workspace
|
||||
|
||||
# Add xvfb init script
|
||||
ADD tools/xvfb-init.sh /etc/init.d/xvfb
|
||||
RUN chmod a+x /etc/init.d/xvfb
|
||||
|
||||
USER builduser
|
||||
WORKDIR /home/builduser
|
||||
61
Dockerfile.arm32v7
Normal file
61
Dockerfile.arm32v7
Normal file
@@ -0,0 +1,61 @@
|
||||
FROM arm32v7/ubuntu:18.04
|
||||
|
||||
RUN groupadd --gid 1000 builduser \
|
||||
&& useradd --uid 1000 --gid builduser --shell /bin/bash --create-home builduser
|
||||
|
||||
# Set up TEMP directory
|
||||
ENV TEMP=/tmp
|
||||
RUN chmod a+rwx /tmp
|
||||
|
||||
RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y \
|
||||
bison \
|
||||
build-essential \
|
||||
clang \
|
||||
curl \
|
||||
gperf \
|
||||
git \
|
||||
libasound2 \
|
||||
libasound2-dev \
|
||||
libcap-dev \
|
||||
libcups2-dev \
|
||||
libdbus-1-dev \
|
||||
libgconf-2-4 \
|
||||
libgconf2-dev \
|
||||
libgnome-keyring-dev \
|
||||
libgtk2.0-0 \
|
||||
libgtk2.0-dev \
|
||||
libgtk-3-0 \
|
||||
libgtk-3-dev \
|
||||
libnotify-bin \
|
||||
libnss3 \
|
||||
libnss3-dev \
|
||||
libxss1 \
|
||||
libxtst-dev \
|
||||
libxtst6 \
|
||||
lsb-release \
|
||||
locales \
|
||||
nano \
|
||||
python-setuptools \
|
||||
python-pip \
|
||||
python-dbusmock \
|
||||
sudo \
|
||||
unzip \
|
||||
wget \
|
||||
xvfb \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Install Node.js
|
||||
RUN curl -sL https://deb.nodesource.com/setup_10.x | bash - \
|
||||
&& DEBIAN_FRONTEND=noninteractive apt-get install -y nodejs \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# crcmod is required by gsutil, which is used for filling the gclient git cache
|
||||
RUN pip install -U crcmod
|
||||
|
||||
ADD tools/xvfb-init.sh /etc/init.d/xvfb
|
||||
RUN chmod a+x /etc/init.d/xvfb
|
||||
|
||||
RUN usermod -aG sudo builduser
|
||||
RUN echo 'builduser ALL=(ALL:ALL) NOPASSWD:ALL' >> /etc/sudoers
|
||||
|
||||
WORKDIR /home/builduser
|
||||
65
Dockerfile.arm64v8
Normal file
65
Dockerfile.arm64v8
Normal file
@@ -0,0 +1,65 @@
|
||||
FROM arm64v8/ubuntu:16.04
|
||||
|
||||
RUN groupadd --gid 1000 builduser \
|
||||
&& useradd --uid 1000 --gid builduser --shell /bin/bash --create-home builduser
|
||||
|
||||
# Set up TEMP directory
|
||||
ENV TEMP=/tmp
|
||||
RUN chmod a+rwx /tmp
|
||||
|
||||
RUN dpkg --add-architecture armhf
|
||||
|
||||
RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y \
|
||||
bison \
|
||||
build-essential \
|
||||
clang \
|
||||
curl \
|
||||
gperf \
|
||||
git \
|
||||
libasound2 \
|
||||
libasound2-dev \
|
||||
libc6:armhf \
|
||||
libcap-dev \
|
||||
libcups2-dev \
|
||||
libdbus-1-dev \
|
||||
libgconf-2-4 \
|
||||
libgconf2-dev \
|
||||
libgnome-keyring-dev \
|
||||
libgtk2.0-0 \
|
||||
libgtk2.0-dev \
|
||||
libgtk-3-0 \
|
||||
libgtk-3-dev \
|
||||
libnotify-bin \
|
||||
libnss3 \
|
||||
libnss3-dev \
|
||||
libstdc++6:armhf \
|
||||
libxss1 \
|
||||
libxtst-dev \
|
||||
libxtst6 \
|
||||
lsb-release \
|
||||
locales \
|
||||
nano \
|
||||
python-setuptools \
|
||||
python-pip \
|
||||
python-dbusmock \
|
||||
sudo \
|
||||
unzip \
|
||||
wget \
|
||||
xvfb \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Install Node.js
|
||||
RUN curl -sL https://deb.nodesource.com/setup_10.x | bash - \
|
||||
&& DEBIAN_FRONTEND=noninteractive apt-get install -y nodejs \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# crcmod is required by gsutil, which is used for filling the gclient git cache
|
||||
RUN pip install -U crcmod
|
||||
|
||||
ADD tools/xvfb-init.sh /etc/init.d/xvfb
|
||||
RUN chmod a+x /etc/init.d/xvfb
|
||||
|
||||
RUN usermod -aG sudo builduser
|
||||
RUN echo 'builduser ALL=(ALL:ALL) NOPASSWD:ALL' >> /etc/sudoers
|
||||
|
||||
WORKDIR /home/builduser
|
||||
@@ -1 +1 @@
|
||||
10.0.0
|
||||
6.0.6
|
||||
2
LICENSE
2
LICENSE
@@ -1,4 +1,4 @@
|
||||
Copyright (c) 2013-2020 GitHub Inc.
|
||||
Copyright (c) 2013-2019 GitHub Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
|
||||
16
README.md
16
README.md
@@ -58,13 +58,13 @@ npm start
|
||||
|
||||
## Resources for learning Electron
|
||||
|
||||
- [electronjs.org/docs](https://electronjs.org/docs) - All of Electron's documentation
|
||||
- [electronjs.org/docs](https://electronjs.org/docs) - all of Electron's documentation
|
||||
- [electron/fiddle](https://github.com/electron/fiddle) - A tool to build, run, and package small Electron experiments
|
||||
- [electron/electron-quick-start](https://github.com/electron/electron-quick-start) - A very basic starter Electron app
|
||||
- [electronjs.org/community#boilerplates](https://electronjs.org/community#boilerplates) - Sample starter apps created by the community
|
||||
- [electron/simple-samples](https://github.com/electron/simple-samples) - Small applications with ideas for taking them further
|
||||
- [electron/electron-api-demos](https://github.com/electron/electron-api-demos) - An Electron app that teaches you how to use Electron
|
||||
- [hokein/electron-sample-apps](https://github.com/hokein/electron-sample-apps) - Small demo apps for the various Electron APIs
|
||||
- [electron/electron-quick-start](https://github.com/electron/electron-quick-start) - a very basic starter Electron app
|
||||
- [electronjs.org/community#boilerplates](https://electronjs.org/community#boilerplates) - sample starter apps created by the community
|
||||
- [electron/simple-samples](https://github.com/electron/simple-samples) - small applications with ideas for taking them further
|
||||
- [electron/electron-api-demos](https://github.com/electron/electron-api-demos) - an Electron app that teaches you how to use Electron
|
||||
- [hokein/electron-sample-apps](https://github.com/hokein/electron-sample-apps) - small demo apps for the various Electron APIs
|
||||
|
||||
## Programmatic usage
|
||||
|
||||
@@ -91,10 +91,6 @@ const child = proc.spawn(electron)
|
||||
|
||||
Find documentation translations in [electron/i18n](https://github.com/electron/i18n).
|
||||
|
||||
## Contributing
|
||||
|
||||
If you are interested in reporting/fixing issues and contributing directly to the code base, please see [CONTRIBUTING.md](CONTRIBUTING.md) for more information on what we're looking for and how to get started.
|
||||
|
||||
## Community
|
||||
|
||||
Info on reporting bugs, getting help, finding third-party tools and sample apps,
|
||||
|
||||
134
appveyor.yml
134
appveyor.yml
@@ -1,5 +1,5 @@
|
||||
# The config expects the following environment variables to be set:
|
||||
# - "GN_CONFIG" Build type. One of {'testing', 'release'}.
|
||||
# - "GN_CONFIG" Build type. One of {'debug', 'testing', 'release'}.
|
||||
# - "GN_EXTRA_ARGS" Additional gn arguments for a build config,
|
||||
# e.g. 'target_cpu="x86"' to build for a 32bit platform.
|
||||
# https://gn.googlesource.com/gn/+/master/docs/reference.md#target_cpu
|
||||
@@ -23,52 +23,28 @@
|
||||
# https://www.appveyor.com/docs/build-configuration/#secure-variables
|
||||
# https://www.appveyor.com/docs/build-configuration/#custom-environment-variables
|
||||
|
||||
# Uncomment these lines to enable RDP
|
||||
#on_finish:
|
||||
# - ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
|
||||
|
||||
version: 1.0.{build}
|
||||
build_cloud: electron-16-core
|
||||
image: vs2019bt-16.6.2
|
||||
build_cloud: libcc-20
|
||||
image: libcc-20-vs2017-15.9
|
||||
environment:
|
||||
GIT_CACHE_PATH: C:\Users\electron\libcc_cache
|
||||
ELECTRON_OUT_DIR: Default
|
||||
ELECTRON_ENABLE_STACK_DUMPING: 1
|
||||
MOCHA_REPORTER: mocha-multi-reporters
|
||||
MOCHA_MULTI_REPORTERS: mocha-appveyor-reporter, tap
|
||||
notifications:
|
||||
- provider: Webhook
|
||||
url: https://electron-mission-control.herokuapp.com/rest/appveyor-hook
|
||||
method: POST
|
||||
headers:
|
||||
x-mission-control-secret:
|
||||
secure: 90BLVPcqhJPG7d24v0q/RRray6W3wDQ8uVQlQjOHaBWkw1i8FoA1lsjr2C/v1dVok+tS2Pi6KxDctPUkwIb4T27u4RhvmcPzQhVpfwVJAG9oNtq+yKN7vzHfg7k/pojEzVdJpQLzeJGcSrZu7VY39Q==
|
||||
on_build_success: false
|
||||
on_build_failure: true
|
||||
on_build_status_changed: false
|
||||
build_script:
|
||||
- ps: >-
|
||||
if(($env:APPVEYOR_PULL_REQUEST_HEAD_REPO_NAME -split "/")[0] -eq ($env:APPVEYOR_REPO_NAME -split "/")[0]) {
|
||||
Write-warning "Skipping PR build for branch"; Exit-AppveyorBuild
|
||||
} else {
|
||||
node script/yarn.js install --frozen-lockfile
|
||||
|
||||
if ($(node script/doc-only-change.js --prNumber=$env:APPVEYOR_PULL_REQUEST_NUMBER --prBranch=$env:APPVEYOR_REPO_BRANCH;$LASTEXITCODE -eq 0)) {
|
||||
Write-warning "Skipping build for doc only change"; Exit-AppveyorBuild
|
||||
}
|
||||
}
|
||||
- echo "Building $env:GN_CONFIG build"
|
||||
- git config --global core.longpaths true
|
||||
- cd ..
|
||||
- mkdir src
|
||||
- ps: if (Test-Path src\electron) { Remove-Item src\electron -Recurse }
|
||||
- ps: Move-Item $env:APPVEYOR_BUILD_FOLDER -Destination src\electron
|
||||
- ps: $env:CHROMIUM_BUILDTOOLS_PATH="$pwd\src\buildtools"
|
||||
- ps: $env:SCCACHE_PATH="$pwd\src\electron\external_binaries\sccache.exe"
|
||||
- ps: >-
|
||||
if ($env:GN_CONFIG -eq 'release') {
|
||||
$env:GCLIENT_EXTRA_ARGS="$env:GCLIENT_EXTRA_ARGS --custom-var=checkout_boto=True --custom-var=checkout_requests=True"
|
||||
} else {
|
||||
$env:NINJA_STATUS="[%r processes, %f/%t @ %o/s : %es] "
|
||||
}
|
||||
- >-
|
||||
gclient config
|
||||
@@ -76,101 +52,27 @@ build_script:
|
||||
--unmanaged
|
||||
%GCLIENT_EXTRA_ARGS%
|
||||
"https://github.com/electron/electron"
|
||||
- ps: >-
|
||||
if ($env:GN_CONFIG -eq 'release') {
|
||||
$env:RUN_GCLIENT_SYNC="true"
|
||||
} else {
|
||||
cd src\electron
|
||||
node script\generate-deps-hash.js
|
||||
$depshash = Get-Content .\.depshash -Raw
|
||||
$zipfile = "Z:\$depshash.7z"
|
||||
cd ..\..
|
||||
if (Test-Path -Path $zipfile) {
|
||||
# file exists, unzip and then gclient sync
|
||||
7z x -y $zipfile -mmt=30 -aoa
|
||||
if (-not (Test-Path -Path "src\buildtools")) {
|
||||
# the zip file must be corrupt - resync
|
||||
$env:RUN_GCLIENT_SYNC="true"
|
||||
if ($env:TARGET_ARCH -ne 'ia32') {
|
||||
# only save on x64/woa to avoid contention saving
|
||||
$env:SAVE_GCLIENT_SRC="true"
|
||||
}
|
||||
} else {
|
||||
# update external binaries
|
||||
python src/electron/script/update-external-binaries.py
|
||||
}
|
||||
} else {
|
||||
# file does not exist, gclient sync, then zip
|
||||
$env:RUN_GCLIENT_SYNC="true"
|
||||
if ($env:TARGET_ARCH -ne 'ia32') {
|
||||
# only save on x64/woa to avoid contention saving
|
||||
$env:SAVE_GCLIENT_SRC="true"
|
||||
}
|
||||
}
|
||||
}
|
||||
- if "%RUN_GCLIENT_SYNC%"=="true" ( gclient sync --with_branch_heads --with_tags --ignore_locks)
|
||||
- ps: >-
|
||||
if ($env:SAVE_GCLIENT_SRC -eq 'true') {
|
||||
# archive current source for future use
|
||||
# only run on x64/woa to avoid contention saving
|
||||
if ($(7z a $zipfile src -xr!android_webview -xr!electron -xr'!*\.git' -xr!third_party\WebKit\LayoutTests! -xr!third_party\blink\web_tests -xr!third_party\blink\perf_tests -slp -t7z -mmt=30;$LASTEXITCODE -ne 0)) {
|
||||
Write-warning "Could not save source to shared drive; continuing anyway"
|
||||
}
|
||||
# build time generation of file gen/angle/commit.h depends on
|
||||
# third_party/angle/.git/HEAD.
|
||||
# https://chromium-review.googlesource.com/c/angle/angle/+/2074924
|
||||
if ($(7z a $zipfile src\third_party\angle\.git\HEAD;$LASTEXITCODE -ne 0)) {
|
||||
Write-warning "Failed to add third_party\angle\.git\HEAD; continuing anyway"
|
||||
}
|
||||
}
|
||||
- ps: >-
|
||||
if ($env:GN_CONFIG -ne 'release') {
|
||||
if (Test-Path 'env:RAW_GOMA_AUTH') {
|
||||
$env:GOMA_OAUTH2_CONFIG_FILE = "$pwd\.goma_oauth2_config"
|
||||
$env:RAW_GOMA_AUTH | Set-Content $env:GOMA_OAUTH2_CONFIG_FILE
|
||||
}
|
||||
git clone https://github.com/electron/build-tools.git
|
||||
cd build-tools
|
||||
npm install
|
||||
mkdir third_party
|
||||
node -e "require('./src/utils/goma.js').downloadAndPrepare()"
|
||||
$env:GN_GOMA_FILE = node -e "console.log(require('./src/utils/goma.js').gnFilePath)"
|
||||
$env:LOCAL_GOMA_DIR = node -e "console.log(require('./src/utils/goma.js').dir)"
|
||||
cd ..
|
||||
.\src\electron\script\start-goma.ps1 -gomaDir $env:LOCAL_GOMA_DIR
|
||||
}
|
||||
- gclient sync --with_branch_heads --with_tags --reset
|
||||
- cd src
|
||||
- set BUILD_CONFIG_PATH=//electron/build/args/%GN_CONFIG%.gn
|
||||
- if DEFINED GN_GOMA_FILE (gn gen out/Default "--args=import(\"%BUILD_CONFIG_PATH%\") import(\"%GN_GOMA_FILE%\") %GN_EXTRA_ARGS% ") else (gn gen out/Default "--args=import(\"%BUILD_CONFIG_PATH%\") %GN_EXTRA_ARGS% cc_wrapper=\"%SCCACHE_PATH%\"")
|
||||
- ps: $env:BUILD_CONFIG_PATH="//electron/build/args/%GN_CONFIG%.gn"
|
||||
- gn gen out/Default "--args=import(\"%BUILD_CONFIG_PATH%\") %GN_EXTRA_ARGS%"
|
||||
- gn check out/Default //electron:electron_lib
|
||||
- gn check out/Default //electron:electron_app
|
||||
- gn check out/Default //electron:manifests
|
||||
- gn check out/Default //electron/shell/common/api:mojo
|
||||
- if DEFINED GN_GOMA_FILE (ninja -j 300 -C out/Default electron:electron_app) else (ninja -C out/Default electron:electron_app)
|
||||
- if "%GN_CONFIG%"=="testing" ( python C:\depot_tools\post_build_ninja_summary.py -C out\Default )
|
||||
- gn check out/Default //electron/atom/common/api:mojo
|
||||
- ninja -C out/Default electron:electron_app
|
||||
- gn gen out/ffmpeg "--args=import(\"//electron/build/args/ffmpeg.gn\") %GN_EXTRA_ARGS%"
|
||||
- ninja -C out/ffmpeg electron:electron_ffmpeg_zip
|
||||
- ninja -C out/Default electron:electron_dist_zip
|
||||
- ninja -C out/Default shell_browser_ui_unittests
|
||||
- gn desc out/Default v8:run_mksnapshot_default args > out/Default/mksnapshot_args
|
||||
- ninja -C out/Default electron:electron_mksnapshot_zip
|
||||
- cd out\Default
|
||||
- 7z a mksnapshot.zip mksnapshot_args gen\v8\embedded.S
|
||||
- cd ..\..
|
||||
- ninja -C out/Default electron:hunspell_dictionaries_zip
|
||||
- ninja -C out/Default electron:electron_chromedriver_zip
|
||||
- ninja -C out/Default third_party/electron_node:headers
|
||||
- if "%GN_CONFIG%"=="testing" ( python %LOCAL_GOMA_DIR%\goma_ctl.py stat )
|
||||
- python electron/build/profile_toolchain.py --output-json=out/Default/windows_toolchain_profile.json
|
||||
- appveyor PushArtifact out/Default/windows_toolchain_profile.json
|
||||
- appveyor PushArtifact out/Default/dist.zip
|
||||
- appveyor PushArtifact out/Default/shell_browser_ui_unittests.exe
|
||||
- appveyor PushArtifact out/Default/chromedriver.zip
|
||||
- appveyor PushArtifact out/ffmpeg/ffmpeg.zip
|
||||
- 7z a node_headers.zip out\Default\gen\node_headers
|
||||
- appveyor PushArtifact node_headers.zip
|
||||
- appveyor PushArtifact out/Default/mksnapshot.zip
|
||||
- appveyor PushArtifact out/Default/hunspell_dictionaries.zip
|
||||
- appveyor PushArtifact out/Default/electron.lib
|
||||
- ps: >-
|
||||
if ($env:GN_CONFIG -eq 'release') {
|
||||
@@ -181,12 +83,7 @@ build_script:
|
||||
- ps: >-
|
||||
if ($env:GN_CONFIG -eq 'release') {
|
||||
python electron\script\zip-symbols.py
|
||||
appveyor-retry appveyor PushArtifact out/Default/symbols.zip
|
||||
} else {
|
||||
# It's useful to have pdb files when debugging testing builds that are
|
||||
# built on CI.
|
||||
7z a pdb.zip out\Default\*.pdb
|
||||
appveyor-retry appveyor PushArtifact pdb.zip
|
||||
appveyor PushArtifact out/Default/symbols.zip
|
||||
}
|
||||
- python electron/script/zip_manifests/check-zip-manifest.py out/Default/dist.zip electron/script/zip_manifests/dist_zip.win.%TARGET_ARCH%.manifest
|
||||
test_script:
|
||||
@@ -204,25 +101,24 @@ test_script:
|
||||
echo "Skipping tests for $env:GN_CONFIG build"
|
||||
}
|
||||
- cd electron
|
||||
- if "%RUN_TESTS%"=="true" ( echo Running test suite & node script/yarn test -- --trace-uncaught --enable-logging)
|
||||
- if "%RUN_TESTS%"=="true" ( echo Running test suite & node script/yarn test -- --ci --enable-logging)
|
||||
- cd ..
|
||||
- if "%RUN_TESTS%"=="true" ( echo Verifying non proprietary ffmpeg & python electron\script\verify-ffmpeg.py --build-dir out\Default --source-root %cd% --ffmpeg-path out\ffmpeg )
|
||||
- echo "About to verify mksnapshot"
|
||||
- if "%RUN_TESTS%"=="true" ( echo Verifying mksnapshot & python electron\script\verify-mksnapshot.py --build-dir out\Default --source-root %cd% )
|
||||
- echo "Done verifying mksnapshot"
|
||||
- if "%RUN_TESTS%"=="true" ( echo Verifying chromedriver & python electron\script\verify-chromedriver.py --build-dir out\Default --source-root %cd% )
|
||||
- echo "Done verifying chromedriver"
|
||||
deploy_script:
|
||||
- cd electron
|
||||
- ps: >-
|
||||
if (Test-Path Env:\ELECTRON_RELEASE) {
|
||||
if (Test-Path Env:\UPLOAD_TO_S3) {
|
||||
Write-Output "Uploading Electron release distribution to s3"
|
||||
& python script\release\uploaders\upload.py --upload_to_s3
|
||||
& python script\upload.py --upload_to_s3
|
||||
} else {
|
||||
Write-Output "Uploading Electron release distribution to github releases"
|
||||
& python script\release\uploaders\upload.py
|
||||
& python script\upload.py
|
||||
}
|
||||
} elseif (Test-Path Env:\TEST_WOA) {
|
||||
node script/release/ci-release-build.js --job=electron-woa-testing --ci=VSTS --armTest --appveyorJobId=$env:APPVEYOR_JOB_ID $env:APPVEYOR_REPO_BRANCH
|
||||
# node script/release/ci-release-build.js --job=electron-woa-testing --ci=VSTS --armTest --appveyorJobId=$env:APPVEYOR_JOB_ID $env:APPVEYOR_REPO_BRANCH
|
||||
echo "Eventually run tests on WOA hardware at this step"
|
||||
}
|
||||
|
||||
@@ -2,30 +2,27 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "shell/app/electron_content_client.h"
|
||||
#include "atom/app/atom_content_client.h"
|
||||
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "atom/common/options_switches.h"
|
||||
#include "base/command_line.h"
|
||||
#include "base/files/file_util.h"
|
||||
#include "base/path_service.h"
|
||||
#include "base/strings/string_split.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "content/public/common/content_constants.h"
|
||||
#include "content/public/common/content_switches.h"
|
||||
#include "content/public/common/pepper_plugin_info.h"
|
||||
#include "electron/buildflags/buildflags.h"
|
||||
#include "extensions/common/constants.h"
|
||||
#include "ppapi/buildflags/buildflags.h"
|
||||
#include "shell/common/electron_paths.h"
|
||||
#include "shell/common/options_switches.h"
|
||||
#include "ppapi/shared_impl/ppapi_permissions.h"
|
||||
#include "ui/base/l10n/l10n_util.h"
|
||||
#include "ui/base/resource/resource_bundle.h"
|
||||
#include "url/url_constants.h"
|
||||
// In SHARED_INTERMEDIATE_DIR.
|
||||
#include "widevine_cdm_version.h" // NOLINT(build/include_directory)
|
||||
#include "widevine_cdm_version.h" // NOLINT(build/include)
|
||||
|
||||
#if defined(WIDEVINE_CDM_AVAILABLE)
|
||||
#include "base/native_library.h"
|
||||
@@ -34,18 +31,11 @@
|
||||
#endif // defined(WIDEVINE_CDM_AVAILABLE)
|
||||
|
||||
#if BUILDFLAG(ENABLE_PDF_VIEWER)
|
||||
#include "pdf/pdf.h" // nogncheck
|
||||
#include "pdf/pdf_ppapi.h" // nogncheck
|
||||
#include "shell/common/electron_constants.h"
|
||||
#include "atom/common/atom_constants.h"
|
||||
#include "pdf/pdf.h"
|
||||
#endif // BUILDFLAG(ENABLE_PDF_VIEWER)
|
||||
|
||||
#if BUILDFLAG(ENABLE_PLUGINS)
|
||||
#include "content/public/browser/plugin_service.h"
|
||||
#include "content/public/common/pepper_plugin_info.h"
|
||||
#include "ppapi/shared_impl/ppapi_permissions.h"
|
||||
#endif // BUILDFLAG(ENABLE_PLUGINS)
|
||||
|
||||
namespace electron {
|
||||
namespace atom {
|
||||
|
||||
namespace {
|
||||
|
||||
@@ -109,27 +99,29 @@ content::PepperPluginInfo CreatePepperFlashInfo(const base::FilePath& path,
|
||||
std::vector<std::string> flash_version_numbers = base::SplitString(
|
||||
version, ".", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
|
||||
if (flash_version_numbers.empty())
|
||||
flash_version_numbers.emplace_back("11");
|
||||
flash_version_numbers.push_back("11");
|
||||
// |SplitString()| puts in an empty string given an empty string. :(
|
||||
else if (flash_version_numbers[0].empty())
|
||||
flash_version_numbers[0] = "11";
|
||||
if (flash_version_numbers.size() < 2)
|
||||
flash_version_numbers.emplace_back("2");
|
||||
flash_version_numbers.push_back("2");
|
||||
if (flash_version_numbers.size() < 3)
|
||||
flash_version_numbers.emplace_back("999");
|
||||
flash_version_numbers.push_back("999");
|
||||
if (flash_version_numbers.size() < 4)
|
||||
flash_version_numbers.emplace_back("999");
|
||||
flash_version_numbers.push_back("999");
|
||||
// E.g., "Shockwave Flash 10.2 r154":
|
||||
plugin.description = plugin.name + " " + flash_version_numbers[0] + "." +
|
||||
flash_version_numbers[1] + " r" +
|
||||
flash_version_numbers[2];
|
||||
plugin.version = base::JoinString(flash_version_numbers, ".");
|
||||
plugin.mime_types.emplace_back(content::kFlashPluginSwfMimeType,
|
||||
content::kFlashPluginSwfExtension,
|
||||
content::kFlashPluginSwfDescription);
|
||||
plugin.mime_types.emplace_back(content::kFlashPluginSplMimeType,
|
||||
content::kFlashPluginSplExtension,
|
||||
content::kFlashPluginSplDescription);
|
||||
content::WebPluginMimeType swf_mime_type(content::kFlashPluginSwfMimeType,
|
||||
content::kFlashPluginSwfExtension,
|
||||
content::kFlashPluginSwfDescription);
|
||||
plugin.mime_types.push_back(swf_mime_type);
|
||||
content::WebPluginMimeType spl_mime_type(content::kFlashPluginSplMimeType,
|
||||
content::kFlashPluginSplExtension,
|
||||
content::kFlashPluginSplDescription);
|
||||
plugin.mime_types.push_back(spl_mime_type);
|
||||
|
||||
return plugin;
|
||||
}
|
||||
@@ -149,7 +141,6 @@ void AddPepperFlashFromCommandLine(
|
||||
}
|
||||
#endif // BUILDFLAG(ENABLE_PEPPER_FLASH)
|
||||
|
||||
#if BUILDFLAG(ENABLE_PLUGINS)
|
||||
void ComputeBuiltInPlugins(std::vector<content::PepperPluginInfo>* plugins) {
|
||||
#if BUILDFLAG(ENABLE_PDF_VIEWER)
|
||||
content::PepperPluginInfo pdf_info;
|
||||
@@ -157,8 +148,7 @@ void ComputeBuiltInPlugins(std::vector<content::PepperPluginInfo>* plugins) {
|
||||
pdf_info.is_out_of_process = true;
|
||||
pdf_info.name = "Chromium PDF Viewer";
|
||||
pdf_info.description = "Portable Document Format";
|
||||
// This isn't a real file path; it's just used as a unique identifier.
|
||||
pdf_info.path = base::FilePath(kPdfPluginPath);
|
||||
pdf_info.path = base::FilePath::FromUTF8Unsafe(kPdfPluginPath);
|
||||
content::WebPluginMimeType pdf_mime_type(kPdfPluginMimeType, "pdf",
|
||||
"Portable Document Format");
|
||||
pdf_info.mime_types.push_back(pdf_mime_type);
|
||||
@@ -167,26 +157,10 @@ void ComputeBuiltInPlugins(std::vector<content::PepperPluginInfo>* plugins) {
|
||||
chrome_pdf::PPP_InitializeModule;
|
||||
pdf_info.internal_entry_points.shutdown_module =
|
||||
chrome_pdf::PPP_ShutdownModule;
|
||||
pdf_info.permissions = ppapi::PERMISSION_PDF | ppapi::PERMISSION_DEV;
|
||||
pdf_info.permissions = ppapi::PERMISSION_PRIVATE | ppapi::PERMISSION_DEV;
|
||||
plugins->push_back(pdf_info);
|
||||
|
||||
// NB. in Chrome, this plugin isn't registered until the PDF extension is
|
||||
// loaded. However, in Electron, we load the PDF extension unconditionally
|
||||
// when it is enabled in the build, so we're OK to load the plugin eagerly
|
||||
// here.
|
||||
content::WebPluginInfo info;
|
||||
info.type = content::WebPluginInfo::PLUGIN_TYPE_BROWSER_PLUGIN;
|
||||
info.name = base::UTF8ToUTF16("Chromium PDF Viewer");
|
||||
// This isn't a real file path; it's just used as a unique identifier.
|
||||
info.path = base::FilePath::FromUTF8Unsafe(extension_misc::kPdfExtensionId);
|
||||
info.background_color = content::WebPluginInfo::kDefaultBackgroundColor;
|
||||
info.mime_types.emplace_back("application/pdf", "pdf",
|
||||
"Portable Document Format");
|
||||
content::PluginService::GetInstance()->RefreshPlugins();
|
||||
content::PluginService::GetInstance()->RegisterInternalPlugin(info, true);
|
||||
#endif // BUILDFLAG(ENABLE_PDF_VIEWER)
|
||||
}
|
||||
#endif // BUILDFLAG(ENABLE_PLUGINS)
|
||||
|
||||
void AppendDelimitedSwitchToVector(const base::StringPiece cmd_switch,
|
||||
std::vector<std::string>* append_me) {
|
||||
@@ -205,71 +179,58 @@ void AppendDelimitedSwitchToVector(const base::StringPiece cmd_switch,
|
||||
|
||||
} // namespace
|
||||
|
||||
ElectronContentClient::ElectronContentClient() = default;
|
||||
AtomContentClient::AtomContentClient() {}
|
||||
|
||||
ElectronContentClient::~ElectronContentClient() = default;
|
||||
AtomContentClient::~AtomContentClient() {}
|
||||
|
||||
base::string16 ElectronContentClient::GetLocalizedString(int message_id) {
|
||||
base::string16 AtomContentClient::GetLocalizedString(int message_id) const {
|
||||
return l10n_util::GetStringUTF16(message_id);
|
||||
}
|
||||
|
||||
base::StringPiece ElectronContentClient::GetDataResource(
|
||||
base::StringPiece AtomContentClient::GetDataResource(
|
||||
int resource_id,
|
||||
ui::ScaleFactor scale_factor) {
|
||||
ui::ScaleFactor scale_factor) const {
|
||||
return ui::ResourceBundle::GetSharedInstance().GetRawDataResourceForScale(
|
||||
resource_id, scale_factor);
|
||||
}
|
||||
|
||||
gfx::Image& ElectronContentClient::GetNativeImageNamed(int resource_id) {
|
||||
gfx::Image& AtomContentClient::GetNativeImageNamed(int resource_id) const {
|
||||
return ui::ResourceBundle::GetSharedInstance().GetNativeImageNamed(
|
||||
resource_id);
|
||||
}
|
||||
|
||||
base::RefCountedMemory* ElectronContentClient::GetDataResourceBytes(
|
||||
int resource_id) {
|
||||
base::RefCountedMemory* AtomContentClient::GetDataResourceBytes(
|
||||
int resource_id) const {
|
||||
return ui::ResourceBundle::GetSharedInstance().LoadDataResourceBytes(
|
||||
resource_id);
|
||||
}
|
||||
|
||||
void ElectronContentClient::AddAdditionalSchemes(Schemes* schemes) {
|
||||
auto* command_line = base::CommandLine::ForCurrentProcess();
|
||||
std::string process_type =
|
||||
command_line->GetSwitchValueASCII(::switches::kProcessType);
|
||||
// Browser Process registration happens in
|
||||
// `api::Protocol::RegisterSchemesAsPrivileged`
|
||||
//
|
||||
// Renderer Process registration happens in `RendererClientBase`
|
||||
//
|
||||
// We use this for registration to network utility process
|
||||
if (process_type == ::switches::kUtilityProcess) {
|
||||
AppendDelimitedSwitchToVector(switches::kServiceWorkerSchemes,
|
||||
&schemes->service_worker_schemes);
|
||||
AppendDelimitedSwitchToVector(switches::kStandardSchemes,
|
||||
&schemes->standard_schemes);
|
||||
AppendDelimitedSwitchToVector(switches::kSecureSchemes,
|
||||
&schemes->secure_schemes);
|
||||
AppendDelimitedSwitchToVector(switches::kBypassCSPSchemes,
|
||||
&schemes->csp_bypassing_schemes);
|
||||
AppendDelimitedSwitchToVector(switches::kCORSSchemes,
|
||||
&schemes->cors_enabled_schemes);
|
||||
}
|
||||
void AtomContentClient::AddAdditionalSchemes(Schemes* schemes) {
|
||||
AppendDelimitedSwitchToVector(switches::kServiceWorkerSchemes,
|
||||
&schemes->service_worker_schemes);
|
||||
AppendDelimitedSwitchToVector(switches::kStandardSchemes,
|
||||
&schemes->standard_schemes);
|
||||
AppendDelimitedSwitchToVector(switches::kSecureSchemes,
|
||||
&schemes->secure_schemes);
|
||||
AppendDelimitedSwitchToVector(switches::kBypassCSPSchemes,
|
||||
&schemes->csp_bypassing_schemes);
|
||||
AppendDelimitedSwitchToVector(switches::kCORSSchemes,
|
||||
&schemes->cors_enabled_schemes);
|
||||
|
||||
schemes->service_worker_schemes.emplace_back(url::kFileScheme);
|
||||
schemes->standard_schemes.emplace_back(extensions::kExtensionScheme);
|
||||
schemes->service_worker_schemes.push_back(url::kFileScheme);
|
||||
schemes->standard_schemes.push_back("chrome-extension");
|
||||
}
|
||||
|
||||
void ElectronContentClient::AddPepperPlugins(
|
||||
void AtomContentClient::AddPepperPlugins(
|
||||
std::vector<content::PepperPluginInfo>* plugins) {
|
||||
#if BUILDFLAG(ENABLE_PEPPER_FLASH)
|
||||
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
|
||||
AddPepperFlashFromCommandLine(command_line, plugins);
|
||||
#endif // BUILDFLAG(ENABLE_PEPPER_FLASH)
|
||||
#if BUILDFLAG(ENABLE_PLUGINS)
|
||||
ComputeBuiltInPlugins(plugins);
|
||||
#endif // BUILDFLAG(ENABLE_PLUGINS)
|
||||
}
|
||||
|
||||
void ElectronContentClient::AddContentDecryptionModules(
|
||||
void AtomContentClient::AddContentDecryptionModules(
|
||||
std::vector<content::CdmInfo>* cdms,
|
||||
std::vector<media::CdmHostFilePath>* cdm_host_file_paths) {
|
||||
if (cdms) {
|
||||
@@ -302,4 +263,8 @@ void ElectronContentClient::AddContentDecryptionModules(
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace electron
|
||||
bool AtomContentClient::IsDataResourceGzipped(int resource_id) const {
|
||||
return ui::ResourceBundle::GetSharedInstance().IsGzipped(resource_id);
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
@@ -2,40 +2,41 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef SHELL_APP_ELECTRON_CONTENT_CLIENT_H_
|
||||
#define SHELL_APP_ELECTRON_CONTENT_CLIENT_H_
|
||||
#ifndef ATOM_APP_ATOM_CONTENT_CLIENT_H_
|
||||
#define ATOM_APP_ATOM_CONTENT_CLIENT_H_
|
||||
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "base/files/file_path.h"
|
||||
#include "content/public/common/content_client.h"
|
||||
|
||||
namespace electron {
|
||||
namespace atom {
|
||||
|
||||
class ElectronContentClient : public content::ContentClient {
|
||||
class AtomContentClient : public content::ContentClient {
|
||||
public:
|
||||
ElectronContentClient();
|
||||
~ElectronContentClient() override;
|
||||
AtomContentClient();
|
||||
~AtomContentClient() override;
|
||||
|
||||
protected:
|
||||
// content::ContentClient:
|
||||
base::string16 GetLocalizedString(int message_id) override;
|
||||
base::StringPiece GetDataResource(int resource_id, ui::ScaleFactor) override;
|
||||
gfx::Image& GetNativeImageNamed(int resource_id) override;
|
||||
base::RefCountedMemory* GetDataResourceBytes(int resource_id) override;
|
||||
base::string16 GetLocalizedString(int message_id) const override;
|
||||
base::StringPiece GetDataResource(int resource_id,
|
||||
ui::ScaleFactor) const override;
|
||||
gfx::Image& GetNativeImageNamed(int resource_id) const override;
|
||||
base::RefCountedMemory* GetDataResourceBytes(int resource_id) const override;
|
||||
void AddAdditionalSchemes(Schemes* schemes) override;
|
||||
void AddPepperPlugins(
|
||||
std::vector<content::PepperPluginInfo>* plugins) override;
|
||||
void AddContentDecryptionModules(
|
||||
std::vector<content::CdmInfo>* cdms,
|
||||
std::vector<media::CdmHostFilePath>* cdm_host_file_paths) override;
|
||||
bool IsDataResourceGzipped(int resource_id) const override;
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(ElectronContentClient);
|
||||
DISALLOW_COPY_AND_ASSIGN(AtomContentClient);
|
||||
};
|
||||
|
||||
} // namespace electron
|
||||
} // namespace atom
|
||||
|
||||
#endif // SHELL_APP_ELECTRON_CONTENT_CLIENT_H_
|
||||
#endif // ATOM_APP_ATOM_CONTENT_CLIENT_H_
|
||||
@@ -2,22 +2,22 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef SHELL_APP_ELECTRON_LIBRARY_MAIN_H_
|
||||
#define SHELL_APP_ELECTRON_LIBRARY_MAIN_H_
|
||||
#ifndef ATOM_APP_ATOM_LIBRARY_MAIN_H_
|
||||
#define ATOM_APP_ATOM_LIBRARY_MAIN_H_
|
||||
|
||||
#include "build/build_config.h"
|
||||
#include "electron/buildflags/buildflags.h"
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
extern "C" {
|
||||
__attribute__((visibility("default"))) int ElectronMain(int argc, char* argv[]);
|
||||
__attribute__((visibility("default"))) int AtomMain(int argc, char* argv[]);
|
||||
|
||||
#if BUILDFLAG(ENABLE_RUN_AS_NODE)
|
||||
__attribute__((visibility("default"))) int ElectronInitializeICUandStartNode(
|
||||
__attribute__((visibility("default"))) int AtomInitializeICUandStartNode(
|
||||
int argc,
|
||||
char* argv[]);
|
||||
#endif
|
||||
}
|
||||
#endif // OS_MACOSX
|
||||
|
||||
#endif // SHELL_APP_ELECTRON_LIBRARY_MAIN_H_
|
||||
#endif // ATOM_APP_ATOM_LIBRARY_MAIN_H_
|
||||
@@ -2,37 +2,37 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "shell/app/electron_library_main.h"
|
||||
#include "atom/app/atom_library_main.h"
|
||||
|
||||
#include "atom/app/atom_main_delegate.h"
|
||||
#include "atom/app/node_main.h"
|
||||
#include "atom/common/atom_command_line.h"
|
||||
#include "atom/common/mac/main_application_bundle.h"
|
||||
#include "base/at_exit.h"
|
||||
#include "base/i18n/icu_util.h"
|
||||
#include "base/mac/bundle_locations.h"
|
||||
#include "base/mac/scoped_nsautorelease_pool.h"
|
||||
#include "content/public/app/content_main.h"
|
||||
#include "shell/app/electron_main_delegate.h"
|
||||
#include "shell/app/node_main.h"
|
||||
#include "shell/common/electron_command_line.h"
|
||||
#include "shell/common/mac/main_application_bundle.h"
|
||||
|
||||
int ElectronMain(int argc, char* argv[]) {
|
||||
electron::ElectronMainDelegate delegate;
|
||||
int AtomMain(int argc, char* argv[]) {
|
||||
atom::AtomMainDelegate delegate;
|
||||
content::ContentMainParams params(&delegate);
|
||||
params.argc = argc;
|
||||
params.argv = const_cast<const char**>(argv);
|
||||
electron::ElectronCommandLine::Init(argc, argv);
|
||||
atom::AtomCommandLine::Init(argc, argv);
|
||||
return content::ContentMain(params);
|
||||
}
|
||||
|
||||
#if BUILDFLAG(ENABLE_RUN_AS_NODE)
|
||||
int ElectronInitializeICUandStartNode(int argc, char* argv[]) {
|
||||
int AtomInitializeICUandStartNode(int argc, char* argv[]) {
|
||||
base::AtExitManager atexit_manager;
|
||||
base::mac::ScopedNSAutoreleasePool pool;
|
||||
base::mac::SetOverrideFrameworkBundlePath(
|
||||
electron::MainApplicationBundlePath()
|
||||
atom::MainApplicationBundlePath()
|
||||
.Append("Contents")
|
||||
.Append("Frameworks")
|
||||
.Append(ELECTRON_PRODUCT_NAME " Framework.framework"));
|
||||
.Append(ATOM_PRODUCT_NAME " Framework.framework"));
|
||||
base::i18n::InitializeICU();
|
||||
return electron::NodeMain(argc, argv);
|
||||
return atom::NodeMain(argc, argv);
|
||||
}
|
||||
#endif
|
||||
@@ -1,7 +1,3 @@
|
||||
// Copyright (c) 2017 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
@@ -2,13 +2,11 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "shell/app/electron_main.h"
|
||||
#include "atom/app/atom_main.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdlib>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#if defined(OS_WIN)
|
||||
@@ -19,37 +17,33 @@
|
||||
#include <shellscalingapi.h>
|
||||
#include <tchar.h>
|
||||
|
||||
#include "atom/app/atom_main_delegate.h"
|
||||
#include "atom/app/command_line_args.h"
|
||||
#include "atom/common/crash_reporter/win/crash_service_main.h"
|
||||
#include "base/environment.h"
|
||||
#include "base/process/launch.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "base/win/windows_version.h"
|
||||
#include "components/browser_watcher/exit_code_watcher_win.h"
|
||||
#include "components/crash/core/app/crash_switches.h"
|
||||
#include "components/crash/core/app/run_as_crashpad_handler_win.h"
|
||||
#include "content/public/app/sandbox_helper_win.h"
|
||||
#include "sandbox/win/src/sandbox_types.h"
|
||||
#include "shell/app/command_line_args.h"
|
||||
#include "shell/app/electron_main_delegate.h"
|
||||
#include "third_party/crashpad/crashpad/util/win/initial_client_data.h"
|
||||
|
||||
#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"
|
||||
#include "shell/app/electron_main_delegate.h" // NOLINT
|
||||
#else // defined(OS_LINUX)
|
||||
#else // defined(OS_LINUX)
|
||||
#include <mach-o/dyld.h>
|
||||
#include <unistd.h>
|
||||
#include <cstdio>
|
||||
#include "shell/app/electron_library_main.h"
|
||||
#include "atom/app/atom_library_main.h"
|
||||
#endif // defined(OS_MACOSX)
|
||||
|
||||
#include "atom/app/node_main.h"
|
||||
#include "atom/common/atom_command_line.h"
|
||||
#include "atom/common/atom_constants.h"
|
||||
#include "base/at_exit.h"
|
||||
#include "base/i18n/icu_util.h"
|
||||
#include "electron/buildflags/buildflags.h"
|
||||
#include "shell/app/node_main.h"
|
||||
#include "shell/common/electron_command_line.h"
|
||||
#include "shell/common/electron_constants.h"
|
||||
|
||||
#if defined(HELPER_EXECUTABLE) && !defined(MAS_BUILD)
|
||||
#include "sandbox/mac/seatbelt_exec.h" // nogncheck
|
||||
@@ -57,13 +51,6 @@
|
||||
|
||||
namespace {
|
||||
|
||||
#if defined(OS_WIN)
|
||||
// Redefined here so we don't have to introduce a dependency on //content
|
||||
// from //electron:electron_app
|
||||
const char kUserDataDir[] = "user-data-dir";
|
||||
const char kProcessType[] = "type";
|
||||
#endif
|
||||
|
||||
ALLOW_UNUSED_TYPE bool IsEnvSet(const char* name) {
|
||||
#if defined(OS_WIN)
|
||||
size_t required_size;
|
||||
@@ -115,8 +102,18 @@ int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE, wchar_t* cmd, int) {
|
||||
|
||||
#ifdef _DEBUG
|
||||
// Don't display assert dialog boxes in CI test runs
|
||||
static const char* kCI = "CI";
|
||||
if (IsEnvSet(kCI)) {
|
||||
static const char* kCI = "ELECTRON_CI";
|
||||
bool is_ci = IsEnvSet(kCI);
|
||||
if (!is_ci) {
|
||||
for (int i = 0; i < arguments.argc; ++i) {
|
||||
if (!_wcsicmp(arguments.argv[i], L"--ci")) {
|
||||
is_ci = true;
|
||||
_putenv_s(kCI, "1"); // set flag for child processes
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (is_ci) {
|
||||
_CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_DEBUG | _CRTDBG_MODE_FILE);
|
||||
_CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR);
|
||||
|
||||
@@ -128,7 +125,7 @@ int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE, wchar_t* cmd, int) {
|
||||
#endif
|
||||
|
||||
#if BUILDFLAG(ENABLE_RUN_AS_NODE)
|
||||
bool run_as_node = IsEnvSet(electron::kRunAsNode);
|
||||
bool run_as_node = IsEnvSet(atom::kRunAsNode);
|
||||
#else
|
||||
bool run_as_node = false;
|
||||
#endif
|
||||
@@ -144,69 +141,30 @@ int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE, wchar_t* cmd, int) {
|
||||
if (run_as_node) {
|
||||
base::AtExitManager atexit_manager;
|
||||
base::i18n::InitializeICU();
|
||||
auto ret = electron::NodeMain(argv.size(), argv.data());
|
||||
auto ret = atom::NodeMain(argv.size(), argv.data());
|
||||
std::for_each(argv.begin(), argv.end(), free);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
base::CommandLine::Init(argv.size(), argv.data());
|
||||
const base::CommandLine* command_line =
|
||||
base::CommandLine::ForCurrentProcess();
|
||||
|
||||
const std::string process_type =
|
||||
command_line->GetSwitchValueASCII(kProcessType);
|
||||
|
||||
if (process_type == crash_reporter::switches::kCrashpadHandler) {
|
||||
// Check if we should monitor the exit code of this process
|
||||
std::unique_ptr<browser_watcher::ExitCodeWatcher> exit_code_watcher;
|
||||
|
||||
// Retrieve the client process from the command line
|
||||
crashpad::InitialClientData initial_client_data;
|
||||
if (initial_client_data.InitializeFromString(
|
||||
command_line->GetSwitchValueASCII("initial-client-data"))) {
|
||||
// Setup exit code watcher to monitor the parent process
|
||||
HANDLE duplicate_handle = INVALID_HANDLE_VALUE;
|
||||
if (DuplicateHandle(
|
||||
::GetCurrentProcess(), initial_client_data.client_process(),
|
||||
::GetCurrentProcess(), &duplicate_handle,
|
||||
PROCESS_QUERY_INFORMATION, FALSE, DUPLICATE_SAME_ACCESS)) {
|
||||
base::Process parent_process(duplicate_handle);
|
||||
exit_code_watcher =
|
||||
std::make_unique<browser_watcher::ExitCodeWatcher>();
|
||||
if (exit_code_watcher->Initialize(std::move(parent_process))) {
|
||||
exit_code_watcher->StartWatching();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The handler process must always be passed the user data dir on the
|
||||
// command line.
|
||||
DCHECK(command_line->HasSwitch(kUserDataDir));
|
||||
|
||||
base::FilePath user_data_dir =
|
||||
command_line->GetSwitchValuePath(kUserDataDir);
|
||||
int crashpad_status = crash_reporter::RunAsCrashpadHandler(
|
||||
*command_line, user_data_dir, kProcessType, kUserDataDir);
|
||||
if (crashpad_status != 0 && exit_code_watcher) {
|
||||
// Crashpad failed to initialize, explicitly stop the exit code watcher
|
||||
// so the crashpad-handler process can exit with an error
|
||||
exit_code_watcher->StopWatching();
|
||||
}
|
||||
return crashpad_status;
|
||||
const base::CommandLine& cmd_line = *base::CommandLine::ForCurrentProcess();
|
||||
if (cmd_line.GetSwitchValueASCII("type") ==
|
||||
crash_reporter::kCrashpadProcess) {
|
||||
return crash_service::Main(&argv);
|
||||
}
|
||||
|
||||
if (!electron::CheckCommandLineArguments(arguments.argc, arguments.argv))
|
||||
if (!atom::CheckCommandLineArguments(arguments.argc, arguments.argv))
|
||||
return -1;
|
||||
|
||||
sandbox::SandboxInterfaceInfo sandbox_info = {0};
|
||||
content::InitializeSandboxInfo(&sandbox_info);
|
||||
electron::ElectronMainDelegate delegate;
|
||||
atom::AtomMainDelegate delegate;
|
||||
|
||||
content::ContentMainParams params(&delegate);
|
||||
params.instance = instance;
|
||||
params.sandbox_info = &sandbox_info;
|
||||
electron::ElectronCommandLine::Init(arguments.argc, arguments.argv);
|
||||
atom::AtomCommandLine::Init(arguments.argc, arguments.argv);
|
||||
return content::ContentMain(params);
|
||||
}
|
||||
|
||||
@@ -216,18 +174,18 @@ int main(int argc, char* argv[]) {
|
||||
FixStdioStreams();
|
||||
|
||||
#if BUILDFLAG(ENABLE_RUN_AS_NODE)
|
||||
if (IsEnvSet(electron::kRunAsNode)) {
|
||||
if (IsEnvSet(atom::kRunAsNode)) {
|
||||
base::i18n::InitializeICU();
|
||||
base::AtExitManager atexit_manager;
|
||||
return electron::NodeMain(argc, argv);
|
||||
return atom::NodeMain(argc, argv);
|
||||
}
|
||||
#endif
|
||||
|
||||
electron::ElectronMainDelegate delegate;
|
||||
atom::AtomMainDelegate delegate;
|
||||
content::ContentMainParams params(&delegate);
|
||||
params.argc = argc;
|
||||
params.argv = const_cast<const char**>(argv);
|
||||
electron::ElectronCommandLine::Init(argc, argv);
|
||||
atom::AtomCommandLine::Init(argc, argv);
|
||||
return content::ContentMain(params);
|
||||
}
|
||||
|
||||
@@ -237,8 +195,8 @@ int main(int argc, char* argv[]) {
|
||||
FixStdioStreams();
|
||||
|
||||
#if BUILDFLAG(ENABLE_RUN_AS_NODE)
|
||||
if (IsEnvSet(electron::kRunAsNode)) {
|
||||
return ElectronInitializeICUandStartNode(argc, argv);
|
||||
if (IsEnvSet(atom::kRunAsNode)) {
|
||||
return AtomInitializeICUandStartNode(argc, argv);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -271,7 +229,7 @@ int main(int argc, char* argv[]) {
|
||||
}
|
||||
#endif // defined(HELPER_EXECUTABLE) && !defined(MAS_BUILD)
|
||||
|
||||
return ElectronMain(argc, argv);
|
||||
return AtomMain(argc, argv);
|
||||
}
|
||||
|
||||
#endif // defined(OS_MACOSX)
|
||||
@@ -2,9 +2,9 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef SHELL_APP_ELECTRON_MAIN_H_
|
||||
#define SHELL_APP_ELECTRON_MAIN_H_
|
||||
#ifndef ATOM_APP_ATOM_MAIN_H_
|
||||
#define ATOM_APP_ATOM_MAIN_H_
|
||||
|
||||
#include "content/public/app/content_main.h"
|
||||
|
||||
#endif // SHELL_APP_ELECTRON_MAIN_H_
|
||||
#endif // ATOM_APP_ATOM_MAIN_H_
|
||||
@@ -2,7 +2,7 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "shell/app/electron_main_delegate.h"
|
||||
#include "atom/app/atom_main_delegate.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
@@ -12,62 +12,49 @@
|
||||
#include <glib.h> // for g_setenv()
|
||||
#endif
|
||||
|
||||
#include "atom/app/atom_content_client.h"
|
||||
#include "atom/browser/atom_browser_client.h"
|
||||
#include "atom/browser/relauncher.h"
|
||||
#include "atom/common/options_switches.h"
|
||||
#include "atom/renderer/atom_renderer_client.h"
|
||||
#include "atom/renderer/atom_sandboxed_renderer_client.h"
|
||||
#include "atom/utility/atom_content_utility_client.h"
|
||||
#include "base/command_line.h"
|
||||
#include "base/debug/stack_trace.h"
|
||||
#include "base/environment.h"
|
||||
#include "base/files/file_util.h"
|
||||
#include "base/logging.h"
|
||||
#include "base/mac/bundle_locations.h"
|
||||
#include "base/path_service.h"
|
||||
#include "base/strings/string_split.h"
|
||||
#include "chrome/common/chrome_paths.h"
|
||||
#include "components/content_settings/core/common/content_settings_pattern.h"
|
||||
#include "content/public/common/content_switches.h"
|
||||
#include "electron/buildflags/buildflags.h"
|
||||
#include "extensions/common/constants.h"
|
||||
#include "ipc/ipc_buildflags.h"
|
||||
#include "services/service_manager/embedder/switches.h"
|
||||
#include "services/service_manager/sandbox/switches.h"
|
||||
#include "services/tracing/public/cpp/stack_sampling/tracing_sampler_profiler.h"
|
||||
#include "shell/app/electron_content_client.h"
|
||||
#include "shell/browser/electron_browser_client.h"
|
||||
#include "shell/browser/electron_gpu_client.h"
|
||||
#include "shell/browser/feature_list.h"
|
||||
#include "shell/browser/relauncher.h"
|
||||
#include "shell/common/electron_paths.h"
|
||||
#include "shell/common/options_switches.h"
|
||||
#include "shell/renderer/electron_renderer_client.h"
|
||||
#include "shell/renderer/electron_sandboxed_renderer_client.h"
|
||||
#include "shell/utility/electron_content_utility_client.h"
|
||||
#include "ui/base/l10n/l10n_util.h"
|
||||
#include "ui/base/resource/resource_bundle.h"
|
||||
#include "ui/base/ui_base_switches.h"
|
||||
|
||||
#if BUILDFLAG(IPC_MESSAGE_LOG_ENABLED)
|
||||
#define IPC_MESSAGE_MACROS_LOG_ENABLED
|
||||
#include "content/public/common/content_ipc_logging.h"
|
||||
#define IPC_LOG_TABLE_ADD_ENTRY(msg_id, logger) \
|
||||
content::RegisterIPCLogger(msg_id, logger)
|
||||
#include "atom/common/common_message_generator.h"
|
||||
#endif
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
#include "shell/app/electron_main_delegate_mac.h"
|
||||
#include "atom/app/atom_main_delegate_mac.h"
|
||||
#endif
|
||||
|
||||
#if defined(OS_WIN)
|
||||
#include "base/win/win_util.h"
|
||||
#include "chrome/child/v8_crashpad_support_win.h"
|
||||
#if defined(_WIN64)
|
||||
#include "atom/common/crash_reporter/crash_reporter_win.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(OS_LINUX)
|
||||
#include "components/crash/core/app/breakpad_linux.h"
|
||||
#include "v8/include/v8-wasm-trap-handler-posix.h"
|
||||
#include "v8/include/v8.h"
|
||||
#endif
|
||||
|
||||
#if !defined(MAS_BUILD)
|
||||
#include "components/crash/core/app/crashpad.h" // nogncheck
|
||||
#include "components/crash/core/common/crash_key.h"
|
||||
#include "components/crash/core/common/crash_keys.h"
|
||||
#include "shell/app/electron_crash_reporter_client.h"
|
||||
#include "shell/browser/api/electron_api_crash_reporter.h"
|
||||
#include "shell/common/crash_keys.h"
|
||||
#endif
|
||||
|
||||
namespace electron {
|
||||
namespace atom {
|
||||
|
||||
namespace {
|
||||
|
||||
@@ -87,7 +74,7 @@ bool IsSandboxEnabled(base::CommandLine* command_line) {
|
||||
// and resources loaded.
|
||||
bool SubprocessNeedsResourceBundle(const std::string& process_type) {
|
||||
return
|
||||
#if defined(OS_LINUX)
|
||||
#if defined(OS_POSIX) && !defined(OS_MACOSX)
|
||||
// The zygote process opens the resources for the renderers.
|
||||
process_type == service_manager::switches::kZygoteProcess ||
|
||||
#endif
|
||||
@@ -114,41 +101,6 @@ void InvalidParameterHandler(const wchar_t*,
|
||||
|
||||
} // namespace
|
||||
|
||||
// TODO(nornagon): move path provider overriding to its own file in
|
||||
// shell/common
|
||||
namespace electron {
|
||||
|
||||
bool GetDefaultCrashDumpsPath(base::FilePath* path) {
|
||||
base::FilePath cur;
|
||||
if (!base::PathService::Get(DIR_USER_DATA, &cur))
|
||||
return false;
|
||||
#if defined(OS_MACOSX) || defined(OS_WIN)
|
||||
cur = cur.Append(FILE_PATH_LITERAL("Crashpad"));
|
||||
#else
|
||||
cur = cur.Append(FILE_PATH_LITERAL("Crash Reports"));
|
||||
#endif
|
||||
// TODO(bauerb): http://crbug.com/259796
|
||||
base::ThreadRestrictions::ScopedAllowIO allow_io;
|
||||
if (!base::PathExists(cur) && !base::CreateDirectory(cur))
|
||||
return false;
|
||||
*path = cur;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ElectronPathProvider(int key, base::FilePath* path) {
|
||||
if (key == DIR_CRASH_DUMPS) {
|
||||
return GetDefaultCrashDumpsPath(path);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void RegisterPathProvider() {
|
||||
base::PathService::RegisterProvider(ElectronPathProvider, PATH_START,
|
||||
PATH_END);
|
||||
}
|
||||
|
||||
} // namespace electron
|
||||
|
||||
void LoadResourceBundle(const std::string& locale) {
|
||||
const bool initialized = ui::ResourceBundle::HasSharedInstance();
|
||||
if (initialized)
|
||||
@@ -169,23 +121,29 @@ void LoadResourceBundle(const std::string& locale) {
|
||||
bundle.ReloadLocaleResources(locale);
|
||||
bundle.AddDataPackFromPath(pak_dir.Append(FILE_PATH_LITERAL("resources.pak")),
|
||||
ui::SCALE_FACTOR_NONE);
|
||||
#if BUILDFLAG(ENABLE_PDF_VIEWER)
|
||||
NOTIMPLEMENTED()
|
||||
<< "Hi, whoever's fixing PDF support! Thanks! The pdf "
|
||||
"viewer resources haven't been ported over to the GN build yet, so "
|
||||
"you'll probably need to change this bit of code.";
|
||||
bundle.AddDataPackFromPath(
|
||||
pak_dir.Append(FILE_PATH_LITERAL("pdf_viewer_resources.pak")),
|
||||
ui::GetSupportedScaleFactors()[0]);
|
||||
#endif // BUILDFLAG(ENABLE_PDF_VIEWER)
|
||||
}
|
||||
|
||||
ElectronMainDelegate::ElectronMainDelegate() = default;
|
||||
AtomMainDelegate::AtomMainDelegate() {}
|
||||
|
||||
ElectronMainDelegate::~ElectronMainDelegate() = default;
|
||||
AtomMainDelegate::~AtomMainDelegate() {}
|
||||
|
||||
const char* const ElectronMainDelegate::kNonWildcardDomainNonPortSchemes[] = {
|
||||
extensions::kExtensionScheme};
|
||||
const size_t ElectronMainDelegate::kNonWildcardDomainNonPortSchemesSize =
|
||||
base::size(kNonWildcardDomainNonPortSchemes);
|
||||
|
||||
bool ElectronMainDelegate::BasicStartupComplete(int* exit_code) {
|
||||
bool AtomMainDelegate::BasicStartupComplete(int* exit_code) {
|
||||
auto* command_line = base::CommandLine::ForCurrentProcess();
|
||||
|
||||
logging::LoggingSettings settings;
|
||||
#if defined(OS_WIN)
|
||||
v8_crashpad_support::SetUp();
|
||||
#if defined(_WIN64)
|
||||
crash_reporter::CrashReporterWin::SetUnhandledExceptionFilter();
|
||||
#endif
|
||||
|
||||
// On Windows the terminal returns immediately, so we add a new line to
|
||||
// prevent output in the same line as the prompt.
|
||||
@@ -194,10 +152,7 @@ bool ElectronMainDelegate::BasicStartupComplete(int* exit_code) {
|
||||
#if defined(DEBUG)
|
||||
// Print logging to debug.log on Windows
|
||||
settings.logging_dest = logging::LOG_TO_ALL;
|
||||
base::FilePath log_filename;
|
||||
base::PathService::Get(base::DIR_EXE, &log_filename);
|
||||
log_filename = log_filename.AppendASCII("debug.log");
|
||||
settings.log_file_path = log_filename.value().c_str();
|
||||
settings.log_file = L"debug.log";
|
||||
settings.lock_log = logging::LOCK_LOG_FILE;
|
||||
settings.delete_old = logging::DELETE_OLD_LOG_FILE;
|
||||
#else
|
||||
@@ -230,16 +185,7 @@ bool ElectronMainDelegate::BasicStartupComplete(int* exit_code) {
|
||||
if (env->HasVar("ELECTRON_DISABLE_SANDBOX"))
|
||||
command_line->AppendSwitch(service_manager::switches::kNoSandbox);
|
||||
|
||||
tracing_sampler_profiler_ =
|
||||
tracing::TracingSamplerProfiler::CreateOnMainThread();
|
||||
|
||||
chrome::RegisterPathProvider();
|
||||
electron::RegisterPathProvider();
|
||||
|
||||
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
||||
ContentSettingsPattern::SetNonWildcardDomainNonPortSchemes(
|
||||
kNonWildcardDomainNonPortSchemes, kNonWildcardDomainNonPortSchemesSize);
|
||||
#endif
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
OverrideChildProcessPath();
|
||||
@@ -266,28 +212,13 @@ bool ElectronMainDelegate::BasicStartupComplete(int* exit_code) {
|
||||
<< " is not supported. See https://crbug.com/638180.";
|
||||
#endif
|
||||
|
||||
#if defined(MAS_BUILD)
|
||||
// In MAS build we are using --disable-remote-core-animation.
|
||||
//
|
||||
// According to ccameron:
|
||||
// If you're running with --disable-remote-core-animation, you may want to
|
||||
// also run with --disable-gpu-memory-buffer-compositor-resources as well.
|
||||
// That flag makes it so we use regular GL textures instead of IOSurfaces
|
||||
// for compositor resources. IOSurfaces are very heavyweight to
|
||||
// create/destroy, but they can be displayed directly by CoreAnimation (and
|
||||
// --disable-remote-core-animation makes it so we don't use this property,
|
||||
// so they're just heavyweight with no upside).
|
||||
command_line->AppendSwitch(
|
||||
::switches::kDisableGpuMemoryBufferCompositorResources);
|
||||
#endif
|
||||
|
||||
content_client_ = std::make_unique<ElectronContentClient>();
|
||||
content_client_ = std::make_unique<AtomContentClient>();
|
||||
SetContentClient(content_client_.get());
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void ElectronMainDelegate::PostEarlyInitialization(bool is_running_tests) {
|
||||
void AtomMainDelegate::PostEarlyInitialization(bool is_running_tests) {
|
||||
std::string custom_locale;
|
||||
ui::ResourceBundle::InitSharedInstanceWithLocale(
|
||||
custom_locale, nullptr, ui::ResourceBundle::LOAD_COMMON_RESOURCES);
|
||||
@@ -295,7 +226,7 @@ void ElectronMainDelegate::PostEarlyInitialization(bool is_running_tests) {
|
||||
if (cmd_line->HasSwitch(::switches::kLang)) {
|
||||
const std::string locale = cmd_line->GetSwitchValueASCII(::switches::kLang);
|
||||
const base::FilePath locale_file_path =
|
||||
ui::ResourceBundle::GetSharedInstance().GetLocaleFilePath(locale);
|
||||
ui::ResourceBundle::GetSharedInstance().GetLocaleFilePath(locale, true);
|
||||
if (!locale_file_path.empty()) {
|
||||
custom_locale = locale;
|
||||
#if defined(OS_LINUX)
|
||||
@@ -313,20 +244,16 @@ void ElectronMainDelegate::PostEarlyInitialization(bool is_running_tests) {
|
||||
|
||||
LoadResourceBundle(custom_locale);
|
||||
|
||||
ElectronBrowserClient::SetApplicationLocale(
|
||||
AtomBrowserClient::SetApplicationLocale(
|
||||
l10n_util::GetApplicationLocale(custom_locale));
|
||||
}
|
||||
|
||||
void ElectronMainDelegate::PreSandboxStartup() {
|
||||
void AtomMainDelegate::PreSandboxStartup() {
|
||||
auto* command_line = base::CommandLine::ForCurrentProcess();
|
||||
|
||||
std::string process_type =
|
||||
command_line->GetSwitchValueASCII(::switches::kProcessType);
|
||||
|
||||
#if !defined(MAS_BUILD)
|
||||
crash_reporter::InitializeCrashKeys();
|
||||
#endif
|
||||
|
||||
// Initialize ResourceBundle which handles files loaded from external
|
||||
// sources. The language should have been passed in to us from the
|
||||
// browser process as a command line flag.
|
||||
@@ -335,83 +262,49 @@ void ElectronMainDelegate::PreSandboxStartup() {
|
||||
LoadResourceBundle(locale);
|
||||
}
|
||||
|
||||
#if defined(OS_WIN) || (defined(OS_MACOSX) && !defined(MAS_BUILD))
|
||||
// In the main process, we wait for JS to call crashReporter.start() before
|
||||
// initializing crashpad. If we're in the renderer, we want to initialize it
|
||||
// immediately at boot.
|
||||
if (!process_type.empty()) {
|
||||
ElectronCrashReporterClient::Create();
|
||||
crash_reporter::InitializeCrashpad(false, process_type);
|
||||
}
|
||||
#endif
|
||||
// Only append arguments for browser process.
|
||||
if (!IsBrowserProcess(command_line))
|
||||
return;
|
||||
|
||||
#if defined(OS_LINUX)
|
||||
if (process_type != service_manager::switches::kZygoteProcess &&
|
||||
!process_type.empty()) {
|
||||
ElectronCrashReporterClient::Create();
|
||||
breakpad::InitCrashReporter(process_type);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(MAS_BUILD)
|
||||
crash_keys::SetCrashKeysFromCommandLine(*command_line);
|
||||
crash_keys::SetPlatformCrashKey();
|
||||
#endif
|
||||
|
||||
if (IsBrowserProcess(command_line)) {
|
||||
// Only append arguments for browser process.
|
||||
|
||||
// Allow file:// URIs to read other file:// URIs by default.
|
||||
command_line->AppendSwitch(::switches::kAllowFileAccessFromFiles);
|
||||
// Allow file:// URIs to read other file:// URIs by default.
|
||||
command_line->AppendSwitch(::switches::kAllowFileAccessFromFiles);
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
// Enable AVFoundation.
|
||||
command_line->AppendSwitch("enable-avfoundation");
|
||||
// Enable AVFoundation.
|
||||
command_line->AppendSwitch("enable-avfoundation");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void ElectronMainDelegate::PreCreateMainMessageLoop() {
|
||||
// This is initialized early because the service manager reads some feature
|
||||
// flags and we need to make sure the feature list is initialized before the
|
||||
// service manager reads the features.
|
||||
InitializeFeatureList();
|
||||
void AtomMainDelegate::PreCreateMainMessageLoop() {
|
||||
#if defined(OS_MACOSX)
|
||||
RegisterAtomCrApp();
|
||||
#endif
|
||||
}
|
||||
|
||||
content::ContentBrowserClient*
|
||||
ElectronMainDelegate::CreateContentBrowserClient() {
|
||||
browser_client_ = std::make_unique<ElectronBrowserClient>();
|
||||
content::ContentBrowserClient* AtomMainDelegate::CreateContentBrowserClient() {
|
||||
browser_client_.reset(new AtomBrowserClient);
|
||||
return browser_client_.get();
|
||||
}
|
||||
|
||||
content::ContentGpuClient* ElectronMainDelegate::CreateContentGpuClient() {
|
||||
gpu_client_ = std::make_unique<ElectronGpuClient>();
|
||||
return gpu_client_.get();
|
||||
}
|
||||
|
||||
content::ContentRendererClient*
|
||||
ElectronMainDelegate::CreateContentRendererClient() {
|
||||
AtomMainDelegate::CreateContentRendererClient() {
|
||||
auto* command_line = base::CommandLine::ForCurrentProcess();
|
||||
|
||||
if (IsSandboxEnabled(command_line)) {
|
||||
renderer_client_ = std::make_unique<ElectronSandboxedRendererClient>();
|
||||
renderer_client_.reset(new AtomSandboxedRendererClient);
|
||||
} else {
|
||||
renderer_client_ = std::make_unique<ElectronRendererClient>();
|
||||
renderer_client_.reset(new AtomRendererClient);
|
||||
}
|
||||
|
||||
return renderer_client_.get();
|
||||
}
|
||||
|
||||
content::ContentUtilityClient*
|
||||
ElectronMainDelegate::CreateContentUtilityClient() {
|
||||
utility_client_ = std::make_unique<ElectronContentUtilityClient>();
|
||||
content::ContentUtilityClient* AtomMainDelegate::CreateContentUtilityClient() {
|
||||
utility_client_.reset(new AtomContentUtilityClient);
|
||||
return utility_client_.get();
|
||||
}
|
||||
|
||||
int ElectronMainDelegate::RunProcess(
|
||||
int AtomMainDelegate::RunProcess(
|
||||
const std::string& process_type,
|
||||
const content::MainFunctionParams& main_function_params) {
|
||||
if (process_type == kRelauncherProcess)
|
||||
@@ -420,28 +313,23 @@ int ElectronMainDelegate::RunProcess(
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool ElectronMainDelegate::ShouldCreateFeatureList() {
|
||||
#if defined(OS_MACOSX)
|
||||
bool AtomMainDelegate::ShouldSendMachPort(const std::string& process_type) {
|
||||
return process_type != kRelauncherProcess;
|
||||
}
|
||||
|
||||
bool AtomMainDelegate::DelaySandboxInitialization(
|
||||
const std::string& process_type) {
|
||||
return process_type == kRelauncherProcess;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool AtomMainDelegate::ShouldLockSchemeRegistry() {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ElectronMainDelegate::ShouldLockSchemeRegistry() {
|
||||
bool AtomMainDelegate::ShouldCreateFeatureList() {
|
||||
return false;
|
||||
}
|
||||
|
||||
#if defined(OS_LINUX)
|
||||
void ElectronMainDelegate::ZygoteForked() {
|
||||
// Needs to be called after we have DIR_USER_DATA. BrowserMain sets
|
||||
// this up for the browser process in a different manner.
|
||||
ElectronCrashReporterClient::Create();
|
||||
const base::CommandLine* command_line =
|
||||
base::CommandLine::ForCurrentProcess();
|
||||
std::string process_type =
|
||||
command_line->GetSwitchValueASCII(::switches::kProcessType);
|
||||
breakpad::InitCrashReporter(process_type);
|
||||
|
||||
// Reset the command line for the newly spawned process.
|
||||
crash_keys::SetCrashKeysFromCommandLine(*command_line);
|
||||
}
|
||||
#endif // defined(OS_LINUX)
|
||||
|
||||
} // namespace electron
|
||||
} // namespace atom
|
||||
@@ -2,8 +2,8 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef SHELL_APP_ELECTRON_MAIN_DELEGATE_H_
|
||||
#define SHELL_APP_ELECTRON_MAIN_DELEGATE_H_
|
||||
#ifndef ATOM_APP_ATOM_MAIN_DELEGATE_H_
|
||||
#define ATOM_APP_ATOM_MAIN_DELEGATE_H_
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
@@ -11,20 +11,14 @@
|
||||
#include "content/public/app/content_main_delegate.h"
|
||||
#include "content/public/common/content_client.h"
|
||||
|
||||
namespace tracing {
|
||||
class TracingSamplerProfiler;
|
||||
}
|
||||
|
||||
namespace electron {
|
||||
namespace atom {
|
||||
|
||||
void LoadResourceBundle(const std::string& locale);
|
||||
|
||||
class ElectronMainDelegate : public content::ContentMainDelegate {
|
||||
class AtomMainDelegate : public content::ContentMainDelegate {
|
||||
public:
|
||||
static const char* const kNonWildcardDomainNonPortSchemes[];
|
||||
static const size_t kNonWildcardDomainNonPortSchemesSize;
|
||||
ElectronMainDelegate();
|
||||
~ElectronMainDelegate() override;
|
||||
AtomMainDelegate();
|
||||
~AtomMainDelegate() override;
|
||||
|
||||
protected:
|
||||
// content::ContentMainDelegate:
|
||||
@@ -33,17 +27,17 @@ class ElectronMainDelegate : public content::ContentMainDelegate {
|
||||
void PreCreateMainMessageLoop() override;
|
||||
void PostEarlyInitialization(bool is_running_tests) override;
|
||||
content::ContentBrowserClient* CreateContentBrowserClient() override;
|
||||
content::ContentGpuClient* CreateContentGpuClient() override;
|
||||
content::ContentRendererClient* CreateContentRendererClient() override;
|
||||
content::ContentUtilityClient* CreateContentUtilityClient() override;
|
||||
int RunProcess(
|
||||
const std::string& process_type,
|
||||
const content::MainFunctionParams& main_function_params) override;
|
||||
bool ShouldCreateFeatureList() override;
|
||||
bool ShouldLockSchemeRegistry() override;
|
||||
#if defined(OS_LINUX)
|
||||
void ZygoteForked() override;
|
||||
#if defined(OS_MACOSX)
|
||||
bool ShouldSendMachPort(const std::string& process_type) override;
|
||||
bool DelaySandboxInitialization(const std::string& process_type) override;
|
||||
#endif
|
||||
bool ShouldLockSchemeRegistry() override;
|
||||
bool ShouldCreateFeatureList() override;
|
||||
|
||||
private:
|
||||
#if defined(OS_MACOSX)
|
||||
@@ -54,14 +48,12 @@ class ElectronMainDelegate : public content::ContentMainDelegate {
|
||||
|
||||
std::unique_ptr<content::ContentBrowserClient> browser_client_;
|
||||
std::unique_ptr<content::ContentClient> content_client_;
|
||||
std::unique_ptr<content::ContentGpuClient> gpu_client_;
|
||||
std::unique_ptr<content::ContentRendererClient> renderer_client_;
|
||||
std::unique_ptr<content::ContentUtilityClient> utility_client_;
|
||||
std::unique_ptr<tracing::TracingSamplerProfiler> tracing_sampler_profiler_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(ElectronMainDelegate);
|
||||
DISALLOW_COPY_AND_ASSIGN(AtomMainDelegate);
|
||||
};
|
||||
|
||||
} // namespace electron
|
||||
} // namespace atom
|
||||
|
||||
#endif // SHELL_APP_ELECTRON_MAIN_DELEGATE_H_
|
||||
#endif // ATOM_APP_ATOM_MAIN_DELEGATE_H_
|
||||
@@ -2,14 +2,14 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef SHELL_APP_ELECTRON_MAIN_DELEGATE_MAC_H_
|
||||
#define SHELL_APP_ELECTRON_MAIN_DELEGATE_MAC_H_
|
||||
#ifndef ATOM_APP_ATOM_MAIN_DELEGATE_MAC_H_
|
||||
#define ATOM_APP_ATOM_MAIN_DELEGATE_MAC_H_
|
||||
|
||||
namespace electron {
|
||||
namespace atom {
|
||||
|
||||
// Initializes NSApplication.
|
||||
void RegisterAtomCrApp();
|
||||
|
||||
} // namespace electron
|
||||
} // namespace atom
|
||||
|
||||
#endif // SHELL_APP_ELECTRON_MAIN_DELEGATE_MAC_H_
|
||||
#endif // ATOM_APP_ATOM_MAIN_DELEGATE_MAC_H_
|
||||
@@ -2,10 +2,11 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "shell/app/electron_main_delegate.h"
|
||||
|
||||
#include <string>
|
||||
#include "atom/app/atom_main_delegate.h"
|
||||
|
||||
#include "atom/browser/mac/atom_application.h"
|
||||
#include "atom/common/application_info.h"
|
||||
#include "atom/common/mac/main_application_bundle.h"
|
||||
#include "base/files/file_path.h"
|
||||
#include "base/files/file_util.h"
|
||||
#include "base/mac/bundle_locations.h"
|
||||
@@ -15,12 +16,8 @@
|
||||
#include "base/strings/sys_string_conversions.h"
|
||||
#include "content/common/mac_helpers.h"
|
||||
#include "content/public/common/content_paths.h"
|
||||
#include "ppapi/buildflags/buildflags.h"
|
||||
#include "shell/browser/mac/electron_application.h"
|
||||
#include "shell/common/application_info.h"
|
||||
#include "shell/common/mac/main_application_bundle.h"
|
||||
|
||||
namespace electron {
|
||||
namespace atom {
|
||||
|
||||
namespace {
|
||||
|
||||
@@ -41,11 +38,9 @@ base::FilePath GetHelperAppPath(const base::FilePath& frameworks_path,
|
||||
} else if (base::EndsWith(path.value(), content::kMacHelperSuffix_gpu,
|
||||
base::CompareCase::SENSITIVE)) {
|
||||
helper_name += content::kMacHelperSuffix_gpu;
|
||||
#if BUILDFLAG(ENABLE_PLUGINS)
|
||||
} else if (base::EndsWith(path.value(), content::kMacHelperSuffix_plugin,
|
||||
base::CompareCase::SENSITIVE)) {
|
||||
helper_name += content::kMacHelperSuffix_plugin;
|
||||
#endif
|
||||
}
|
||||
|
||||
return frameworks_path.Append(name + " " + helper_name + ".app")
|
||||
@@ -56,15 +51,15 @@ base::FilePath GetHelperAppPath(const base::FilePath& frameworks_path,
|
||||
|
||||
} // namespace
|
||||
|
||||
void ElectronMainDelegate::OverrideFrameworkBundlePath() {
|
||||
void AtomMainDelegate::OverrideFrameworkBundlePath() {
|
||||
base::mac::SetOverrideFrameworkBundlePath(
|
||||
GetFrameworksPath().Append(ELECTRON_PRODUCT_NAME " Framework.framework"));
|
||||
GetFrameworksPath().Append(ATOM_PRODUCT_NAME " Framework.framework"));
|
||||
}
|
||||
|
||||
void ElectronMainDelegate::OverrideChildProcessPath() {
|
||||
void AtomMainDelegate::OverrideChildProcessPath() {
|
||||
base::FilePath frameworks_path = GetFrameworksPath();
|
||||
base::FilePath helper_path =
|
||||
GetHelperAppPath(frameworks_path, ELECTRON_PRODUCT_NAME);
|
||||
GetHelperAppPath(frameworks_path, ATOM_PRODUCT_NAME);
|
||||
if (!base::PathExists(helper_path))
|
||||
helper_path = GetHelperAppPath(frameworks_path, GetApplicationName());
|
||||
if (!base::PathExists(helper_path))
|
||||
@@ -72,7 +67,7 @@ void ElectronMainDelegate::OverrideChildProcessPath() {
|
||||
base::PathService::Override(content::CHILD_PROCESS_EXE, helper_path);
|
||||
}
|
||||
|
||||
void ElectronMainDelegate::SetUpBundleOverrides() {
|
||||
void AtomMainDelegate::SetUpBundleOverrides() {
|
||||
base::mac::ScopedNSAutoreleasePool pool;
|
||||
NSBundle* bundle = MainApplicationBundle();
|
||||
std::string base_bundle_id =
|
||||
@@ -88,4 +83,4 @@ void RegisterAtomCrApp() {
|
||||
[AtomApplication sharedApplication];
|
||||
}
|
||||
|
||||
} // namespace electron
|
||||
} // namespace atom
|
||||
@@ -2,7 +2,7 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "shell/app/command_line_args.h"
|
||||
#include "atom/app/command_line_args.h"
|
||||
|
||||
namespace {
|
||||
|
||||
@@ -33,7 +33,7 @@ bool IsUrlArg(const base::CommandLine::CharType* arg) {
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace electron {
|
||||
namespace atom {
|
||||
|
||||
bool CheckCommandLineArguments(int argc, base::CommandLine::CharType** argv) {
|
||||
const base::CommandLine::StringType dashdash(2, '-');
|
||||
@@ -50,4 +50,4 @@ bool CheckCommandLineArguments(int argc, base::CommandLine::CharType** argv) {
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace electron
|
||||
} // namespace atom
|
||||
@@ -2,15 +2,15 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef SHELL_APP_COMMAND_LINE_ARGS_H_
|
||||
#define SHELL_APP_COMMAND_LINE_ARGS_H_
|
||||
#ifndef ATOM_APP_COMMAND_LINE_ARGS_H_
|
||||
#define ATOM_APP_COMMAND_LINE_ARGS_H_
|
||||
|
||||
#include "base/command_line.h"
|
||||
|
||||
namespace electron {
|
||||
namespace atom {
|
||||
|
||||
bool CheckCommandLineArguments(int argc, base::CommandLine::CharType** argv);
|
||||
|
||||
} // namespace electron
|
||||
} // namespace atom
|
||||
|
||||
#endif // SHELL_APP_COMMAND_LINE_ARGS_H_
|
||||
#endif // ATOM_APP_COMMAND_LINE_ARGS_H_
|
||||
65
atom/app/manifests.cc
Normal file
65
atom/app/manifests.cc
Normal file
@@ -0,0 +1,65 @@
|
||||
// Copyright (c) 2019 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/app/manifests.h"
|
||||
|
||||
#include "base/no_destructor.h"
|
||||
#include "electron/atom/common/api/api.mojom.h"
|
||||
#include "printing/buildflags/buildflags.h"
|
||||
#include "services/proxy_resolver/public/cpp/manifest.h"
|
||||
#include "services/service_manager/public/cpp/manifest_builder.h"
|
||||
|
||||
#if BUILDFLAG(ENABLE_PRINTING)
|
||||
#include "components/services/pdf_compositor/public/cpp/manifest.h"
|
||||
#endif
|
||||
|
||||
#if BUILDFLAG(ENABLE_PRINT_PREVIEW)
|
||||
#include "chrome/services/printing/public/cpp/manifest.h"
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
|
||||
// TODO(https://crbug.com/781334): Remove these helpers and just update the
|
||||
// manifest definitions to be marked out-of-process. This is here only to avoid
|
||||
// extra churn when transitioning away from content_packaged_services.
|
||||
service_manager::Manifest MakeOutOfProcess(
|
||||
const service_manager::Manifest& manifest) {
|
||||
// cpplint.py emits a false positive [build/include_what_you_use]
|
||||
service_manager::Manifest copy(manifest); // NOLINT
|
||||
copy.options.execution_mode =
|
||||
service_manager::Manifest::ExecutionMode::kOutOfProcessBuiltin;
|
||||
return copy;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
const service_manager::Manifest& GetElectronContentBrowserOverlayManifest() {
|
||||
static base::NoDestructor<service_manager::Manifest> manifest{
|
||||
service_manager::ManifestBuilder()
|
||||
.WithDisplayName("Electron (browser process)")
|
||||
.RequireCapability("device", "device:geolocation_control")
|
||||
.RequireCapability("proxy_resolver", "factory")
|
||||
.RequireCapability("chrome_printing", "converter")
|
||||
.RequireCapability("pdf_compositor", "compositor")
|
||||
.ExposeInterfaceFilterCapability_Deprecated(
|
||||
"navigation:frame", "renderer",
|
||||
service_manager::Manifest::InterfaceList<
|
||||
atom::mojom::ElectronBrowser>())
|
||||
.Build()};
|
||||
return *manifest;
|
||||
}
|
||||
|
||||
const std::vector<service_manager::Manifest>&
|
||||
GetElectronBuiltinServiceManifests() {
|
||||
static base::NoDestructor<std::vector<service_manager::Manifest>> manifests{{
|
||||
MakeOutOfProcess(proxy_resolver::GetManifest()),
|
||||
#if BUILDFLAG(ENABLE_PRINTING)
|
||||
MakeOutOfProcess(printing::GetPdfCompositorManifest()),
|
||||
#endif
|
||||
#if BUILDFLAG(ENABLE_PRINT_PREVIEW)
|
||||
MakeOutOfProcess(GetChromePrintingManifest()),
|
||||
#endif
|
||||
}};
|
||||
return *manifests;
|
||||
}
|
||||
@@ -1,14 +1,16 @@
|
||||
// Copyright (c) 2019 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef SHELL_APP_MANIFESTS_H_
|
||||
#define SHELL_APP_MANIFESTS_H_
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "services/service_manager/public/cpp/manifest.h"
|
||||
|
||||
const service_manager::Manifest& GetElectronContentBrowserOverlayManifest();
|
||||
|
||||
#endif // SHELL_APP_MANIFESTS_H_
|
||||
// Copyright (c) 2019 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ATOM_APP_MANIFESTS_H_
|
||||
#define ATOM_APP_MANIFESTS_H_
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "services/service_manager/public/cpp/manifest.h"
|
||||
|
||||
const service_manager::Manifest& GetElectronContentBrowserOverlayManifest();
|
||||
const std::vector<service_manager::Manifest>&
|
||||
GetElectronBuiltinServiceManifests();
|
||||
|
||||
#endif // ATOM_APP_MANIFESTS_H_
|
||||
133
atom/app/node_main.cc
Normal file
133
atom/app/node_main.cc
Normal file
@@ -0,0 +1,133 @@
|
||||
// Copyright (c) 2015 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/app/node_main.h"
|
||||
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
#include "atom/app/uv_task_runner.h"
|
||||
#include "atom/browser/javascript_environment.h"
|
||||
#include "atom/browser/node_debugger.h"
|
||||
#include "atom/common/api/electron_bindings.h"
|
||||
#include "atom/common/atom_version.h"
|
||||
#include "atom/common/crash_reporter/crash_reporter.h"
|
||||
#include "atom/common/native_mate_converters/string16_converter.h"
|
||||
#include "atom/common/node_bindings.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "base/command_line.h"
|
||||
#include "base/feature_list.h"
|
||||
#include "base/task/thread_pool/thread_pool.h"
|
||||
#include "base/threading/thread_task_runner_handle.h"
|
||||
#include "gin/array_buffer.h"
|
||||
#include "gin/public/isolate_holder.h"
|
||||
#include "gin/v8_initializer.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
|
||||
#if defined(_WIN64)
|
||||
#include "atom/common/crash_reporter/crash_reporter_win.h"
|
||||
#endif
|
||||
|
||||
namespace atom {
|
||||
|
||||
int NodeMain(int argc, char* argv[]) {
|
||||
base::CommandLine::Init(argc, argv);
|
||||
|
||||
int exit_code = 1;
|
||||
{
|
||||
// Feed gin::PerIsolateData with a task runner.
|
||||
argv = uv_setup_args(argc, argv);
|
||||
uv_loop_t* loop = uv_default_loop();
|
||||
scoped_refptr<UvTaskRunner> uv_task_runner(new UvTaskRunner(loop));
|
||||
base::ThreadTaskRunnerHandle handle(uv_task_runner);
|
||||
|
||||
// Initialize feature list.
|
||||
auto feature_list = std::make_unique<base::FeatureList>();
|
||||
feature_list->InitializeFromCommandLine("", "");
|
||||
base::FeatureList::SetInstance(std::move(feature_list));
|
||||
|
||||
gin::V8Initializer::LoadV8Snapshot(
|
||||
gin::V8Initializer::V8SnapshotFileType::kWithAdditionalContext);
|
||||
gin::V8Initializer::LoadV8Natives();
|
||||
|
||||
// V8 requires a task scheduler apparently
|
||||
base::ThreadPoolInstance::CreateAndStartWithDefaultParams("Electron");
|
||||
|
||||
// Initialize gin::IsolateHolder.
|
||||
JavascriptEnvironment gin_env(loop);
|
||||
#if defined(_WIN64)
|
||||
crash_reporter::CrashReporterWin::SetUnhandledExceptionFilter();
|
||||
#endif
|
||||
|
||||
// Explicitly register electron's builtin modules.
|
||||
NodeBindings::RegisterBuiltinModules();
|
||||
|
||||
int exec_argc;
|
||||
const char** exec_argv;
|
||||
node::Init(&argc, const_cast<const char**>(argv), &exec_argc, &exec_argv);
|
||||
|
||||
node::Environment* env = node::CreateEnvironment(
|
||||
node::CreateIsolateData(gin_env.isolate(), loop, gin_env.platform()),
|
||||
gin_env.context(), argc, argv, exec_argc, exec_argv);
|
||||
|
||||
// Enable support for v8 inspector.
|
||||
NodeDebugger node_debugger(env);
|
||||
node_debugger.Start();
|
||||
|
||||
mate::Dictionary process(gin_env.isolate(), env->process_object());
|
||||
#if defined(OS_WIN)
|
||||
process.SetMethod("log", &ElectronBindings::Log);
|
||||
#endif
|
||||
process.SetMethod("crash", &ElectronBindings::Crash);
|
||||
|
||||
// Setup process.crashReporter.start in child node processes
|
||||
auto reporter = mate::Dictionary::CreateEmpty(gin_env.isolate());
|
||||
reporter.SetMethod("start", &crash_reporter::CrashReporter::StartInstance);
|
||||
process.Set("crashReporter", reporter);
|
||||
|
||||
mate::Dictionary versions;
|
||||
if (process.Get("versions", &versions)) {
|
||||
versions.SetReadOnly(ATOM_PROJECT_NAME, ATOM_VERSION_STRING);
|
||||
}
|
||||
|
||||
node::LoadEnvironment(env);
|
||||
|
||||
bool more;
|
||||
do {
|
||||
more = uv_run(env->event_loop(), UV_RUN_ONCE);
|
||||
gin_env.platform()->DrainTasks(env->isolate());
|
||||
if (more == false) {
|
||||
node::EmitBeforeExit(env);
|
||||
|
||||
// Emit `beforeExit` if the loop became alive either after emitting
|
||||
// event, or after running some callbacks.
|
||||
more = uv_loop_alive(env->event_loop());
|
||||
if (uv_run(env->event_loop(), UV_RUN_NOWAIT) != 0)
|
||||
more = true;
|
||||
}
|
||||
} while (more == true);
|
||||
|
||||
node_debugger.Stop();
|
||||
exit_code = node::EmitExit(env);
|
||||
node::RunAtExit(env);
|
||||
gin_env.platform()->DrainTasks(env->isolate());
|
||||
gin_env.platform()->CancelPendingDelayedTasks(env->isolate());
|
||||
gin_env.platform()->UnregisterIsolate(env->isolate());
|
||||
|
||||
node::FreeEnvironment(env);
|
||||
}
|
||||
|
||||
// According to "src/gin/shell/gin_main.cc":
|
||||
//
|
||||
// gin::IsolateHolder waits for tasks running in ThreadPool in its
|
||||
// destructor and thus must be destroyed before ThreadPool starts skipping
|
||||
// CONTINUE_ON_SHUTDOWN tasks.
|
||||
base::ThreadPoolInstance::Get()->Shutdown();
|
||||
|
||||
v8::V8::Dispose();
|
||||
|
||||
return exit_code;
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
@@ -2,13 +2,13 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef SHELL_APP_NODE_MAIN_H_
|
||||
#define SHELL_APP_NODE_MAIN_H_
|
||||
#ifndef ATOM_APP_NODE_MAIN_H_
|
||||
#define ATOM_APP_NODE_MAIN_H_
|
||||
|
||||
namespace electron {
|
||||
namespace atom {
|
||||
|
||||
int NodeMain(int argc, char* argv[]);
|
||||
|
||||
} // namespace electron
|
||||
} // namespace atom
|
||||
|
||||
#endif // SHELL_APP_NODE_MAIN_H_
|
||||
#endif // ATOM_APP_NODE_MAIN_H_
|
||||
@@ -3,7 +3,7 @@
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>${ELECTRON_BUNDLE_ID}</string>
|
||||
<string>${ATOM_BUNDLE_ID}</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>${PRODUCT_NAME}</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
@@ -12,7 +12,5 @@
|
||||
<string>APPL</string>
|
||||
<key>LSBackgroundOnly</key>
|
||||
<true/>
|
||||
<key>LSRequiresNativeExecution</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -4,11 +4,11 @@
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "shell/app/uv_task_runner.h"
|
||||
#include "atom/app/uv_task_runner.h"
|
||||
|
||||
#include "base/stl_util.h"
|
||||
|
||||
namespace electron {
|
||||
namespace atom {
|
||||
|
||||
UvTaskRunner::UvTaskRunner(uv_loop_t* loop) : loop_(loop) {}
|
||||
|
||||
@@ -42,13 +42,12 @@ bool UvTaskRunner::PostNonNestableDelayedTask(const base::Location& from_here,
|
||||
|
||||
// static
|
||||
void UvTaskRunner::OnTimeout(uv_timer_t* timer) {
|
||||
auto& tasks = static_cast<UvTaskRunner*>(timer->data)->tasks_;
|
||||
const auto iter = tasks.find(timer);
|
||||
if (iter == std::end(tasks))
|
||||
UvTaskRunner* self = static_cast<UvTaskRunner*>(timer->data);
|
||||
if (!ContainsKey(self->tasks_, timer))
|
||||
return;
|
||||
|
||||
std::move(iter->second).Run();
|
||||
tasks.erase(iter);
|
||||
std::move(self->tasks_[timer]).Run();
|
||||
self->tasks_.erase(timer);
|
||||
uv_timer_stop(timer);
|
||||
uv_close(reinterpret_cast<uv_handle_t*>(timer), UvTaskRunner::OnClose);
|
||||
}
|
||||
@@ -58,4 +57,4 @@ void UvTaskRunner::OnClose(uv_handle_t* handle) {
|
||||
delete reinterpret_cast<uv_timer_t*>(handle);
|
||||
}
|
||||
|
||||
} // namespace electron
|
||||
} // namespace atom
|
||||
@@ -2,17 +2,17 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef SHELL_APP_UV_TASK_RUNNER_H_
|
||||
#define SHELL_APP_UV_TASK_RUNNER_H_
|
||||
#ifndef ATOM_APP_UV_TASK_RUNNER_H_
|
||||
#define ATOM_APP_UV_TASK_RUNNER_H_
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "base/callback.h"
|
||||
#include "base/location.h"
|
||||
#include "base/single_thread_task_runner.h"
|
||||
#include "uv.h" // NOLINT(build/include_directory)
|
||||
#include "uv.h" // NOLINT(build/include)
|
||||
|
||||
namespace electron {
|
||||
namespace atom {
|
||||
|
||||
// TaskRunner implementation that posts tasks into libuv's default loop.
|
||||
class UvTaskRunner : public base::SingleThreadTaskRunner {
|
||||
@@ -40,6 +40,6 @@ class UvTaskRunner : public base::SingleThreadTaskRunner {
|
||||
DISALLOW_COPY_AND_ASSIGN(UvTaskRunner);
|
||||
};
|
||||
|
||||
} // namespace electron
|
||||
} // namespace atom
|
||||
|
||||
#endif // SHELL_APP_UV_TASK_RUNNER_H_
|
||||
#endif // ATOM_APP_UV_TASK_RUNNER_H_
|
||||
File diff suppressed because it is too large
Load Diff
@@ -2,8 +2,8 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef SHELL_BROWSER_API_ELECTRON_API_APP_H_
|
||||
#define SHELL_BROWSER_API_ELECTRON_API_APP_H_
|
||||
#ifndef ATOM_BROWSER_API_ATOM_API_APP_H_
|
||||
#define ATOM_BROWSER_API_ATOM_API_APP_H_
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
@@ -11,24 +11,25 @@
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "atom/browser/api/event_emitter.h"
|
||||
#include "atom/browser/atom_browser_client.h"
|
||||
#include "atom/browser/browser.h"
|
||||
#include "atom/browser/browser_observer.h"
|
||||
#include "atom/common/native_mate_converters/callback.h"
|
||||
#include "atom/common/promise_util.h"
|
||||
#include "base/process/process_iterator.h"
|
||||
#include "base/process/process_metrics.h"
|
||||
#include "base/task/cancelable_task_tracker.h"
|
||||
#include "chrome/browser/icon_manager.h"
|
||||
#include "chrome/browser/process_singleton.h"
|
||||
#include "content/public/browser/browser_child_process_observer.h"
|
||||
#include "content/public/browser/gpu_data_manager_observer.h"
|
||||
#include "content/public/browser/render_process_host.h"
|
||||
#include "gin/handle.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "native_mate/handle.h"
|
||||
#include "net/base/completion_once_callback.h"
|
||||
#include "net/base/completion_repeating_callback.h"
|
||||
#include "net/ssl/client_cert_identity.h"
|
||||
#include "shell/browser/api/process_metric.h"
|
||||
#include "shell/browser/browser.h"
|
||||
#include "shell/browser/browser_observer.h"
|
||||
#include "shell/browser/electron_browser_client.h"
|
||||
#include "shell/common/gin_helper/dictionary.h"
|
||||
#include "shell/common/gin_helper/error_thrower.h"
|
||||
#include "shell/common/gin_helper/event_emitter.h"
|
||||
#include "shell/common/gin_helper/promise.h"
|
||||
|
||||
#if defined(USE_NSS_CERTS)
|
||||
#include "chrome/browser/certificate_manager_model.h"
|
||||
@@ -38,32 +39,46 @@ namespace base {
|
||||
class FilePath;
|
||||
}
|
||||
|
||||
namespace electron {
|
||||
namespace mate {
|
||||
class Arguments;
|
||||
} // namespace mate
|
||||
|
||||
namespace atom {
|
||||
|
||||
#if defined(OS_WIN)
|
||||
enum class JumpListResult : int;
|
||||
#endif
|
||||
|
||||
struct ProcessMetric {
|
||||
int type;
|
||||
base::ProcessId pid;
|
||||
std::unique_ptr<base::ProcessMetrics> metrics;
|
||||
|
||||
ProcessMetric(int type,
|
||||
base::ProcessId pid,
|
||||
std::unique_ptr<base::ProcessMetrics> metrics);
|
||||
~ProcessMetric();
|
||||
};
|
||||
|
||||
namespace api {
|
||||
|
||||
class App : public ElectronBrowserClient::Delegate,
|
||||
public gin_helper::EventEmitter<App>,
|
||||
class App : public AtomBrowserClient::Delegate,
|
||||
public mate::EventEmitter<App>,
|
||||
public BrowserObserver,
|
||||
public content::GpuDataManagerObserver,
|
||||
public content::BrowserChildProcessObserver {
|
||||
public:
|
||||
using FileIconCallback =
|
||||
base::RepeatingCallback<void(v8::Local<v8::Value>, const gfx::Image&)>;
|
||||
base::Callback<void(v8::Local<v8::Value>, const gfx::Image&)>;
|
||||
|
||||
static gin::Handle<App> Create(v8::Isolate* isolate);
|
||||
static App* Get();
|
||||
static mate::Handle<App> Create(v8::Isolate* isolate);
|
||||
|
||||
static void BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype);
|
||||
|
||||
#if defined(USE_NSS_CERTS)
|
||||
void OnCertificateManagerModelCreated(
|
||||
base::Value options,
|
||||
std::unique_ptr<base::DictionaryValue> options,
|
||||
net::CompletionOnceCallback callback,
|
||||
std::unique_ptr<CertificateManagerModel> model);
|
||||
#endif
|
||||
@@ -71,10 +86,10 @@ class App : public ElectronBrowserClient::Delegate,
|
||||
base::FilePath GetAppPath() const;
|
||||
void RenderProcessReady(content::RenderProcessHost* host);
|
||||
void RenderProcessDisconnected(base::ProcessId host_pid);
|
||||
void PreMainMessageLoopRun();
|
||||
|
||||
protected:
|
||||
explicit App(v8::Isolate* isolate);
|
||||
|
||||
private:
|
||||
~App() override;
|
||||
|
||||
// BrowserObserver:
|
||||
@@ -87,9 +102,10 @@ class App : public ElectronBrowserClient::Delegate,
|
||||
void OnActivate(bool has_visible_windows) override;
|
||||
void OnWillFinishLaunching() override;
|
||||
void OnFinishLaunching(const base::DictionaryValue& launch_info) override;
|
||||
void OnLogin(scoped_refptr<LoginHandler> login_handler,
|
||||
const base::DictionaryValue& request_details) override;
|
||||
void OnAccessibilitySupportChanged() override;
|
||||
void OnPreMainMessageLoopRun() override;
|
||||
void OnPreCreateThreads() override;
|
||||
#if defined(OS_MACOSX)
|
||||
void OnWillContinueUserActivity(bool* prevent_default,
|
||||
const std::string& type) override;
|
||||
@@ -116,9 +132,10 @@ class App : public ElectronBrowserClient::Delegate,
|
||||
const GURL& request_url,
|
||||
bool is_main_frame_request,
|
||||
bool strict_enforcement,
|
||||
base::OnceCallback<void(content::CertificateRequestResultType)> callback)
|
||||
override;
|
||||
base::OnceClosure SelectClientCertificate(
|
||||
bool expired_previous_decision,
|
||||
const base::Callback<void(content::CertificateRequestResultType)>&
|
||||
callback) override;
|
||||
void SelectClientCertificate(
|
||||
content::WebContents* web_contents,
|
||||
net::SSLCertRequestInfo* cert_request_info,
|
||||
net::ClientCertIdentityList client_certs,
|
||||
@@ -133,14 +150,13 @@ class App : public ElectronBrowserClient::Delegate,
|
||||
const std::string& frame_name,
|
||||
WindowOpenDisposition disposition,
|
||||
const blink::mojom::WindowFeatures& features,
|
||||
const std::string& raw_features,
|
||||
const std::vector<std::string>& additional_features,
|
||||
const scoped_refptr<network::ResourceRequestBody>& body,
|
||||
bool user_gesture,
|
||||
bool opener_suppressed,
|
||||
bool* no_javascript_access) override;
|
||||
|
||||
// content::GpuDataManagerObserver:
|
||||
void OnGpuInfoUpdate() override;
|
||||
void OnGpuProcessCrashed(base::TerminationStatus status) override;
|
||||
|
||||
// content::BrowserChildProcessObserver:
|
||||
@@ -160,13 +176,11 @@ class App : public ElectronBrowserClient::Delegate,
|
||||
void ChildProcessLaunched(int process_type, base::ProcessHandle handle);
|
||||
void ChildProcessDisconnected(base::ProcessId pid);
|
||||
|
||||
void SetAppLogsPath(gin_helper::ErrorThrower thrower,
|
||||
base::Optional<base::FilePath> custom_path);
|
||||
void SetAppLogsPath(mate::Arguments* args);
|
||||
|
||||
// Get/Set the pre-defined path in PathService.
|
||||
base::FilePath GetPath(gin_helper::ErrorThrower thrower,
|
||||
const std::string& name);
|
||||
void SetPath(gin_helper::ErrorThrower thrower,
|
||||
base::FilePath GetPath(mate::Arguments* args, const std::string& name);
|
||||
void SetPath(mate::Arguments* args,
|
||||
const std::string& name,
|
||||
const base::FilePath& path);
|
||||
|
||||
@@ -178,43 +192,39 @@ class App : public ElectronBrowserClient::Delegate,
|
||||
bool HasSingleInstanceLock() const;
|
||||
bool RequestSingleInstanceLock();
|
||||
void ReleaseSingleInstanceLock();
|
||||
bool Relaunch(gin_helper::Arguments* args);
|
||||
void DisableHardwareAcceleration(gin_helper::ErrorThrower thrower);
|
||||
void DisableDomainBlockingFor3DAPIs(gin_helper::ErrorThrower thrower);
|
||||
bool Relaunch(mate::Arguments* args);
|
||||
void DisableHardwareAcceleration(mate::Arguments* args);
|
||||
void DisableDomainBlockingFor3DAPIs(mate::Arguments* args);
|
||||
bool IsAccessibilitySupportEnabled();
|
||||
void SetAccessibilitySupportEnabled(gin_helper::ErrorThrower thrower,
|
||||
bool enabled);
|
||||
Browser::LoginItemSettings GetLoginItemSettings(gin_helper::Arguments* args);
|
||||
void SetAccessibilitySupportEnabled(bool enabled, mate::Arguments* args);
|
||||
Browser::LoginItemSettings GetLoginItemSettings(mate::Arguments* args);
|
||||
#if defined(USE_NSS_CERTS)
|
||||
void ImportCertificate(gin_helper::ErrorThrower thrower,
|
||||
base::Value options,
|
||||
net::CompletionOnceCallback callback);
|
||||
void ImportCertificate(const base::DictionaryValue& options,
|
||||
net::CompletionRepeatingCallback callback);
|
||||
#endif
|
||||
v8::Local<v8::Promise> GetFileIcon(const base::FilePath& path,
|
||||
gin_helper::Arguments* args);
|
||||
mate::Arguments* args);
|
||||
|
||||
std::vector<gin_helper::Dictionary> GetAppMetrics(v8::Isolate* isolate);
|
||||
std::vector<mate::Dictionary> GetAppMetrics(v8::Isolate* isolate);
|
||||
v8::Local<v8::Value> GetGPUFeatureStatus(v8::Isolate* isolate);
|
||||
v8::Local<v8::Promise> GetGPUInfo(v8::Isolate* isolate,
|
||||
const std::string& info_type);
|
||||
void EnableSandbox(gin_helper::ErrorThrower thrower);
|
||||
void EnableSandbox(mate::Arguments* args);
|
||||
void SetUserAgentFallback(const std::string& user_agent);
|
||||
std::string GetUserAgentFallback();
|
||||
void SetBrowserClientCanUseCustomSiteInstance(bool should_disable);
|
||||
bool CanBrowserClientUseCustomSiteInstance();
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
void SetActivationPolicy(gin_helper::ErrorThrower thrower,
|
||||
const std::string& policy);
|
||||
bool MoveToApplicationsFolder(gin_helper::ErrorThrower, gin::Arguments* args);
|
||||
bool MoveToApplicationsFolder(mate::Arguments* args);
|
||||
bool IsInApplicationsFolder();
|
||||
v8::Local<v8::Value> GetDockAPI(v8::Isolate* isolate);
|
||||
v8::Global<v8::Value> dock_;
|
||||
#endif
|
||||
|
||||
#if defined(MAS_BUILD)
|
||||
base::RepeatingCallback<void()> StartAccessingSecurityScopedResource(
|
||||
gin_helper::Arguments* args);
|
||||
base::Callback<void()> StartAccessingSecurityScopedResource(
|
||||
mate::Arguments* args);
|
||||
#endif
|
||||
|
||||
#if defined(OS_WIN)
|
||||
@@ -222,8 +232,7 @@ class App : public ElectronBrowserClient::Delegate,
|
||||
v8::Local<v8::Value> GetJumpListSettings();
|
||||
|
||||
// Set or remove a custom Jump List for the application.
|
||||
JumpListResult SetJumpList(v8::Local<v8::Value> val,
|
||||
gin_helper::Arguments* args);
|
||||
JumpListResult SetJumpList(v8::Local<v8::Value> val, mate::Arguments* args);
|
||||
#endif // defined(OS_WIN)
|
||||
|
||||
std::unique_ptr<ProcessSingleton> process_singleton_;
|
||||
@@ -238,18 +247,14 @@ class App : public ElectronBrowserClient::Delegate,
|
||||
base::FilePath app_path_;
|
||||
|
||||
using ProcessMetricMap =
|
||||
std::unordered_map<base::ProcessId,
|
||||
std::unique_ptr<electron::ProcessMetric>>;
|
||||
std::unordered_map<base::ProcessId, std::unique_ptr<atom::ProcessMetric>>;
|
||||
ProcessMetricMap app_metrics_;
|
||||
|
||||
bool disable_hw_acceleration_ = false;
|
||||
bool disable_domain_blocking_for_3DAPIs_ = false;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(App);
|
||||
};
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace electron
|
||||
} // namespace atom
|
||||
|
||||
#endif // SHELL_BROWSER_API_ELECTRON_API_APP_H_
|
||||
#endif // ATOM_BROWSER_API_ATOM_API_APP_H_
|
||||
38
atom/browser/api/atom_api_app_mac.mm
Normal file
38
atom/browser/api/atom_api_app_mac.mm
Normal file
@@ -0,0 +1,38 @@
|
||||
// Copyright (c) 2019 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/browser/api/atom_api_app.h"
|
||||
#include "atom/browser/atom_paths.h"
|
||||
#include "atom/common/native_mate_converters/file_path_converter.h"
|
||||
#include "base/path_service.h"
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
void App::SetAppLogsPath(mate::Arguments* args) {
|
||||
base::FilePath custom_path;
|
||||
if (args->GetNext(&custom_path)) {
|
||||
if (!custom_path.IsAbsolute()) {
|
||||
args->ThrowError("Path must be absolute");
|
||||
return;
|
||||
}
|
||||
base::PathService::Override(DIR_APP_LOGS, custom_path);
|
||||
} else {
|
||||
NSString* bundle_name =
|
||||
[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleName"];
|
||||
NSString* logs_path =
|
||||
[NSString stringWithFormat:@"Library/Logs/%@", bundle_name];
|
||||
NSString* library_path =
|
||||
[NSHomeDirectory() stringByAppendingPathComponent:logs_path];
|
||||
base::PathService::Override(DIR_APP_LOGS,
|
||||
base::FilePath([library_path UTF8String]));
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
|
||||
} // namespace api
|
||||
@@ -2,15 +2,13 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "shell/browser/api/electron_api_app.h"
|
||||
|
||||
#include <string>
|
||||
#include "atom/browser/api/atom_api_app.h"
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
#include "base/strings/sys_string_conversions.h"
|
||||
|
||||
namespace electron {
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
@@ -21,13 +19,13 @@ void OnStopAccessingSecurityScopedResource(NSURL* bookmarkUrl) {
|
||||
}
|
||||
|
||||
// Get base64 encoded NSData, create a bookmark for it and start accessing it.
|
||||
base::RepeatingCallback<void()> App::StartAccessingSecurityScopedResource(
|
||||
gin_helper::Arguments* args) {
|
||||
base::Callback<void()> App::StartAccessingSecurityScopedResource(
|
||||
mate::Arguments* args) {
|
||||
std::string data;
|
||||
args->GetNext(&data);
|
||||
NSString* base64str = base::SysUTF8ToNSString(data);
|
||||
NSData* bookmarkData = [[NSData alloc] initWithBase64EncodedString:base64str
|
||||
options:0];
|
||||
NSData* bookmarkData =
|
||||
[[NSData alloc] initWithBase64EncodedString:base64str options:0];
|
||||
|
||||
// Create bookmarkUrl from NSData.
|
||||
BOOL isStale = false;
|
||||
@@ -57,10 +55,9 @@ base::RepeatingCallback<void()> App::StartAccessingSecurityScopedResource(
|
||||
[bookmarkUrl retain];
|
||||
|
||||
// Return a js callback which will close the bookmark.
|
||||
return base::BindRepeating(&OnStopAccessingSecurityScopedResource,
|
||||
bookmarkUrl);
|
||||
return base::Bind(&OnStopAccessingSecurityScopedResource, bookmarkUrl);
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
} // namespace atom
|
||||
|
||||
} // namespace electron
|
||||
} // namespace api
|
||||
@@ -2,20 +2,36 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "shell/browser/api/electron_api_auto_updater.h"
|
||||
#include "atom/browser/api/atom_api_auto_updater.h"
|
||||
|
||||
#include "atom/browser/browser.h"
|
||||
#include "atom/browser/native_window.h"
|
||||
#include "atom/browser/window_list.h"
|
||||
#include "atom/common/api/event_emitter_caller.h"
|
||||
#include "atom/common/native_mate_converters/callback.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "base/time/time.h"
|
||||
#include "shell/browser/browser.h"
|
||||
#include "shell/browser/native_window.h"
|
||||
#include "shell/browser/window_list.h"
|
||||
#include "shell/common/gin_converters/callback_converter.h"
|
||||
#include "shell/common/gin_converters/time_converter.h"
|
||||
#include "shell/common/gin_helper/dictionary.h"
|
||||
#include "shell/common/gin_helper/event_emitter_caller.h"
|
||||
#include "shell/common/gin_helper/object_template_builder.h"
|
||||
#include "shell/common/node_includes.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "native_mate/object_template_builder.h"
|
||||
|
||||
namespace electron {
|
||||
namespace mate {
|
||||
|
||||
template <>
|
||||
struct Converter<base::Time> {
|
||||
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
||||
const base::Time& val) {
|
||||
v8::MaybeLocal<v8::Value> date =
|
||||
v8::Date::New(isolate->GetCurrentContext(), val.ToJsTime());
|
||||
if (date.IsEmpty())
|
||||
return v8::Null(isolate);
|
||||
else
|
||||
return date.ToLocalChecked();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace mate
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
@@ -31,8 +47,8 @@ AutoUpdater::~AutoUpdater() {
|
||||
void AutoUpdater::OnError(const std::string& message) {
|
||||
v8::Locker locker(isolate());
|
||||
v8::HandleScope handle_scope(isolate());
|
||||
auto error = v8::Exception::Error(gin::StringToV8(isolate(), message));
|
||||
gin_helper::EmitEvent(
|
||||
auto error = v8::Exception::Error(mate::StringToV8(isolate(), message));
|
||||
mate::EmitEvent(
|
||||
isolate(), GetWrapper(), "error",
|
||||
error->ToObject(isolate()->GetCurrentContext()).ToLocalChecked(),
|
||||
// Message is also emitted to keep compatibility with old code.
|
||||
@@ -44,7 +60,7 @@ void AutoUpdater::OnError(const std::string& message,
|
||||
const std::string& domain) {
|
||||
v8::Locker locker(isolate());
|
||||
v8::HandleScope handle_scope(isolate());
|
||||
auto error = v8::Exception::Error(gin::StringToV8(isolate(), message));
|
||||
auto error = v8::Exception::Error(mate::StringToV8(isolate(), message));
|
||||
auto errorObject =
|
||||
error->ToObject(isolate()->GetCurrentContext()).ToLocalChecked();
|
||||
|
||||
@@ -52,15 +68,15 @@ void AutoUpdater::OnError(const std::string& message,
|
||||
|
||||
// add two new params for better error handling
|
||||
errorObject
|
||||
->Set(context, gin::StringToV8(isolate(), "code"),
|
||||
->Set(context, mate::StringToV8(isolate(), "code"),
|
||||
v8::Integer::New(isolate(), code))
|
||||
.Check();
|
||||
errorObject
|
||||
->Set(context, gin::StringToV8(isolate(), "domain"),
|
||||
gin::StringToV8(isolate(), domain))
|
||||
->Set(context, mate::StringToV8(isolate(), "domain"),
|
||||
mate::StringToV8(isolate(), domain))
|
||||
.Check();
|
||||
|
||||
gin_helper::EmitEvent(isolate(), GetWrapper(), "error", errorObject, message);
|
||||
mate::EmitEvent(isolate(), GetWrapper(), "error", errorObject, message);
|
||||
}
|
||||
|
||||
void AutoUpdater::OnCheckingForUpdate() {
|
||||
@@ -81,15 +97,14 @@ void AutoUpdater::OnUpdateDownloaded(const std::string& release_notes,
|
||||
const std::string& url) {
|
||||
Emit("update-downloaded", release_notes, release_name, release_date, url,
|
||||
// Keep compatibility with old APIs.
|
||||
base::BindRepeating(&AutoUpdater::QuitAndInstall,
|
||||
base::Unretained(this)));
|
||||
base::Bind(&AutoUpdater::QuitAndInstall, base::Unretained(this)));
|
||||
}
|
||||
|
||||
void AutoUpdater::OnWindowAllClosed() {
|
||||
QuitAndInstall();
|
||||
}
|
||||
|
||||
void AutoUpdater::SetFeedURL(gin_helper::Arguments* args) {
|
||||
void AutoUpdater::SetFeedURL(mate::Arguments* args) {
|
||||
auto_updater::AutoUpdater::SetFeedURL(args);
|
||||
}
|
||||
|
||||
@@ -108,15 +123,15 @@ void AutoUpdater::QuitAndInstall() {
|
||||
}
|
||||
|
||||
// static
|
||||
gin::Handle<AutoUpdater> AutoUpdater::Create(v8::Isolate* isolate) {
|
||||
return gin::CreateHandle(isolate, new AutoUpdater(isolate));
|
||||
mate::Handle<AutoUpdater> AutoUpdater::Create(v8::Isolate* isolate) {
|
||||
return mate::CreateHandle(isolate, new AutoUpdater(isolate));
|
||||
}
|
||||
|
||||
// static
|
||||
void AutoUpdater::BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype) {
|
||||
prototype->SetClassName(gin::StringToV8(isolate, "AutoUpdater"));
|
||||
gin_helper::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
||||
prototype->SetClassName(mate::StringToV8(isolate, "AutoUpdater"));
|
||||
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
||||
.SetMethod("checkForUpdates", &auto_updater::AutoUpdater::CheckForUpdates)
|
||||
.SetMethod("getFeedURL", &auto_updater::AutoUpdater::GetFeedURL)
|
||||
.SetMethod("setFeedURL", &AutoUpdater::SetFeedURL)
|
||||
@@ -125,18 +140,18 @@ void AutoUpdater::BuildPrototype(v8::Isolate* isolate,
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace electron
|
||||
} // namespace atom
|
||||
|
||||
namespace {
|
||||
|
||||
using electron::api::AutoUpdater;
|
||||
using atom::api::AutoUpdater;
|
||||
|
||||
void Initialize(v8::Local<v8::Object> exports,
|
||||
v8::Local<v8::Value> unused,
|
||||
v8::Local<v8::Context> context,
|
||||
void* priv) {
|
||||
v8::Isolate* isolate = context->GetIsolate();
|
||||
gin_helper::Dictionary dict(isolate, exports);
|
||||
mate::Dictionary dict(isolate, exports);
|
||||
dict.Set("autoUpdater", AutoUpdater::Create(isolate));
|
||||
dict.Set("AutoUpdater", AutoUpdater::GetConstructor(isolate)
|
||||
->GetFunction(context)
|
||||
@@ -145,4 +160,4 @@ void Initialize(v8::Local<v8::Object> exports,
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(electron_browser_auto_updater, Initialize)
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_auto_updater, Initialize)
|
||||
@@ -2,25 +2,26 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef SHELL_BROWSER_API_ELECTRON_API_AUTO_UPDATER_H_
|
||||
#define SHELL_BROWSER_API_ELECTRON_API_AUTO_UPDATER_H_
|
||||
#ifndef ATOM_BROWSER_API_ATOM_API_AUTO_UPDATER_H_
|
||||
#define ATOM_BROWSER_API_ATOM_API_AUTO_UPDATER_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "gin/handle.h"
|
||||
#include "shell/browser/auto_updater.h"
|
||||
#include "shell/browser/window_list_observer.h"
|
||||
#include "shell/common/gin_helper/event_emitter.h"
|
||||
#include "atom/browser/api/event_emitter.h"
|
||||
#include "atom/browser/auto_updater.h"
|
||||
#include "atom/browser/window_list_observer.h"
|
||||
#include "native_mate/arguments.h"
|
||||
#include "native_mate/handle.h"
|
||||
|
||||
namespace electron {
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
class AutoUpdater : public gin_helper::EventEmitter<AutoUpdater>,
|
||||
class AutoUpdater : public mate::EventEmitter<AutoUpdater>,
|
||||
public auto_updater::Delegate,
|
||||
public WindowListObserver {
|
||||
public:
|
||||
static gin::Handle<AutoUpdater> Create(v8::Isolate* isolate);
|
||||
static mate::Handle<AutoUpdater> Create(v8::Isolate* isolate);
|
||||
|
||||
static void BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype);
|
||||
@@ -47,7 +48,7 @@ class AutoUpdater : public gin_helper::EventEmitter<AutoUpdater>,
|
||||
|
||||
private:
|
||||
std::string GetFeedURL();
|
||||
void SetFeedURL(gin_helper::Arguments* args);
|
||||
void SetFeedURL(mate::Arguments* args);
|
||||
void QuitAndInstall();
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(AutoUpdater);
|
||||
@@ -55,6 +56,6 @@ class AutoUpdater : public gin_helper::EventEmitter<AutoUpdater>,
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace electron
|
||||
} // namespace atom
|
||||
|
||||
#endif // SHELL_BROWSER_API_ELECTRON_API_AUTO_UPDATER_H_
|
||||
#endif // ATOM_BROWSER_API_ATOM_API_AUTO_UPDATER_H_
|
||||
@@ -2,27 +2,28 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "shell/browser/api/electron_api_browser_view.h"
|
||||
#include "atom/browser/api/atom_api_browser_view.h"
|
||||
|
||||
#include "shell/browser/api/electron_api_web_contents.h"
|
||||
#include "shell/browser/browser.h"
|
||||
#include "shell/browser/native_browser_view.h"
|
||||
#include "shell/common/color_util.h"
|
||||
#include "shell/common/gin_converters/gfx_converter.h"
|
||||
#include "shell/common/gin_helper/dictionary.h"
|
||||
#include "shell/common/gin_helper/object_template_builder.h"
|
||||
#include "shell/common/node_includes.h"
|
||||
#include "shell/common/options_switches.h"
|
||||
#include "atom/browser/api/atom_api_web_contents.h"
|
||||
#include "atom/browser/browser.h"
|
||||
#include "atom/browser/native_browser_view.h"
|
||||
#include "atom/common/color_util.h"
|
||||
#include "atom/common/native_mate_converters/gfx_converter.h"
|
||||
#include "atom/common/native_mate_converters/value_converter.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "atom/common/options_switches.h"
|
||||
#include "native_mate/constructor.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "ui/gfx/geometry/rect.h"
|
||||
|
||||
namespace gin {
|
||||
namespace mate {
|
||||
|
||||
template <>
|
||||
struct Converter<electron::AutoResizeFlags> {
|
||||
struct Converter<atom::AutoResizeFlags> {
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
electron::AutoResizeFlags* auto_resize_flags) {
|
||||
gin_helper::Dictionary params;
|
||||
atom::AutoResizeFlags* auto_resize_flags) {
|
||||
mate::Dictionary params;
|
||||
if (!ConvertFromV8(isolate, val, ¶ms)) {
|
||||
return false;
|
||||
}
|
||||
@@ -30,40 +31,45 @@ struct Converter<electron::AutoResizeFlags> {
|
||||
uint8_t flags = 0;
|
||||
bool width = false;
|
||||
if (params.Get("width", &width) && width) {
|
||||
flags |= electron::kAutoResizeWidth;
|
||||
flags |= atom::kAutoResizeWidth;
|
||||
}
|
||||
bool height = false;
|
||||
if (params.Get("height", &height) && height) {
|
||||
flags |= electron::kAutoResizeHeight;
|
||||
flags |= atom::kAutoResizeHeight;
|
||||
}
|
||||
bool horizontal = false;
|
||||
if (params.Get("horizontal", &horizontal) && horizontal) {
|
||||
flags |= electron::kAutoResizeHorizontal;
|
||||
flags |= atom::kAutoResizeHorizontal;
|
||||
}
|
||||
bool vertical = false;
|
||||
if (params.Get("vertical", &vertical) && vertical) {
|
||||
flags |= electron::kAutoResizeVertical;
|
||||
flags |= atom::kAutoResizeVertical;
|
||||
}
|
||||
|
||||
*auto_resize_flags = static_cast<electron::AutoResizeFlags>(flags);
|
||||
*auto_resize_flags = static_cast<atom::AutoResizeFlags>(flags);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace gin
|
||||
} // namespace mate
|
||||
|
||||
namespace electron {
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
BrowserView::BrowserView(gin::Arguments* args,
|
||||
const gin_helper::Dictionary& options) {
|
||||
v8::Isolate* isolate = args->isolate();
|
||||
gin_helper::Dictionary web_preferences =
|
||||
gin::Dictionary::CreateEmpty(isolate);
|
||||
BrowserView::BrowserView(v8::Isolate* isolate,
|
||||
v8::Local<v8::Object> wrapper,
|
||||
const mate::Dictionary& options) {
|
||||
Init(isolate, wrapper, options);
|
||||
}
|
||||
|
||||
void BrowserView::Init(v8::Isolate* isolate,
|
||||
v8::Local<v8::Object> wrapper,
|
||||
const mate::Dictionary& options) {
|
||||
mate::Dictionary web_preferences = mate::Dictionary::CreateEmpty(isolate);
|
||||
options.Get(options::kWebPreferences, &web_preferences);
|
||||
web_preferences.Set("type", "browserView");
|
||||
gin::Handle<class WebContents> web_contents =
|
||||
web_preferences.Set("isBrowserView", true);
|
||||
mate::Handle<class WebContents> web_contents =
|
||||
WebContents::Create(isolate, web_preferences);
|
||||
|
||||
web_contents_.Reset(isolate, web_contents.ToV8());
|
||||
@@ -73,7 +79,7 @@ BrowserView::BrowserView(gin::Arguments* args,
|
||||
view_.reset(
|
||||
NativeBrowserView::Create(api_web_contents_->managed_web_contents()));
|
||||
|
||||
InitWithArgs(args);
|
||||
InitWith(isolate, wrapper);
|
||||
}
|
||||
|
||||
BrowserView::~BrowserView() {
|
||||
@@ -90,17 +96,23 @@ void BrowserView::WebContentsDestroyed() {
|
||||
}
|
||||
|
||||
// static
|
||||
gin_helper::WrappableBase* BrowserView::New(gin_helper::ErrorThrower thrower,
|
||||
gin::Arguments* args) {
|
||||
mate::WrappableBase* BrowserView::New(mate::Arguments* args) {
|
||||
if (!Browser::Get()->is_ready()) {
|
||||
thrower.ThrowError("Cannot create BrowserView before app is ready");
|
||||
args->ThrowError("Cannot create BrowserView before app is ready");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
gin::Dictionary options = gin::Dictionary::CreateEmpty(args->isolate());
|
||||
args->GetNext(&options);
|
||||
if (args->Length() > 1) {
|
||||
args->ThrowError("Too many arguments");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return new BrowserView(args, options);
|
||||
mate::Dictionary options;
|
||||
if (!(args->Length() == 1 && args->GetNext(&options))) {
|
||||
options = mate::Dictionary::CreateEmpty(args->isolate());
|
||||
}
|
||||
|
||||
return new BrowserView(args->isolate(), args->GetThis(), options);
|
||||
}
|
||||
|
||||
int32_t BrowserView::ID() const {
|
||||
@@ -115,10 +127,6 @@ void BrowserView::SetBounds(const gfx::Rect& bounds) {
|
||||
view_->SetBounds(bounds);
|
||||
}
|
||||
|
||||
gfx::Rect BrowserView::GetBounds() {
|
||||
return view_->GetBounds();
|
||||
}
|
||||
|
||||
void BrowserView::SetBackgroundColor(const std::string& color_name) {
|
||||
view_->SetBackgroundColor(ParseHexColor(color_name));
|
||||
}
|
||||
@@ -134,12 +142,11 @@ v8::Local<v8::Value> BrowserView::GetWebContents() {
|
||||
// static
|
||||
void BrowserView::BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype) {
|
||||
prototype->SetClassName(gin::StringToV8(isolate, "BrowserView"));
|
||||
gin_helper::Destroyable::MakeDestroyable(isolate, prototype);
|
||||
gin_helper::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
||||
prototype->SetClassName(mate::StringToV8(isolate, "BrowserView"));
|
||||
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
||||
.MakeDestroyable()
|
||||
.SetMethod("setAutoResize", &BrowserView::SetAutoResize)
|
||||
.SetMethod("setBounds", &BrowserView::SetBounds)
|
||||
.SetMethod("getBounds", &BrowserView::GetBounds)
|
||||
.SetMethod("setBackgroundColor", &BrowserView::SetBackgroundColor)
|
||||
.SetProperty("webContents", &BrowserView::GetWebContents)
|
||||
.SetProperty("id", &BrowserView::ID);
|
||||
@@ -147,29 +154,30 @@ void BrowserView::BuildPrototype(v8::Isolate* isolate,
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace electron
|
||||
} // namespace atom
|
||||
|
||||
namespace {
|
||||
|
||||
using electron::api::BrowserView;
|
||||
using atom::api::BrowserView;
|
||||
|
||||
void Initialize(v8::Local<v8::Object> exports,
|
||||
v8::Local<v8::Value> unused,
|
||||
v8::Local<v8::Context> context,
|
||||
void* priv) {
|
||||
v8::Isolate* isolate = context->GetIsolate();
|
||||
BrowserView::SetConstructor(isolate, base::BindRepeating(&BrowserView::New));
|
||||
BrowserView::SetConstructor(isolate, base::Bind(&BrowserView::New));
|
||||
|
||||
gin_helper::Dictionary browser_view(isolate,
|
||||
BrowserView::GetConstructor(isolate)
|
||||
->GetFunction(context)
|
||||
.ToLocalChecked());
|
||||
browser_view.SetMethod("fromId", &BrowserView::FromWeakMapID);
|
||||
browser_view.SetMethod("getAllViews", &BrowserView::GetAll);
|
||||
gin_helper::Dictionary dict(isolate, exports);
|
||||
mate::Dictionary browser_view(isolate, BrowserView::GetConstructor(isolate)
|
||||
->GetFunction(context)
|
||||
.ToLocalChecked());
|
||||
browser_view.SetMethod("fromId",
|
||||
&mate::TrackableObject<BrowserView>::FromWeakMapID);
|
||||
browser_view.SetMethod("getAllViews",
|
||||
&mate::TrackableObject<BrowserView>::GetAll);
|
||||
mate::Dictionary dict(isolate, exports);
|
||||
dict.Set("BrowserView", browser_view);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(electron_browser_browser_view, Initialize)
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_browser_view, Initialize)
|
||||
@@ -2,27 +2,27 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef SHELL_BROWSER_API_ELECTRON_API_BROWSER_VIEW_H_
|
||||
#define SHELL_BROWSER_API_ELECTRON_API_BROWSER_VIEW_H_
|
||||
#ifndef ATOM_BROWSER_API_ATOM_API_BROWSER_VIEW_H_
|
||||
#define ATOM_BROWSER_API_ATOM_API_BROWSER_VIEW_H_
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "atom/browser/api/trackable_object.h"
|
||||
#include "atom/browser/native_browser_view.h"
|
||||
#include "content/public/browser/web_contents_observer.h"
|
||||
#include "gin/handle.h"
|
||||
#include "shell/browser/native_browser_view.h"
|
||||
#include "shell/common/gin_helper/error_thrower.h"
|
||||
#include "shell/common/gin_helper/trackable_object.h"
|
||||
#include "native_mate/handle.h"
|
||||
|
||||
namespace gfx {
|
||||
class Rect;
|
||||
}
|
||||
|
||||
namespace gin_helper {
|
||||
namespace mate {
|
||||
class Arguments;
|
||||
class Dictionary;
|
||||
}
|
||||
} // namespace mate
|
||||
|
||||
namespace electron {
|
||||
namespace atom {
|
||||
|
||||
class NativeBrowserView;
|
||||
|
||||
@@ -30,11 +30,10 @@ namespace api {
|
||||
|
||||
class WebContents;
|
||||
|
||||
class BrowserView : public gin_helper::TrackableObject<BrowserView>,
|
||||
class BrowserView : public mate::TrackableObject<BrowserView>,
|
||||
public content::WebContentsObserver {
|
||||
public:
|
||||
static gin_helper::WrappableBase* New(gin_helper::ErrorThrower thrower,
|
||||
gin::Arguments* args);
|
||||
static mate::WrappableBase* New(mate::Arguments* args);
|
||||
|
||||
static void BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype);
|
||||
@@ -45,17 +44,23 @@ class BrowserView : public gin_helper::TrackableObject<BrowserView>,
|
||||
int32_t ID() const;
|
||||
|
||||
protected:
|
||||
BrowserView(gin::Arguments* args, const gin_helper::Dictionary& options);
|
||||
BrowserView(v8::Isolate* isolate,
|
||||
v8::Local<v8::Object> wrapper,
|
||||
const mate::Dictionary& options);
|
||||
~BrowserView() override;
|
||||
|
||||
// content::WebContentsObserver:
|
||||
void WebContentsDestroyed() override;
|
||||
|
||||
private:
|
||||
void Init(v8::Isolate* isolate,
|
||||
v8::Local<v8::Object> wrapper,
|
||||
const mate::Dictionary& options);
|
||||
|
||||
void SetAutoResize(AutoResizeFlags flags);
|
||||
void SetBounds(const gfx::Rect& bounds);
|
||||
gfx::Rect GetBounds();
|
||||
void SetBackgroundColor(const std::string& color_name);
|
||||
|
||||
v8::Local<v8::Value> GetWebContents();
|
||||
|
||||
v8::Global<v8::Value> web_contents_;
|
||||
@@ -68,6 +73,6 @@ class BrowserView : public gin_helper::TrackableObject<BrowserView>,
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace electron
|
||||
} // namespace atom
|
||||
|
||||
#endif // SHELL_BROWSER_API_ELECTRON_API_BROWSER_VIEW_H_
|
||||
#endif // ATOM_BROWSER_API_ATOM_API_BROWSER_VIEW_H_
|
||||
@@ -2,40 +2,42 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "shell/browser/api/electron_api_browser_window.h"
|
||||
#include "atom/browser/api/atom_api_browser_window.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "atom/browser/browser.h"
|
||||
#include "atom/browser/unresponsive_suppressor.h"
|
||||
#include "atom/browser/web_contents_preferences.h"
|
||||
#include "atom/browser/window_list.h"
|
||||
#include "atom/common/api/api_messages.h"
|
||||
#include "atom/common/api/constructor.h"
|
||||
#include "atom/common/color_util.h"
|
||||
#include "atom/common/native_mate_converters/callback.h"
|
||||
#include "atom/common/native_mate_converters/value_converter.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "atom/common/options_switches.h"
|
||||
#include "base/threading/thread_task_runner_handle.h"
|
||||
#include "content/browser/renderer_host/render_widget_host_impl.h" // nogncheck
|
||||
#include "content/browser/renderer_host/render_widget_host_owner_delegate.h" // nogncheck
|
||||
#include "content/browser/web_contents/web_contents_impl.h" // nogncheck
|
||||
#include "content/public/browser/render_process_host.h"
|
||||
#include "content/public/browser/render_view_host.h"
|
||||
#include "shell/browser/api/electron_api_web_contents_view.h"
|
||||
#include "shell/browser/browser.h"
|
||||
#include "shell/browser/unresponsive_suppressor.h"
|
||||
#include "shell/browser/web_contents_preferences.h"
|
||||
#include "shell/browser/window_list.h"
|
||||
#include "shell/common/color_util.h"
|
||||
#include "shell/common/gin_helper/constructor.h"
|
||||
#include "shell/common/gin_helper/dictionary.h"
|
||||
#include "shell/common/gin_helper/object_template_builder.h"
|
||||
#include "shell/common/node_includes.h"
|
||||
#include "shell/common/options_switches.h"
|
||||
#include "gin/converter.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "ui/gl/gpu_switching_manager.h"
|
||||
|
||||
namespace electron {
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
BrowserWindow::BrowserWindow(gin::Arguments* args,
|
||||
const gin_helper::Dictionary& options)
|
||||
: TopLevelWindow(args->isolate(), options), weak_factory_(this) {
|
||||
BrowserWindow::BrowserWindow(v8::Isolate* isolate,
|
||||
v8::Local<v8::Object> wrapper,
|
||||
const mate::Dictionary& options)
|
||||
: TopLevelWindow(isolate, options), weak_factory_(this) {
|
||||
mate::Handle<class WebContents> web_contents;
|
||||
|
||||
// Use options.webPreferences in WebContents.
|
||||
v8::Isolate* isolate = args->isolate();
|
||||
gin_helper::Dictionary web_preferences =
|
||||
gin::Dictionary::CreateEmpty(isolate);
|
||||
mate::Dictionary web_preferences = mate::Dictionary::CreateEmpty(isolate);
|
||||
options.Get(options::kWebPreferences, &web_preferences);
|
||||
|
||||
// Copy the backgroundColor to webContents.
|
||||
@@ -43,42 +45,34 @@ BrowserWindow::BrowserWindow(gin::Arguments* args,
|
||||
if (options.Get(options::kBackgroundColor, &value))
|
||||
web_preferences.Set(options::kBackgroundColor, value);
|
||||
|
||||
// Copy the transparent setting to webContents
|
||||
v8::Local<v8::Value> transparent;
|
||||
if (options.Get("transparent", &transparent))
|
||||
web_preferences.Set("transparent", transparent);
|
||||
|
||||
// Copy the show setting to webContents, but only if we don't want to paint
|
||||
// when initially hidden
|
||||
bool paint_when_initially_hidden = true;
|
||||
options.Get("paintWhenInitiallyHidden", &paint_when_initially_hidden);
|
||||
if (!paint_when_initially_hidden) {
|
||||
bool show = true;
|
||||
options.Get(options::kShow, &show);
|
||||
web_preferences.Set(options::kShow, show);
|
||||
if (options.Get("webContents", &web_contents) && !web_contents.IsEmpty()) {
|
||||
// Set webPreferences from options if using an existing webContents.
|
||||
// These preferences will be used when the webContent launches new
|
||||
// render processes.
|
||||
auto* existing_preferences =
|
||||
WebContentsPreferences::From(web_contents->web_contents());
|
||||
base::DictionaryValue web_preferences_dict;
|
||||
if (mate::ConvertFromV8(isolate, web_preferences.GetHandle(),
|
||||
&web_preferences_dict)) {
|
||||
existing_preferences->Clear();
|
||||
existing_preferences->Merge(web_preferences_dict);
|
||||
}
|
||||
} else {
|
||||
// Creates the WebContents used by BrowserWindow.
|
||||
web_contents = WebContents::Create(isolate, web_preferences);
|
||||
}
|
||||
|
||||
// Copy the webContents option to webPreferences. This is only used internally
|
||||
// to implement nativeWindowOpen option.
|
||||
if (options.Get("webContents", &value)) {
|
||||
web_preferences.SetHidden("webContents", value);
|
||||
}
|
||||
|
||||
// Creates the WebContentsView.
|
||||
gin::Handle<WebContentsView> web_contents_view =
|
||||
WebContentsView::Create(isolate, web_preferences);
|
||||
DCHECK(web_contents_view.get());
|
||||
|
||||
// Save a reference of the WebContents.
|
||||
gin::Handle<WebContents> web_contents =
|
||||
web_contents_view->GetWebContents(isolate);
|
||||
web_contents_.Reset(isolate, web_contents.ToV8());
|
||||
api_web_contents_ = web_contents->GetWeakPtr();
|
||||
api_web_contents_->AddObserver(this);
|
||||
Observe(api_web_contents_->web_contents());
|
||||
|
||||
// Keep a copy of the options for later use.
|
||||
gin_helper::Dictionary(isolate, web_contents->GetWrapper())
|
||||
mate::Dictionary(isolate, web_contents->GetWrapper())
|
||||
.Set("browserWindowOptions", options);
|
||||
|
||||
// Associate with BrowserWindow.
|
||||
@@ -88,10 +82,7 @@ BrowserWindow::BrowserWindow(gin::Arguments* args,
|
||||
if (host)
|
||||
host->GetWidget()->AddInputEventObserver(this);
|
||||
|
||||
InitWithArgs(args);
|
||||
|
||||
// Install the content view after TopLevelWindow's JS code is initialized.
|
||||
SetContentView(gin::CreateHandle<View>(isolate, web_contents_view.get()));
|
||||
InitWith(isolate, wrapper);
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
OverrideNSWindowContentView(web_contents->managed_web_contents());
|
||||
@@ -113,9 +104,9 @@ BrowserWindow::~BrowserWindow() {
|
||||
|
||||
void BrowserWindow::OnInputEvent(const blink::WebInputEvent& event) {
|
||||
switch (event.GetType()) {
|
||||
case blink::WebInputEvent::Type::kGestureScrollBegin:
|
||||
case blink::WebInputEvent::Type::kGestureScrollUpdate:
|
||||
case blink::WebInputEvent::Type::kGestureScrollEnd:
|
||||
case blink::WebInputEvent::kGestureScrollBegin:
|
||||
case blink::WebInputEvent::kGestureScrollUpdate:
|
||||
case blink::WebInputEvent::kGestureScrollEnd:
|
||||
Emit("scroll-touch-edge");
|
||||
break;
|
||||
default:
|
||||
@@ -180,6 +171,17 @@ void BrowserWindow::OnRendererUnresponsive(content::RenderProcessHost*) {
|
||||
ScheduleUnresponsiveEvent(50);
|
||||
}
|
||||
|
||||
bool BrowserWindow::OnMessageReceived(const IPC::Message& message,
|
||||
content::RenderFrameHost* rfh) {
|
||||
bool handled = true;
|
||||
IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(BrowserWindow, message, rfh)
|
||||
IPC_MESSAGE_HANDLER(AtomFrameHostMsg_UpdateDraggableRegions,
|
||||
UpdateDraggableRegions)
|
||||
IPC_MESSAGE_UNHANDLED(handled = false)
|
||||
IPC_END_MESSAGE_MAP()
|
||||
return handled;
|
||||
}
|
||||
|
||||
void BrowserWindow::OnCloseContents() {
|
||||
// On some machines it may happen that the window gets destroyed for twice,
|
||||
// checking web_contents() can effectively guard against that.
|
||||
@@ -194,8 +196,8 @@ void BrowserWindow::OnCloseContents() {
|
||||
v8::Locker locker(isolate());
|
||||
v8::HandleScope handle_scope(isolate());
|
||||
for (v8::Local<v8::Value> value : child_windows_.Values(isolate())) {
|
||||
gin::Handle<BrowserWindow> child;
|
||||
if (gin::ConvertFromV8(isolate(), value, &child) && !child.IsEmpty())
|
||||
mate::Handle<BrowserWindow> child;
|
||||
if (mate::ConvertFromV8(isolate(), value, &child) && !child.IsEmpty())
|
||||
child->window()->CloseImmediately();
|
||||
}
|
||||
|
||||
@@ -210,41 +212,11 @@ void BrowserWindow::OnCloseContents() {
|
||||
window_unresponsive_closure_.Cancel();
|
||||
}
|
||||
|
||||
void BrowserWindow::OnRendererResponsive(content::RenderProcessHost*) {
|
||||
void BrowserWindow::OnRendererResponsive() {
|
||||
window_unresponsive_closure_.Cancel();
|
||||
Emit("responsive");
|
||||
}
|
||||
|
||||
void BrowserWindow::OnDraggableRegionsUpdated(
|
||||
const std::vector<mojom::DraggableRegionPtr>& regions) {
|
||||
UpdateDraggableRegions(regions);
|
||||
}
|
||||
|
||||
void BrowserWindow::OnSetContentBounds(const gfx::Rect& rect) {
|
||||
// window.resizeTo(...)
|
||||
// window.moveTo(...)
|
||||
window()->SetBounds(rect, false);
|
||||
}
|
||||
|
||||
void BrowserWindow::OnActivateContents() {
|
||||
// Hide the auto-hide menu when webContents is focused.
|
||||
#if !defined(OS_MACOSX)
|
||||
if (IsMenuBarAutoHide() && IsMenuBarVisible())
|
||||
window()->SetMenuBarVisibility(false);
|
||||
#endif
|
||||
}
|
||||
|
||||
void BrowserWindow::OnPageTitleUpdated(const base::string16& title,
|
||||
bool explicit_set) {
|
||||
// Change window title to page title.
|
||||
auto self = GetWeakPtr();
|
||||
if (!Emit("page-title-updated", title, explicit_set)) {
|
||||
// |this| might be deleted, or marked as destroyed by close().
|
||||
if (self && !IsDestroyed())
|
||||
SetTitle(base::UTF16ToUTF8(title));
|
||||
}
|
||||
}
|
||||
|
||||
void BrowserWindow::RequestPreferredWidth(int* width) {
|
||||
*width = web_contents()->GetPreferredSize().width();
|
||||
}
|
||||
@@ -266,10 +238,7 @@ void BrowserWindow::OnCloseButtonClicked(bool* prevent_default) {
|
||||
// Already closed by renderer
|
||||
return;
|
||||
|
||||
// Required to make beforeunload handler work.
|
||||
api_web_contents_->NotifyUserActivation();
|
||||
|
||||
if (web_contents()->NeedToFireBeforeUnloadOrUnload())
|
||||
if (web_contents()->NeedToFireBeforeUnload())
|
||||
web_contents()->DispatchBeforeUnload(false /* auto_cancel */);
|
||||
else
|
||||
web_contents()->Close();
|
||||
@@ -277,21 +246,27 @@ void BrowserWindow::OnCloseButtonClicked(bool* prevent_default) {
|
||||
|
||||
void BrowserWindow::OnWindowClosed() {
|
||||
Cleanup();
|
||||
// See TopLevelWindow::OnWindowClosed on why calling InvalidateWeakPtrs.
|
||||
weak_factory_.InvalidateWeakPtrs();
|
||||
TopLevelWindow::OnWindowClosed();
|
||||
}
|
||||
|
||||
void BrowserWindow::OnWindowBlur() {
|
||||
web_contents()->StoreFocus();
|
||||
#if defined(OS_MACOSX)
|
||||
auto* rwhv = web_contents()->GetRenderWidgetHostView();
|
||||
if (rwhv)
|
||||
rwhv->SetActive(false);
|
||||
#endif
|
||||
|
||||
TopLevelWindow::OnWindowBlur();
|
||||
}
|
||||
|
||||
void BrowserWindow::OnWindowFocus() {
|
||||
web_contents()->RestoreFocus();
|
||||
|
||||
#if !defined(OS_MACOSX)
|
||||
#if defined(OS_MACOSX)
|
||||
auto* rwhv = web_contents()->GetRenderWidgetHostView();
|
||||
if (rwhv)
|
||||
rwhv->SetActive(true);
|
||||
#else
|
||||
if (!api_web_contents_->IsDevToolsOpened())
|
||||
web_contents()->Focus();
|
||||
#endif
|
||||
@@ -299,18 +274,10 @@ void BrowserWindow::OnWindowFocus() {
|
||||
TopLevelWindow::OnWindowFocus();
|
||||
}
|
||||
|
||||
void BrowserWindow::OnWindowIsKeyChanged(bool is_key) {
|
||||
#if defined(OS_MACOSX)
|
||||
auto* rwhv = web_contents()->GetRenderWidgetHostView();
|
||||
if (rwhv)
|
||||
rwhv->SetActive(is_key);
|
||||
#endif
|
||||
}
|
||||
|
||||
void BrowserWindow::OnWindowResize() {
|
||||
#if defined(OS_MACOSX)
|
||||
if (!draggable_regions_.empty())
|
||||
UpdateDraggableRegions(draggable_regions_);
|
||||
UpdateDraggableRegions(nullptr, draggable_regions_);
|
||||
#endif
|
||||
TopLevelWindow::OnWindowResize();
|
||||
}
|
||||
@@ -358,28 +325,28 @@ void BrowserWindow::SetBrowserView(v8::Local<v8::Value> value) {
|
||||
TopLevelWindow::ResetBrowserViews();
|
||||
TopLevelWindow::AddBrowserView(value);
|
||||
#if defined(OS_MACOSX)
|
||||
UpdateDraggableRegions(draggable_regions_);
|
||||
UpdateDraggableRegions(nullptr, draggable_regions_);
|
||||
#endif
|
||||
}
|
||||
|
||||
void BrowserWindow::AddBrowserView(v8::Local<v8::Value> value) {
|
||||
TopLevelWindow::AddBrowserView(value);
|
||||
#if defined(OS_MACOSX)
|
||||
UpdateDraggableRegions(draggable_regions_);
|
||||
UpdateDraggableRegions(nullptr, draggable_regions_);
|
||||
#endif
|
||||
}
|
||||
|
||||
void BrowserWindow::RemoveBrowserView(v8::Local<v8::Value> value) {
|
||||
TopLevelWindow::RemoveBrowserView(value);
|
||||
#if defined(OS_MACOSX)
|
||||
UpdateDraggableRegions(draggable_regions_);
|
||||
UpdateDraggableRegions(nullptr, draggable_regions_);
|
||||
#endif
|
||||
}
|
||||
|
||||
void BrowserWindow::ResetBrowserViews() {
|
||||
TopLevelWindow::ResetBrowserViews();
|
||||
#if defined(OS_MACOSX)
|
||||
UpdateDraggableRegions(draggable_regions_);
|
||||
UpdateDraggableRegions(nullptr, draggable_regions_);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -421,13 +388,13 @@ v8::Local<v8::Value> BrowserWindow::GetWebContents(v8::Isolate* isolate) {
|
||||
|
||||
// Convert draggable regions in raw format to SkRegion format.
|
||||
std::unique_ptr<SkRegion> BrowserWindow::DraggableRegionsToSkRegion(
|
||||
const std::vector<mojom::DraggableRegionPtr>& regions) {
|
||||
const std::vector<DraggableRegion>& regions) {
|
||||
auto sk_region = std::make_unique<SkRegion>();
|
||||
for (const auto& region : regions) {
|
||||
for (const DraggableRegion& region : regions) {
|
||||
sk_region->op(
|
||||
{region->bounds.x(), region->bounds.y(), region->bounds.right(),
|
||||
region->bounds.bottom()},
|
||||
region->draggable ? SkRegion::kUnion_Op : SkRegion::kDifference_Op);
|
||||
region.bounds.x(), region.bounds.y(), region.bounds.right(),
|
||||
region.bounds.bottom(),
|
||||
region.draggable ? SkRegion::kUnion_Op : SkRegion::kDifference_Op);
|
||||
}
|
||||
return sk_region;
|
||||
}
|
||||
@@ -436,8 +403,8 @@ void BrowserWindow::ScheduleUnresponsiveEvent(int ms) {
|
||||
if (!window_unresponsive_closure_.IsCancelled())
|
||||
return;
|
||||
|
||||
window_unresponsive_closure_.Reset(base::BindRepeating(
|
||||
&BrowserWindow::NotifyWindowUnresponsive, GetWeakPtr()));
|
||||
window_unresponsive_closure_.Reset(
|
||||
base::Bind(&BrowserWindow::NotifyWindowUnresponsive, GetWeakPtr()));
|
||||
base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
|
||||
FROM_HERE, window_unresponsive_closure_.callback(),
|
||||
base::TimeDelta::FromMilliseconds(ms));
|
||||
@@ -462,21 +429,10 @@ void BrowserWindow::Cleanup() {
|
||||
Observe(nullptr);
|
||||
}
|
||||
|
||||
void BrowserWindow::OnWindowShow() {
|
||||
web_contents()->WasShown();
|
||||
TopLevelWindow::OnWindowShow();
|
||||
}
|
||||
|
||||
void BrowserWindow::OnWindowHide() {
|
||||
web_contents()->WasOccluded();
|
||||
TopLevelWindow::OnWindowHide();
|
||||
}
|
||||
|
||||
// static
|
||||
gin_helper::WrappableBase* BrowserWindow::New(gin_helper::ErrorThrower thrower,
|
||||
gin::Arguments* args) {
|
||||
mate::WrappableBase* BrowserWindow::New(mate::Arguments* args) {
|
||||
if (!Browser::Get()->is_ready()) {
|
||||
thrower.ThrowError("Cannot create BrowserWindow before app is ready");
|
||||
args->ThrowError("Cannot create BrowserWindow before app is ready");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -485,19 +441,19 @@ gin_helper::WrappableBase* BrowserWindow::New(gin_helper::ErrorThrower thrower,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
gin_helper::Dictionary options;
|
||||
mate::Dictionary options;
|
||||
if (!(args->Length() == 1 && args->GetNext(&options))) {
|
||||
options = gin::Dictionary::CreateEmpty(args->isolate());
|
||||
options = mate::Dictionary::CreateEmpty(args->isolate());
|
||||
}
|
||||
|
||||
return new BrowserWindow(args, options);
|
||||
return new BrowserWindow(args->isolate(), args->GetThis(), options);
|
||||
}
|
||||
|
||||
// static
|
||||
void BrowserWindow::BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype) {
|
||||
prototype->SetClassName(gin::StringToV8(isolate, "BrowserWindow"));
|
||||
gin_helper::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
||||
prototype->SetClassName(mate::StringToV8(isolate, "BrowserWindow"));
|
||||
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
||||
.SetMethod("focusOnWebView", &BrowserWindow::FocusOnWebView)
|
||||
.SetMethod("blurWebView", &BrowserWindow::BlurWebView)
|
||||
.SetMethod("isWebViewFocused", &BrowserWindow::IsWebViewFocused)
|
||||
@@ -516,24 +472,23 @@ v8::Local<v8::Value> BrowserWindow::From(v8::Isolate* isolate,
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace electron
|
||||
} // namespace atom
|
||||
|
||||
namespace {
|
||||
|
||||
using electron::api::BrowserWindow;
|
||||
using electron::api::TopLevelWindow;
|
||||
using atom::api::BrowserWindow;
|
||||
using atom::api::TopLevelWindow;
|
||||
|
||||
void Initialize(v8::Local<v8::Object> exports,
|
||||
v8::Local<v8::Value> unused,
|
||||
v8::Local<v8::Context> context,
|
||||
void* priv) {
|
||||
v8::Isolate* isolate = context->GetIsolate();
|
||||
gin_helper::Dictionary dict(isolate, exports);
|
||||
dict.Set("BrowserWindow",
|
||||
gin_helper::CreateConstructor<BrowserWindow>(
|
||||
isolate, base::BindRepeating(&BrowserWindow::New)));
|
||||
mate::Dictionary dict(isolate, exports);
|
||||
dict.Set("BrowserWindow", mate::CreateConstructor<BrowserWindow>(
|
||||
isolate, base::Bind(&BrowserWindow::New)));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(electron_browser_window, Initialize)
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_window, Initialize)
|
||||
@@ -2,19 +2,18 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef SHELL_BROWSER_API_ELECTRON_API_BROWSER_WINDOW_H_
|
||||
#define SHELL_BROWSER_API_ELECTRON_API_BROWSER_WINDOW_H_
|
||||
#ifndef ATOM_BROWSER_API_ATOM_API_BROWSER_WINDOW_H_
|
||||
#define ATOM_BROWSER_API_ATOM_API_BROWSER_WINDOW_H_
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "atom/browser/api/atom_api_top_level_window.h"
|
||||
#include "atom/browser/api/atom_api_web_contents.h"
|
||||
#include "base/cancelable_callback.h"
|
||||
#include "shell/browser/api/electron_api_top_level_window.h"
|
||||
#include "shell/browser/api/electron_api_web_contents.h"
|
||||
#include "shell/common/gin_helper/error_thrower.h"
|
||||
|
||||
namespace electron {
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
@@ -23,8 +22,7 @@ class BrowserWindow : public TopLevelWindow,
|
||||
public content::WebContentsObserver,
|
||||
public ExtendedWebContentsObserver {
|
||||
public:
|
||||
static gin_helper::WrappableBase* New(gin_helper::ErrorThrower thrower,
|
||||
gin::Arguments* args);
|
||||
static mate::WrappableBase* New(mate::Arguments* args);
|
||||
|
||||
static void BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype);
|
||||
@@ -38,7 +36,9 @@ class BrowserWindow : public TopLevelWindow,
|
||||
}
|
||||
|
||||
protected:
|
||||
BrowserWindow(gin::Arguments* args, const gin_helper::Dictionary& options);
|
||||
BrowserWindow(v8::Isolate* isolate,
|
||||
v8::Local<v8::Object> wrapper,
|
||||
const mate::Dictionary& options);
|
||||
~BrowserWindow() override;
|
||||
|
||||
// content::RenderWidgetHost::InputEventObserver:
|
||||
@@ -51,22 +51,16 @@ class BrowserWindow : public TopLevelWindow,
|
||||
void DidFirstVisuallyNonEmptyPaint() override;
|
||||
void BeforeUnloadDialogCancelled() override;
|
||||
void OnRendererUnresponsive(content::RenderProcessHost*) override;
|
||||
void OnRendererResponsive(
|
||||
content::RenderProcessHost* render_process_host) override;
|
||||
bool OnMessageReceived(const IPC::Message& message,
|
||||
content::RenderFrameHost* rfh) override;
|
||||
|
||||
// ExtendedWebContentsObserver:
|
||||
void OnCloseContents() override;
|
||||
void OnDraggableRegionsUpdated(
|
||||
const std::vector<mojom::DraggableRegionPtr>& regions) override;
|
||||
void OnSetContentBounds(const gfx::Rect& rect) override;
|
||||
void OnActivateContents() override;
|
||||
void OnPageTitleUpdated(const base::string16& title,
|
||||
bool explicit_set) override;
|
||||
void OnRendererResponsive() override;
|
||||
|
||||
// NativeWindowObserver:
|
||||
void RequestPreferredWidth(int* width) override;
|
||||
void OnCloseButtonClicked(bool* prevent_default) override;
|
||||
void OnWindowIsKeyChanged(bool is_key) override;
|
||||
|
||||
// TopLevelWindow:
|
||||
void OnWindowClosed() override;
|
||||
@@ -82,8 +76,6 @@ class BrowserWindow : public TopLevelWindow,
|
||||
void RemoveBrowserView(v8::Local<v8::Value> value) override;
|
||||
void ResetBrowserViews() override;
|
||||
void SetVibrancy(v8::Isolate* isolate, v8::Local<v8::Value> value) override;
|
||||
void OnWindowShow() override;
|
||||
void OnWindowHide() override;
|
||||
|
||||
// BrowserWindow APIs.
|
||||
void FocusOnWebView();
|
||||
@@ -99,12 +91,12 @@ class BrowserWindow : public TopLevelWindow,
|
||||
// Helpers.
|
||||
|
||||
// Called when the window needs to update its draggable region.
|
||||
void UpdateDraggableRegions(
|
||||
const std::vector<mojom::DraggableRegionPtr>& regions);
|
||||
void UpdateDraggableRegions(content::RenderFrameHost* rfh,
|
||||
const std::vector<DraggableRegion>& regions);
|
||||
|
||||
// Convert draggable regions in raw format to SkRegion format.
|
||||
std::unique_ptr<SkRegion> DraggableRegionsToSkRegion(
|
||||
const std::vector<mojom::DraggableRegionPtr>& regions);
|
||||
const std::vector<DraggableRegion>& regions);
|
||||
|
||||
// Schedule a notification unresponsive event.
|
||||
void ScheduleUnresponsiveEvent(int ms);
|
||||
@@ -120,7 +112,7 @@ class BrowserWindow : public TopLevelWindow,
|
||||
base::CancelableClosure window_unresponsive_closure_;
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
std::vector<mojom::DraggableRegionPtr> draggable_regions_;
|
||||
std::vector<DraggableRegion> draggable_regions_;
|
||||
#endif
|
||||
|
||||
v8::Global<v8::Value> web_contents_;
|
||||
@@ -133,6 +125,6 @@ class BrowserWindow : public TopLevelWindow,
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace electron
|
||||
} // namespace atom
|
||||
|
||||
#endif // SHELL_BROWSER_API_ELECTRON_API_BROWSER_WINDOW_H_
|
||||
#endif // ATOM_BROWSER_API_ATOM_API_BROWSER_WINDOW_H_
|
||||
@@ -2,17 +2,15 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "shell/browser/api/electron_api_browser_window.h"
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include "atom/browser/api/atom_api_browser_window.h"
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
#include "atom/browser/native_browser_view.h"
|
||||
#include "atom/browser/native_window_mac.h"
|
||||
#include "atom/browser/ui/inspectable_web_contents_view.h"
|
||||
#include "atom/common/draggable_region.h"
|
||||
#include "base/mac/scoped_nsobject.h"
|
||||
#include "shell/browser/native_browser_view.h"
|
||||
#include "shell/browser/native_window_mac.h"
|
||||
#include "shell/browser/ui/inspectable_web_contents_view.h"
|
||||
|
||||
@interface NSView (WebContentsView)
|
||||
- (void)setMouseDownCanMoveWindow:(BOOL)can_move;
|
||||
@@ -33,7 +31,7 @@
|
||||
|
||||
@end
|
||||
|
||||
namespace electron {
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
@@ -47,7 +45,7 @@ std::vector<gfx::Rect> CalculateNonDraggableRegions(
|
||||
int height) {
|
||||
std::vector<gfx::Rect> result;
|
||||
SkRegion non_draggable;
|
||||
non_draggable.op({0, 0, width, height}, SkRegion::kUnion_Op);
|
||||
non_draggable.op(0, 0, width, height, SkRegion::kUnion_Op);
|
||||
non_draggable.op(*draggable, SkRegion::kDifference_Op);
|
||||
for (SkRegion::Iterator it(non_draggable); !it.done(); it.next()) {
|
||||
result.push_back(gfx::SkIRectToRect(it.rect()));
|
||||
@@ -75,13 +73,11 @@ void BrowserWindow::OverrideNSWindowContentView(InspectableWebContents* iwc) {
|
||||
}
|
||||
|
||||
void BrowserWindow::UpdateDraggableRegions(
|
||||
const std::vector<mojom::DraggableRegionPtr>& regions) {
|
||||
content::RenderFrameHost* rfh,
|
||||
const std::vector<DraggableRegion>& regions) {
|
||||
if (window_->has_frame())
|
||||
return;
|
||||
|
||||
if (!web_contents())
|
||||
return;
|
||||
|
||||
// All ControlRegionViews should be added as children of the WebContentsView,
|
||||
// because WebContentsView will be removed and re-added when entering and
|
||||
// leaving fullscreen mode.
|
||||
@@ -104,11 +100,7 @@ void BrowserWindow::UpdateDraggableRegions(
|
||||
|
||||
// Draggable regions is implemented by having the whole web view draggable
|
||||
// (mouseDownCanMoveWindow) and overlaying regions that are not draggable.
|
||||
if (&draggable_regions_ != ®ions) {
|
||||
draggable_regions_.clear();
|
||||
for (const auto& r : regions)
|
||||
draggable_regions_.push_back(r.Clone());
|
||||
}
|
||||
draggable_regions_ = regions;
|
||||
std::vector<gfx::Rect> drag_exclude_rects;
|
||||
if (regions.empty()) {
|
||||
drag_exclude_rects.push_back(gfx::Rect(0, 0, webViewWidth, webViewHeight));
|
||||
@@ -119,7 +111,7 @@ void BrowserWindow::UpdateDraggableRegions(
|
||||
|
||||
auto browser_views = window_->browser_views();
|
||||
for (NativeBrowserView* view : browser_views) {
|
||||
view->UpdateDraggableRegions(drag_exclude_rects);
|
||||
(view)->UpdateDraggableRegions(drag_exclude_rects);
|
||||
}
|
||||
|
||||
// Create and add a ControlRegionView for each region that needs to be
|
||||
@@ -142,4 +134,4 @@ void BrowserWindow::UpdateDraggableRegions(
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace electron
|
||||
} // namespace atom
|
||||
@@ -2,16 +2,17 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "shell/browser/api/electron_api_browser_window.h"
|
||||
#include "atom/browser/api/atom_api_browser_window.h"
|
||||
|
||||
#include "shell/browser/native_window_views.h"
|
||||
#include "atom/browser/native_window_views.h"
|
||||
|
||||
namespace electron {
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
void BrowserWindow::UpdateDraggableRegions(
|
||||
const std::vector<mojom::DraggableRegionPtr>& regions) {
|
||||
content::RenderFrameHost* rfh,
|
||||
const std::vector<DraggableRegion>& regions) {
|
||||
if (window_->has_frame())
|
||||
return;
|
||||
static_cast<NativeWindowViews*>(window_.get())
|
||||
@@ -20,4 +21,4 @@ void BrowserWindow::UpdateDraggableRegions(
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace electron
|
||||
} // namespace atom
|
||||
146
atom/browser/api/atom_api_content_tracing.cc
Normal file
146
atom/browser/api/atom_api_content_tracing.cc
Normal file
@@ -0,0 +1,146 @@
|
||||
// Copyright (c) 2014 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include <set>
|
||||
#include <string>
|
||||
|
||||
#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 "atom/common/node_includes.h"
|
||||
#include "atom/common/promise_util.h"
|
||||
#include "base/bind.h"
|
||||
#include "base/files/file_util.h"
|
||||
#include "base/threading/thread_restrictions.h"
|
||||
#include "content/public/browser/tracing_controller.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
|
||||
using content::TracingController;
|
||||
|
||||
namespace mate {
|
||||
|
||||
template <>
|
||||
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)) {
|
||||
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;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace mate
|
||||
|
||||
namespace {
|
||||
|
||||
using CompletionCallback = base::Callback<void(const base::FilePath&)>;
|
||||
|
||||
scoped_refptr<TracingController::TraceDataEndpoint> GetTraceDataEndpoint(
|
||||
const base::FilePath& path,
|
||||
const CompletionCallback& callback) {
|
||||
base::FilePath result_file_path = path;
|
||||
|
||||
// base::CreateTemporaryFile prevents blocking so we need to allow it
|
||||
// for now since offloading this to a different sequence would require
|
||||
// changing the api shape
|
||||
base::ThreadRestrictions::ScopedAllowIO allow_io;
|
||||
if (result_file_path.empty() && !base::CreateTemporaryFile(&result_file_path))
|
||||
LOG(ERROR) << "Creating temporary file failed";
|
||||
|
||||
return TracingController::CreateFileEndpoint(
|
||||
result_file_path, base::Bind(callback, result_file_path));
|
||||
}
|
||||
|
||||
v8::Local<v8::Promise> StopRecording(v8::Isolate* isolate,
|
||||
const base::FilePath& path) {
|
||||
atom::util::Promise promise(isolate);
|
||||
v8::Local<v8::Promise> handle = promise.GetHandle();
|
||||
|
||||
// TODO(zcbenz): Remove the use of CopyablePromise when the
|
||||
// CreateFileEndpoint API accepts OnceCallback.
|
||||
TracingController::GetInstance()->StopTracing(GetTraceDataEndpoint(
|
||||
path, base::Bind(atom::util::CopyablePromise::ResolveCopyablePromise<
|
||||
const base::FilePath&>,
|
||||
atom::util::CopyablePromise(promise))));
|
||||
return handle;
|
||||
}
|
||||
|
||||
v8::Local<v8::Promise> GetCategories(v8::Isolate* isolate) {
|
||||
atom::util::Promise promise(isolate);
|
||||
v8::Local<v8::Promise> handle = promise.GetHandle();
|
||||
|
||||
// Note: This method always succeeds.
|
||||
TracingController::GetInstance()->GetCategories(base::BindOnce(
|
||||
atom::util::Promise::ResolvePromise<const std::set<std::string>&>,
|
||||
std::move(promise)));
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
v8::Local<v8::Promise> StartTracing(
|
||||
v8::Isolate* isolate,
|
||||
const base::trace_event::TraceConfig& trace_config) {
|
||||
atom::util::Promise promise(isolate);
|
||||
v8::Local<v8::Promise> handle = promise.GetHandle();
|
||||
|
||||
// Note: This method always succeeds.
|
||||
TracingController::GetInstance()->StartTracing(
|
||||
trace_config, base::BindOnce(atom::util::Promise::ResolveEmptyPromise,
|
||||
std::move(promise)));
|
||||
return handle;
|
||||
}
|
||||
|
||||
void OnTraceBufferUsageAvailable(atom::util::Promise promise,
|
||||
float percent_full,
|
||||
size_t approximate_count) {
|
||||
mate::Dictionary dict = mate::Dictionary::CreateEmpty(promise.isolate());
|
||||
dict.Set("percentage", percent_full);
|
||||
dict.Set("value", approximate_count);
|
||||
|
||||
promise.Resolve(dict.GetHandle());
|
||||
}
|
||||
|
||||
v8::Local<v8::Promise> GetTraceBufferUsage(v8::Isolate* isolate) {
|
||||
atom::util::Promise promise(isolate);
|
||||
v8::Local<v8::Promise> handle = promise.GetHandle();
|
||||
|
||||
// Note: This method always succeeds.
|
||||
TracingController::GetInstance()->GetTraceBufferUsage(
|
||||
base::BindOnce(&OnTraceBufferUsageAvailable, std::move(promise)));
|
||||
return handle;
|
||||
}
|
||||
|
||||
void Initialize(v8::Local<v8::Object> exports,
|
||||
v8::Local<v8::Value> unused,
|
||||
v8::Local<v8::Context> context,
|
||||
void* priv) {
|
||||
mate::Dictionary dict(context->GetIsolate(), exports);
|
||||
dict.SetMethod("getCategories", &GetCategories);
|
||||
dict.SetMethod("startRecording", &StartTracing);
|
||||
dict.SetMethod("stopRecording", &StopRecording);
|
||||
dict.SetMethod("getTraceBufferUsage", &GetTraceBufferUsage);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_content_tracing, Initialize)
|
||||
407
atom/browser/api/atom_api_cookies.cc
Normal file
407
atom/browser/api/atom_api_cookies.cc
Normal file
@@ -0,0 +1,407 @@
|
||||
// Copyright (c) 2015 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/browser/api/atom_api_cookies.h"
|
||||
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
#include "atom/browser/atom_browser_context.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"
|
||||
#include "base/task/post_task.h"
|
||||
#include "base/time/time.h"
|
||||
#include "base/values.h"
|
||||
#include "content/public/browser/browser_context.h"
|
||||
#include "content/public/browser/browser_task_traits.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "native_mate/object_template_builder.h"
|
||||
#include "net/cookies/canonical_cookie.h"
|
||||
#include "net/cookies/cookie_store.h"
|
||||
#include "net/cookies/cookie_util.h"
|
||||
#include "net/url_request/url_request_context.h"
|
||||
#include "net/url_request/url_request_context_getter.h"
|
||||
|
||||
using content::BrowserThread;
|
||||
|
||||
namespace mate {
|
||||
|
||||
template <>
|
||||
struct Converter<atom::api::Cookies::Error> {
|
||||
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
||||
atom::api::Cookies::Error val) {
|
||||
if (val == atom::api::Cookies::SUCCESS)
|
||||
return v8::Null(isolate);
|
||||
else
|
||||
return v8::Exception::Error(StringToV8(isolate, "Setting cookie failed"));
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Converter<net::CanonicalCookie> {
|
||||
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
||||
const net::CanonicalCookie& val) {
|
||||
mate::Dictionary dict(isolate, v8::Object::New(isolate));
|
||||
dict.Set("name", val.Name());
|
||||
dict.Set("value", val.Value());
|
||||
dict.Set("domain", val.Domain());
|
||||
dict.Set("hostOnly", net::cookie_util::DomainIsHostOnly(val.Domain()));
|
||||
dict.Set("path", val.Path());
|
||||
dict.Set("secure", val.IsSecure());
|
||||
dict.Set("httpOnly", val.IsHttpOnly());
|
||||
dict.Set("session", !val.IsPersistent());
|
||||
if (val.IsPersistent())
|
||||
dict.Set("expirationDate", val.ExpiryDate().ToDoubleT());
|
||||
return dict.GetHandle();
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Converter<network::mojom::CookieChangeCause> {
|
||||
static v8::Local<v8::Value> ToV8(
|
||||
v8::Isolate* isolate,
|
||||
const network::mojom::CookieChangeCause& val) {
|
||||
switch (val) {
|
||||
case network::mojom::CookieChangeCause::INSERTED:
|
||||
case network::mojom::CookieChangeCause::EXPLICIT:
|
||||
return mate::StringToV8(isolate, "explicit");
|
||||
case network::mojom::CookieChangeCause::OVERWRITE:
|
||||
return mate::StringToV8(isolate, "overwrite");
|
||||
case network::mojom::CookieChangeCause::EXPIRED:
|
||||
return mate::StringToV8(isolate, "expired");
|
||||
case network::mojom::CookieChangeCause::EVICTED:
|
||||
return mate::StringToV8(isolate, "evicted");
|
||||
case network::mojom::CookieChangeCause::EXPIRED_OVERWRITE:
|
||||
return mate::StringToV8(isolate, "expired-overwrite");
|
||||
default:
|
||||
return mate::StringToV8(isolate, "unknown");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace mate
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
namespace {
|
||||
|
||||
// Returns whether |domain| matches |filter|.
|
||||
bool MatchesDomain(std::string filter, const std::string& domain) {
|
||||
// Add a leading '.' character to the filter domain if it doesn't exist.
|
||||
if (net::cookie_util::DomainIsHostOnly(filter))
|
||||
filter.insert(0, ".");
|
||||
|
||||
std::string sub_domain(domain);
|
||||
// Strip any leading '.' character from the input cookie domain.
|
||||
if (!net::cookie_util::DomainIsHostOnly(sub_domain))
|
||||
sub_domain = sub_domain.substr(1);
|
||||
|
||||
// Now check whether the domain argument is a subdomain of the filter domain.
|
||||
for (sub_domain.insert(0, "."); sub_domain.length() >= filter.length();) {
|
||||
if (sub_domain == filter)
|
||||
return true;
|
||||
const size_t next_dot = sub_domain.find('.', 1); // Skip over leading dot.
|
||||
sub_domain.erase(0, next_dot);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Returns whether |cookie| matches |filter|.
|
||||
bool MatchesCookie(const base::DictionaryValue* filter,
|
||||
const net::CanonicalCookie& cookie) {
|
||||
std::string str;
|
||||
bool b;
|
||||
if (filter->GetString("name", &str) && str != cookie.Name())
|
||||
return false;
|
||||
if (filter->GetString("path", &str) && str != cookie.Path())
|
||||
return false;
|
||||
if (filter->GetString("domain", &str) && !MatchesDomain(str, cookie.Domain()))
|
||||
return false;
|
||||
if (filter->GetBoolean("secure", &b) && b != cookie.IsSecure())
|
||||
return false;
|
||||
if (filter->GetBoolean("session", &b) && b != !cookie.IsPersistent())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Helper to returns the CookieStore.
|
||||
inline net::CookieStore* GetCookieStore(
|
||||
scoped_refptr<net::URLRequestContextGetter> getter) {
|
||||
return getter->GetURLRequestContext()->cookie_store();
|
||||
}
|
||||
|
||||
// Remove cookies from |list| not matching |filter|, and pass it to |callback|.
|
||||
void FilterCookies(std::unique_ptr<base::DictionaryValue> filter,
|
||||
util::Promise promise,
|
||||
const net::CookieList& list,
|
||||
const net::CookieStatusList& excluded_list) {
|
||||
net::CookieList result;
|
||||
for (const auto& cookie : list) {
|
||||
if (MatchesCookie(filter.get(), cookie))
|
||||
result.push_back(cookie);
|
||||
}
|
||||
|
||||
base::PostTaskWithTraits(
|
||||
FROM_HERE, {BrowserThread::UI},
|
||||
base::BindOnce(util::Promise::ResolvePromise<const net::CookieList&>,
|
||||
std::move(promise), std::move(result)));
|
||||
}
|
||||
|
||||
// Receives cookies matching |filter| in IO thread.
|
||||
void GetCookiesOnIO(scoped_refptr<net::URLRequestContextGetter> getter,
|
||||
std::unique_ptr<base::DictionaryValue> filter,
|
||||
util::Promise promise) {
|
||||
std::string url;
|
||||
filter->GetString("url", &url);
|
||||
|
||||
auto filtered_callback =
|
||||
base::BindOnce(FilterCookies, std::move(filter), std::move(promise));
|
||||
|
||||
// Empty url will match all url cookies.
|
||||
if (url.empty())
|
||||
GetCookieStore(getter)->GetAllCookiesAsync(std::move(filtered_callback));
|
||||
else
|
||||
GetCookieStore(getter)->GetAllCookiesForURLAsync(
|
||||
GURL(url), std::move(filtered_callback));
|
||||
}
|
||||
|
||||
// Removes cookie with |url| and |name| in IO thread.
|
||||
void RemoveCookieOnIO(scoped_refptr<net::URLRequestContextGetter> getter,
|
||||
const GURL& url,
|
||||
const std::string& name,
|
||||
util::Promise promise) {
|
||||
net::CookieDeletionInfo cookie_info;
|
||||
cookie_info.url = url;
|
||||
cookie_info.name = name;
|
||||
GetCookieStore(getter)->DeleteAllMatchingInfoAsync(
|
||||
std::move(cookie_info),
|
||||
base::BindOnce(
|
||||
[](util::Promise promise, uint32_t num_deleted) {
|
||||
util::Promise::ResolveEmptyPromise(std::move(promise));
|
||||
},
|
||||
std::move(promise)));
|
||||
}
|
||||
|
||||
// Callback of SetCookie.
|
||||
void OnSetCookie(util::Promise promise,
|
||||
net::CanonicalCookie::CookieInclusionStatus status) {
|
||||
std::string errmsg;
|
||||
switch (status) {
|
||||
case net::CanonicalCookie::CookieInclusionStatus::EXCLUDE_HTTP_ONLY:
|
||||
errmsg = "Failed to create httponly cookie";
|
||||
break;
|
||||
case net::CanonicalCookie::CookieInclusionStatus::EXCLUDE_SECURE_ONLY:
|
||||
errmsg = "Cannot create a secure cookie from an insecure URL";
|
||||
break;
|
||||
case net::CanonicalCookie::CookieInclusionStatus::EXCLUDE_FAILURE_TO_STORE:
|
||||
errmsg = "Failed to parse cookie";
|
||||
break;
|
||||
case net::CanonicalCookie::CookieInclusionStatus::EXCLUDE_INVALID_DOMAIN:
|
||||
errmsg = "Failed to get cookie domain";
|
||||
break;
|
||||
case net::CanonicalCookie::CookieInclusionStatus::EXCLUDE_INVALID_PREFIX:
|
||||
errmsg = "Failed because the cookie violated prefix rules.";
|
||||
break;
|
||||
case net::CanonicalCookie::CookieInclusionStatus::
|
||||
EXCLUDE_NONCOOKIEABLE_SCHEME:
|
||||
errmsg = "Cannot set cookie for current scheme";
|
||||
break;
|
||||
case net::CanonicalCookie::CookieInclusionStatus::INCLUDE:
|
||||
errmsg = "";
|
||||
break;
|
||||
default:
|
||||
errmsg = "Setting cookie failed";
|
||||
break;
|
||||
}
|
||||
if (errmsg.empty()) {
|
||||
base::PostTaskWithTraits(
|
||||
FROM_HERE, {BrowserThread::UI},
|
||||
base::BindOnce(util::Promise::ResolveEmptyPromise, std::move(promise)));
|
||||
} else {
|
||||
base::PostTaskWithTraits(
|
||||
FROM_HERE, {BrowserThread::UI},
|
||||
base::BindOnce(util::Promise::RejectPromise, std::move(promise),
|
||||
std::move(errmsg)));
|
||||
}
|
||||
}
|
||||
|
||||
// Flushes cookie store in IO thread.
|
||||
void FlushCookieStoreOnIOThread(
|
||||
scoped_refptr<net::URLRequestContextGetter> getter,
|
||||
util::Promise promise) {
|
||||
GetCookieStore(getter)->FlushStore(
|
||||
base::BindOnce(util::Promise::ResolveEmptyPromise, std::move(promise)));
|
||||
}
|
||||
|
||||
// Sets cookie with |details| in IO thread.
|
||||
void SetCookieOnIO(scoped_refptr<net::URLRequestContextGetter> getter,
|
||||
std::unique_ptr<base::DictionaryValue> details,
|
||||
util::Promise promise) {
|
||||
std::string url_string, name, value, domain, path;
|
||||
bool secure = false;
|
||||
bool http_only = false;
|
||||
double creation_date;
|
||||
double expiration_date;
|
||||
double last_access_date;
|
||||
details->GetString("url", &url_string);
|
||||
details->GetString("name", &name);
|
||||
details->GetString("value", &value);
|
||||
details->GetString("domain", &domain);
|
||||
details->GetString("path", &path);
|
||||
details->GetBoolean("secure", &secure);
|
||||
details->GetBoolean("httpOnly", &http_only);
|
||||
|
||||
base::Time creation_time;
|
||||
if (details->GetDouble("creationDate", &creation_date)) {
|
||||
creation_time = (creation_date == 0)
|
||||
? base::Time::UnixEpoch()
|
||||
: base::Time::FromDoubleT(creation_date);
|
||||
}
|
||||
|
||||
base::Time expiration_time;
|
||||
if (details->GetDouble("expirationDate", &expiration_date)) {
|
||||
expiration_time = (expiration_date == 0)
|
||||
? base::Time::UnixEpoch()
|
||||
: base::Time::FromDoubleT(expiration_date);
|
||||
}
|
||||
|
||||
base::Time last_access_time;
|
||||
if (details->GetDouble("lastAccessDate", &last_access_date)) {
|
||||
last_access_time = (last_access_date == 0)
|
||||
? base::Time::UnixEpoch()
|
||||
: base::Time::FromDoubleT(last_access_date);
|
||||
}
|
||||
|
||||
GURL url(url_string);
|
||||
std::unique_ptr<net::CanonicalCookie> canonical_cookie(
|
||||
net::CanonicalCookie::CreateSanitizedCookie(
|
||||
url, name, value, domain, path, creation_time, expiration_time,
|
||||
last_access_time, secure, http_only,
|
||||
net::CookieSameSite::NO_RESTRICTION, net::COOKIE_PRIORITY_DEFAULT));
|
||||
auto completion_callback = base::BindOnce(OnSetCookie, std::move(promise));
|
||||
if (!canonical_cookie || !canonical_cookie->IsCanonical()) {
|
||||
std::move(completion_callback)
|
||||
.Run(net::CanonicalCookie::CookieInclusionStatus::
|
||||
EXCLUDE_FAILURE_TO_STORE);
|
||||
return;
|
||||
}
|
||||
if (!url.is_valid()) {
|
||||
std::move(completion_callback)
|
||||
.Run(net::CanonicalCookie::CookieInclusionStatus::
|
||||
EXCLUDE_INVALID_DOMAIN);
|
||||
return;
|
||||
}
|
||||
if (name.empty()) {
|
||||
std::move(completion_callback)
|
||||
.Run(net::CanonicalCookie::CookieInclusionStatus::
|
||||
EXCLUDE_FAILURE_TO_STORE);
|
||||
return;
|
||||
}
|
||||
net::CookieOptions options;
|
||||
if (http_only) {
|
||||
options.set_include_httponly();
|
||||
}
|
||||
GetCookieStore(getter)->SetCanonicalCookieAsync(
|
||||
std::move(canonical_cookie), url.scheme(), options,
|
||||
std::move(completion_callback));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
Cookies::Cookies(v8::Isolate* isolate, AtomBrowserContext* browser_context)
|
||||
: browser_context_(browser_context) {
|
||||
Init(isolate);
|
||||
cookie_change_subscription_ =
|
||||
browser_context_->cookie_change_notifier()->RegisterCookieChangeCallback(
|
||||
base::Bind(&Cookies::OnCookieChanged, base::Unretained(this)));
|
||||
}
|
||||
|
||||
Cookies::~Cookies() {}
|
||||
|
||||
v8::Local<v8::Promise> Cookies::Get(const base::DictionaryValue& filter) {
|
||||
util::Promise promise(isolate());
|
||||
v8::Local<v8::Promise> handle = promise.GetHandle();
|
||||
|
||||
auto copy = base::DictionaryValue::From(
|
||||
base::Value::ToUniquePtrValue(filter.Clone()));
|
||||
auto* getter = browser_context_->GetRequestContext();
|
||||
base::PostTaskWithTraits(
|
||||
FROM_HERE, {BrowserThread::IO},
|
||||
base::BindOnce(GetCookiesOnIO, base::RetainedRef(getter), std::move(copy),
|
||||
std::move(promise)));
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
v8::Local<v8::Promise> Cookies::Remove(const GURL& url,
|
||||
const std::string& name) {
|
||||
util::Promise promise(isolate());
|
||||
v8::Local<v8::Promise> handle = promise.GetHandle();
|
||||
|
||||
auto* getter = browser_context_->GetRequestContext();
|
||||
base::PostTaskWithTraits(
|
||||
FROM_HERE, {BrowserThread::IO},
|
||||
base::BindOnce(RemoveCookieOnIO, base::RetainedRef(getter), url, name,
|
||||
std::move(promise)));
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
v8::Local<v8::Promise> Cookies::Set(const base::DictionaryValue& details) {
|
||||
util::Promise promise(isolate());
|
||||
v8::Local<v8::Promise> handle = promise.GetHandle();
|
||||
|
||||
auto copy = base::DictionaryValue::From(
|
||||
base::Value::ToUniquePtrValue(details.Clone()));
|
||||
auto* getter = browser_context_->GetRequestContext();
|
||||
base::PostTaskWithTraits(
|
||||
FROM_HERE, {BrowserThread::IO},
|
||||
base::BindOnce(SetCookieOnIO, base::RetainedRef(getter), std::move(copy),
|
||||
std::move(promise)));
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
v8::Local<v8::Promise> Cookies::FlushStore() {
|
||||
util::Promise promise(isolate());
|
||||
v8::Local<v8::Promise> handle = promise.GetHandle();
|
||||
|
||||
auto* getter = browser_context_->GetRequestContext();
|
||||
base::PostTaskWithTraits(
|
||||
FROM_HERE, {BrowserThread::IO},
|
||||
base::BindOnce(FlushCookieStoreOnIOThread, base::RetainedRef(getter),
|
||||
std::move(promise)));
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
void Cookies::OnCookieChanged(const CookieDetails* details) {
|
||||
Emit("changed", *(details->cookie), details->cause, details->removed);
|
||||
}
|
||||
|
||||
// static
|
||||
mate::Handle<Cookies> Cookies::Create(v8::Isolate* isolate,
|
||||
AtomBrowserContext* browser_context) {
|
||||
return mate::CreateHandle(isolate, new Cookies(isolate, browser_context));
|
||||
}
|
||||
|
||||
// static
|
||||
void Cookies::BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype) {
|
||||
prototype->SetClassName(mate::StringToV8(isolate, "Cookies"));
|
||||
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
||||
.SetMethod("get", &Cookies::Get)
|
||||
.SetMethod("remove", &Cookies::Remove)
|
||||
.SetMethod("set", &Cookies::Set)
|
||||
.SetMethod("flushStore", &Cookies::FlushStore);
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
70
atom/browser/api/atom_api_cookies.h
Normal file
70
atom/browser/api/atom_api_cookies.h
Normal file
@@ -0,0 +1,70 @@
|
||||
// Copyright (c) 2015 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ATOM_BROWSER_API_ATOM_API_COOKIES_H_
|
||||
#define ATOM_BROWSER_API_ATOM_API_COOKIES_H_
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "atom/browser/api/trackable_object.h"
|
||||
#include "atom/browser/net/cookie_details.h"
|
||||
#include "atom/common/promise_util.h"
|
||||
#include "base/callback_list.h"
|
||||
#include "native_mate/handle.h"
|
||||
#include "net/cookies/canonical_cookie.h"
|
||||
|
||||
namespace base {
|
||||
class DictionaryValue;
|
||||
}
|
||||
|
||||
namespace net {
|
||||
class URLRequestContextGetter;
|
||||
}
|
||||
|
||||
namespace atom {
|
||||
|
||||
class AtomBrowserContext;
|
||||
|
||||
namespace api {
|
||||
|
||||
class Cookies : public mate::TrackableObject<Cookies> {
|
||||
public:
|
||||
enum Error {
|
||||
SUCCESS,
|
||||
FAILED,
|
||||
};
|
||||
|
||||
static mate::Handle<Cookies> Create(v8::Isolate* isolate,
|
||||
AtomBrowserContext* browser_context);
|
||||
|
||||
// mate::TrackableObject:
|
||||
static void BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype);
|
||||
|
||||
protected:
|
||||
Cookies(v8::Isolate* isolate, AtomBrowserContext* browser_context);
|
||||
~Cookies() override;
|
||||
|
||||
v8::Local<v8::Promise> Get(const base::DictionaryValue& filter);
|
||||
v8::Local<v8::Promise> Set(const base::DictionaryValue& details);
|
||||
v8::Local<v8::Promise> Remove(const GURL& url, const std::string& name);
|
||||
v8::Local<v8::Promise> FlushStore();
|
||||
|
||||
// CookieChangeNotifier subscription:
|
||||
void OnCookieChanged(const CookieDetails*);
|
||||
|
||||
private:
|
||||
std::unique_ptr<base::CallbackList<void(const CookieDetails*)>::Subscription>
|
||||
cookie_change_subscription_;
|
||||
scoped_refptr<AtomBrowserContext> browser_context_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(Cookies);
|
||||
};
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_API_ATOM_API_COOKIES_H_
|
||||
@@ -2,33 +2,33 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "shell/browser/api/electron_api_debugger.h"
|
||||
#include "atom/browser/api/atom_api_debugger.h"
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "atom/common/native_mate_converters/callback.h"
|
||||
#include "atom/common/native_mate_converters/value_converter.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "base/json/json_reader.h"
|
||||
#include "base/json/json_writer.h"
|
||||
#include "content/public/browser/devtools_agent_host.h"
|
||||
#include "content/public/browser/web_contents.h"
|
||||
#include "gin/object_template_builder.h"
|
||||
#include "gin/per_isolate_data.h"
|
||||
#include "shell/common/gin_converters/value_converter.h"
|
||||
#include "shell/common/node_includes.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
|
||||
using content::DevToolsAgentHost;
|
||||
|
||||
namespace electron {
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
gin::WrapperInfo Debugger::kWrapperInfo = {gin::kEmbedderNativeGin};
|
||||
|
||||
Debugger::Debugger(v8::Isolate* isolate, content::WebContents* web_contents)
|
||||
: content::WebContentsObserver(web_contents), web_contents_(web_contents) {}
|
||||
: content::WebContentsObserver(web_contents), web_contents_(web_contents) {
|
||||
Init(isolate);
|
||||
}
|
||||
|
||||
Debugger::~Debugger() = default;
|
||||
Debugger::~Debugger() {}
|
||||
|
||||
void Debugger::AgentHostClosed(DevToolsAgentHost* agent_host) {
|
||||
DCHECK(agent_host == agent_host_);
|
||||
@@ -38,19 +38,14 @@ void Debugger::AgentHostClosed(DevToolsAgentHost* agent_host) {
|
||||
}
|
||||
|
||||
void Debugger::DispatchProtocolMessage(DevToolsAgentHost* agent_host,
|
||||
base::span<const uint8_t> message) {
|
||||
const std::string& message) {
|
||||
DCHECK(agent_host == agent_host_);
|
||||
|
||||
v8::Isolate* isolate = v8::Isolate::GetCurrent();
|
||||
v8::Locker locker(isolate());
|
||||
v8::HandleScope handle_scope(isolate());
|
||||
|
||||
v8::Locker locker(isolate);
|
||||
v8::HandleScope handle_scope(isolate);
|
||||
|
||||
base::StringPiece message_str(reinterpret_cast<const char*>(message.data()),
|
||||
message.size());
|
||||
std::unique_ptr<base::Value> parsed_message =
|
||||
base::JSONReader::ReadDeprecated(message_str,
|
||||
base::JSON_REPLACE_INVALID_CHARACTERS);
|
||||
base::JSONReader::ReadDeprecated(message);
|
||||
if (!parsed_message || !parsed_message->is_dict())
|
||||
return;
|
||||
base::DictionaryValue* dict =
|
||||
@@ -60,19 +55,17 @@ void Debugger::DispatchProtocolMessage(DevToolsAgentHost* agent_host,
|
||||
std::string method;
|
||||
if (!dict->GetString("method", &method))
|
||||
return;
|
||||
std::string session_id;
|
||||
dict->GetString("sessionId", &session_id);
|
||||
base::DictionaryValue* params_value = nullptr;
|
||||
base::DictionaryValue params;
|
||||
if (dict->GetDictionary("params", ¶ms_value))
|
||||
params.Swap(params_value);
|
||||
Emit("message", method, params, session_id);
|
||||
Emit("message", method, params);
|
||||
} else {
|
||||
auto it = pending_requests_.find(id);
|
||||
if (it == pending_requests_.end())
|
||||
return;
|
||||
|
||||
gin_helper::Promise<base::DictionaryValue> promise = std::move(it->second);
|
||||
atom::util::Promise promise = std::move(it->second);
|
||||
pending_requests_.erase(it);
|
||||
|
||||
base::DictionaryValue* error = nullptr;
|
||||
@@ -100,24 +93,24 @@ void Debugger::RenderFrameHostChanged(content::RenderFrameHost* old_rfh,
|
||||
}
|
||||
}
|
||||
|
||||
void Debugger::Attach(gin::Arguments* args) {
|
||||
void Debugger::Attach(mate::Arguments* args) {
|
||||
std::string protocol_version;
|
||||
args->GetNext(&protocol_version);
|
||||
|
||||
if (agent_host_) {
|
||||
args->ThrowTypeError("Debugger is already attached to the target");
|
||||
args->ThrowError("Debugger is already attached to the target");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!protocol_version.empty() &&
|
||||
!DevToolsAgentHost::IsSupportedProtocolVersion(protocol_version)) {
|
||||
args->ThrowTypeError("Requested protocol version is not supported");
|
||||
args->ThrowError("Requested protocol version is not supported");
|
||||
return;
|
||||
}
|
||||
|
||||
agent_host_ = DevToolsAgentHost::GetOrCreateFor(web_contents_);
|
||||
if (!agent_host_) {
|
||||
args->ThrowTypeError("No target available");
|
||||
args->ThrowError("No target available");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -135,9 +128,8 @@ void Debugger::Detach() {
|
||||
AgentHostClosed(agent_host_.get());
|
||||
}
|
||||
|
||||
v8::Local<v8::Promise> Debugger::SendCommand(gin::Arguments* args) {
|
||||
v8::Isolate* isolate = args->isolate();
|
||||
gin_helper::Promise<base::DictionaryValue> promise(isolate);
|
||||
v8::Local<v8::Promise> Debugger::SendCommand(mate::Arguments* args) {
|
||||
atom::util::Promise promise(isolate());
|
||||
v8::Local<v8::Promise> handle = promise.GetHandle();
|
||||
|
||||
if (!agent_host_) {
|
||||
@@ -154,30 +146,18 @@ v8::Local<v8::Promise> Debugger::SendCommand(gin::Arguments* args) {
|
||||
base::DictionaryValue command_params;
|
||||
args->GetNext(&command_params);
|
||||
|
||||
std::string session_id;
|
||||
if (args->GetNext(&session_id) && session_id.empty()) {
|
||||
promise.RejectWithErrorMessage("Empty session id is not allowed");
|
||||
return handle;
|
||||
}
|
||||
|
||||
base::DictionaryValue request;
|
||||
int request_id = ++previous_request_id_;
|
||||
pending_requests_.emplace(request_id, std::move(promise));
|
||||
request.SetInteger("id", request_id);
|
||||
request.SetString("method", method);
|
||||
if (!command_params.empty()) {
|
||||
if (!command_params.empty())
|
||||
request.Set("params",
|
||||
base::Value::ToUniquePtrValue(command_params.Clone()));
|
||||
}
|
||||
|
||||
if (!session_id.empty()) {
|
||||
request.SetString("sessionId", session_id);
|
||||
}
|
||||
|
||||
std::string json_args;
|
||||
base::JSONWriter::Write(request, &json_args);
|
||||
agent_host_->DispatchProtocolMessage(
|
||||
this, base::as_bytes(base::make_span(json_args)));
|
||||
agent_host_->DispatchProtocolMessage(this, json_args);
|
||||
|
||||
return handle;
|
||||
}
|
||||
@@ -188,25 +168,41 @@ void Debugger::ClearPendingRequests() {
|
||||
}
|
||||
|
||||
// static
|
||||
gin::Handle<Debugger> Debugger::Create(v8::Isolate* isolate,
|
||||
content::WebContents* web_contents) {
|
||||
return gin::CreateHandle(isolate, new Debugger(isolate, web_contents));
|
||||
mate::Handle<Debugger> Debugger::Create(v8::Isolate* isolate,
|
||||
content::WebContents* web_contents) {
|
||||
return mate::CreateHandle(isolate, new Debugger(isolate, web_contents));
|
||||
}
|
||||
|
||||
gin::ObjectTemplateBuilder Debugger::GetObjectTemplateBuilder(
|
||||
v8::Isolate* isolate) {
|
||||
return gin_helper::EventEmitterMixin<Debugger>::GetObjectTemplateBuilder(
|
||||
isolate)
|
||||
// static
|
||||
void Debugger::BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype) {
|
||||
prototype->SetClassName(mate::StringToV8(isolate, "Debugger"));
|
||||
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
||||
.SetMethod("attach", &Debugger::Attach)
|
||||
.SetMethod("isAttached", &Debugger::IsAttached)
|
||||
.SetMethod("detach", &Debugger::Detach)
|
||||
.SetMethod("sendCommand", &Debugger::SendCommand);
|
||||
}
|
||||
|
||||
const char* Debugger::GetTypeName() {
|
||||
return "Debugger";
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace electron
|
||||
} // namespace atom
|
||||
|
||||
namespace {
|
||||
|
||||
using atom::api::Debugger;
|
||||
|
||||
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(isolate, exports)
|
||||
.Set("Debugger", Debugger::GetConstructor(isolate)
|
||||
->GetFunction(context)
|
||||
.ToLocalChecked());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_debugger, Initialize)
|
||||
@@ -2,44 +2,43 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef SHELL_BROWSER_API_ELECTRON_API_DEBUGGER_H_
|
||||
#define SHELL_BROWSER_API_ELECTRON_API_DEBUGGER_H_
|
||||
#ifndef ATOM_BROWSER_API_ATOM_API_DEBUGGER_H_
|
||||
#define ATOM_BROWSER_API_ATOM_API_DEBUGGER_H_
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
#include "atom/browser/api/trackable_object.h"
|
||||
#include "atom/common/promise_util.h"
|
||||
#include "base/callback.h"
|
||||
#include "base/values.h"
|
||||
#include "content/public/browser/devtools_agent_host_client.h"
|
||||
#include "content/public/browser/web_contents_observer.h"
|
||||
#include "gin/arguments.h"
|
||||
#include "gin/handle.h"
|
||||
#include "gin/wrappable.h"
|
||||
#include "shell/browser/event_emitter_mixin.h"
|
||||
#include "shell/common/gin_helper/promise.h"
|
||||
#include "native_mate/handle.h"
|
||||
|
||||
namespace content {
|
||||
class DevToolsAgentHost;
|
||||
class WebContents;
|
||||
} // namespace content
|
||||
|
||||
namespace electron {
|
||||
namespace mate {
|
||||
class Arguments;
|
||||
}
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
class Debugger : public gin::Wrappable<Debugger>,
|
||||
public gin_helper::EventEmitterMixin<Debugger>,
|
||||
class Debugger : public mate::TrackableObject<Debugger>,
|
||||
public content::DevToolsAgentHostClient,
|
||||
public content::WebContentsObserver {
|
||||
public:
|
||||
static gin::Handle<Debugger> Create(v8::Isolate* isolate,
|
||||
content::WebContents* web_contents);
|
||||
static mate::Handle<Debugger> Create(v8::Isolate* isolate,
|
||||
content::WebContents* web_contents);
|
||||
|
||||
// gin::Wrappable
|
||||
static gin::WrapperInfo kWrapperInfo;
|
||||
gin::ObjectTemplateBuilder GetObjectTemplateBuilder(
|
||||
v8::Isolate* isolate) override;
|
||||
const char* GetTypeName() override;
|
||||
// mate::TrackableObject:
|
||||
static void BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype);
|
||||
|
||||
protected:
|
||||
Debugger(v8::Isolate* isolate, content::WebContents* web_contents);
|
||||
@@ -48,20 +47,19 @@ class Debugger : public gin::Wrappable<Debugger>,
|
||||
// content::DevToolsAgentHostClient:
|
||||
void AgentHostClosed(content::DevToolsAgentHost* agent_host) override;
|
||||
void DispatchProtocolMessage(content::DevToolsAgentHost* agent_host,
|
||||
base::span<const uint8_t> message) override;
|
||||
const std::string& message) override;
|
||||
|
||||
// content::WebContentsObserver:
|
||||
void RenderFrameHostChanged(content::RenderFrameHost* old_rfh,
|
||||
content::RenderFrameHost* new_rfh) override;
|
||||
|
||||
private:
|
||||
using PendingRequestMap =
|
||||
std::map<int, gin_helper::Promise<base::DictionaryValue>>;
|
||||
using PendingRequestMap = std::map<int, atom::util::Promise>;
|
||||
|
||||
void Attach(gin::Arguments* args);
|
||||
void Attach(mate::Arguments* args);
|
||||
bool IsAttached();
|
||||
void Detach();
|
||||
v8::Local<v8::Promise> SendCommand(gin::Arguments* args);
|
||||
v8::Local<v8::Promise> SendCommand(mate::Arguments* args);
|
||||
void ClearPendingRequests();
|
||||
|
||||
content::WebContents* web_contents_; // Weak Reference.
|
||||
@@ -75,6 +73,6 @@ class Debugger : public gin::Wrappable<Debugger>,
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace electron
|
||||
} // namespace atom
|
||||
|
||||
#endif // SHELL_BROWSER_API_ELECTRON_API_DEBUGGER_H_
|
||||
#endif // ATOM_BROWSER_API_ATOM_API_DEBUGGER_H_
|
||||
@@ -2,24 +2,22 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "shell/browser/api/electron_api_desktop_capturer.h"
|
||||
#include "atom/browser/api/atom_api_desktop_capturer.h"
|
||||
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "atom/common/api/atom_api_native_image.h"
|
||||
#include "atom/common/native_mate_converters/gfx_converter.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "base/strings/string_number_conversions.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "base/threading/thread_restrictions.h"
|
||||
#include "chrome/browser/media/webrtc/desktop_media_list.h"
|
||||
#include "chrome/browser/media/webrtc/window_icon_util.h"
|
||||
#include "content/public/browser/desktop_capture.h"
|
||||
#include "gin/object_template_builder.h"
|
||||
#include "shell/common/api/electron_api_native_image.h"
|
||||
#include "shell/common/gin_converters/gfx_converter.h"
|
||||
#include "shell/common/gin_helper/dictionary.h"
|
||||
#include "shell/common/gin_helper/event_emitter_caller.h"
|
||||
#include "shell/common/node_includes.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "third_party/webrtc/modules/desktop_capture/desktop_capture_options.h"
|
||||
#include "third_party/webrtc/modules/desktop_capture/desktop_capturer.h"
|
||||
|
||||
@@ -29,44 +27,42 @@
|
||||
#include "ui/display/win/display_info.h"
|
||||
#endif // defined(OS_WIN)
|
||||
|
||||
namespace gin {
|
||||
namespace mate {
|
||||
|
||||
template <>
|
||||
struct Converter<electron::api::DesktopCapturer::Source> {
|
||||
struct Converter<atom::api::DesktopCapturer::Source> {
|
||||
static v8::Local<v8::Value> ToV8(
|
||||
v8::Isolate* isolate,
|
||||
const electron::api::DesktopCapturer::Source& source) {
|
||||
gin_helper::Dictionary dict = gin::Dictionary::CreateEmpty(isolate);
|
||||
const atom::api::DesktopCapturer::Source& source) {
|
||||
mate::Dictionary dict(isolate, v8::Object::New(isolate));
|
||||
content::DesktopMediaID id = source.media_list_source.id;
|
||||
dict.Set("name", base::UTF16ToUTF8(source.media_list_source.name));
|
||||
dict.Set("id", id.ToString());
|
||||
dict.Set("thumbnail",
|
||||
electron::api::NativeImage::Create(
|
||||
atom::api::NativeImage::Create(
|
||||
isolate, gfx::Image(source.media_list_source.thumbnail)));
|
||||
dict.Set("display_id", source.display_id);
|
||||
if (source.fetch_icon) {
|
||||
dict.Set(
|
||||
"appIcon",
|
||||
electron::api::NativeImage::Create(
|
||||
atom::api::NativeImage::Create(
|
||||
isolate, gfx::Image(GetWindowIcon(source.media_list_source.id))));
|
||||
} else {
|
||||
dict.Set("appIcon", nullptr);
|
||||
}
|
||||
return ConvertToV8(isolate, dict);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace gin
|
||||
} // namespace mate
|
||||
|
||||
namespace electron {
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
gin::WrapperInfo DesktopCapturer::kWrapperInfo = {gin::kEmbedderNativeGin};
|
||||
DesktopCapturer::DesktopCapturer(v8::Isolate* isolate) {
|
||||
Init(isolate);
|
||||
}
|
||||
|
||||
DesktopCapturer::DesktopCapturer(v8::Isolate* isolate) {}
|
||||
|
||||
DesktopCapturer::~DesktopCapturer() = default;
|
||||
DesktopCapturer::~DesktopCapturer() {}
|
||||
|
||||
void DesktopCapturer::StartHandling(bool capture_window,
|
||||
bool capture_screen,
|
||||
@@ -94,33 +90,47 @@ void DesktopCapturer::StartHandling(bool capture_window,
|
||||
// Initialize the source list.
|
||||
// Apply the new thumbnail size and restart capture.
|
||||
if (capture_window) {
|
||||
window_capturer_ = std::make_unique<NativeDesktopMediaList>(
|
||||
window_capturer_.reset(new NativeDesktopMediaList(
|
||||
content::DesktopMediaID::TYPE_WINDOW,
|
||||
content::desktop_capture::CreateWindowCapturer());
|
||||
content::desktop_capture::CreateWindowCapturer()));
|
||||
window_capturer_->SetThumbnailSize(thumbnail_size);
|
||||
window_capturer_->AddObserver(this);
|
||||
window_capturer_->Update(base::BindOnce(
|
||||
&DesktopCapturer::UpdateSourcesList, weak_ptr_factory_.GetWeakPtr(),
|
||||
window_capturer_.get()));
|
||||
window_capturer_->StartUpdating();
|
||||
}
|
||||
|
||||
if (capture_screen) {
|
||||
screen_capturer_ = std::make_unique<NativeDesktopMediaList>(
|
||||
screen_capturer_.reset(new NativeDesktopMediaList(
|
||||
content::DesktopMediaID::TYPE_SCREEN,
|
||||
content::desktop_capture::CreateScreenCapturer());
|
||||
content::desktop_capture::CreateScreenCapturer()));
|
||||
screen_capturer_->SetThumbnailSize(thumbnail_size);
|
||||
screen_capturer_->AddObserver(this);
|
||||
screen_capturer_->Update(base::BindOnce(
|
||||
&DesktopCapturer::UpdateSourcesList, weak_ptr_factory_.GetWeakPtr(),
|
||||
screen_capturer_.get()));
|
||||
screen_capturer_->StartUpdating();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DesktopCapturer::OnSourceAdded(DesktopMediaList* list, int index) {}
|
||||
|
||||
void DesktopCapturer::OnSourceRemoved(DesktopMediaList* list, int index) {}
|
||||
|
||||
void DesktopCapturer::OnSourceMoved(DesktopMediaList* list,
|
||||
int old_index,
|
||||
int new_index) {}
|
||||
|
||||
void DesktopCapturer::OnSourceNameChanged(DesktopMediaList* list, int index) {}
|
||||
|
||||
void DesktopCapturer::OnSourceThumbnailChanged(DesktopMediaList* list,
|
||||
int index) {}
|
||||
|
||||
void DesktopCapturer::OnSourceUnchanged(DesktopMediaList* list) {
|
||||
UpdateSourcesList(list);
|
||||
}
|
||||
|
||||
bool DesktopCapturer::ShouldScheduleNextRefresh(DesktopMediaList* list) {
|
||||
UpdateSourcesList(list);
|
||||
return false;
|
||||
}
|
||||
|
||||
void DesktopCapturer::UpdateSourcesList(DesktopMediaList* list) {
|
||||
if (capture_window_ &&
|
||||
list->GetMediaListType() == content::DesktopMediaID::TYPE_WINDOW) {
|
||||
@@ -157,10 +167,7 @@ void DesktopCapturer::UpdateSourcesList(DesktopMediaList* list) {
|
||||
// |media_list_sources|.
|
||||
if (!webrtc::DxgiDuplicatorController::Instance()->GetDeviceNames(
|
||||
&device_names)) {
|
||||
v8::Isolate* isolate = v8::Isolate::GetCurrent();
|
||||
v8::Locker locker(isolate);
|
||||
v8::HandleScope scope(isolate);
|
||||
gin_helper::CallMethod(this, "_onerror", "Failed to get sources.");
|
||||
Emit("error", "Failed to get sources.");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -189,32 +196,27 @@ void DesktopCapturer::UpdateSourcesList(DesktopMediaList* list) {
|
||||
std::back_inserter(captured_sources_));
|
||||
}
|
||||
|
||||
if (!capture_window_ && !capture_screen_) {
|
||||
v8::Isolate* isolate = v8::Isolate::GetCurrent();
|
||||
v8::Locker locker(isolate);
|
||||
v8::HandleScope scope(isolate);
|
||||
gin_helper::CallMethod(this, "_onfinished", captured_sources_);
|
||||
}
|
||||
if (!capture_window_ && !capture_screen_)
|
||||
Emit("finished", captured_sources_, fetch_window_icons_);
|
||||
}
|
||||
|
||||
// static
|
||||
gin::Handle<DesktopCapturer> DesktopCapturer::Create(v8::Isolate* isolate) {
|
||||
return gin::CreateHandle(isolate, new DesktopCapturer(isolate));
|
||||
mate::Handle<DesktopCapturer> DesktopCapturer::Create(v8::Isolate* isolate) {
|
||||
return mate::CreateHandle(isolate, new DesktopCapturer(isolate));
|
||||
}
|
||||
|
||||
gin::ObjectTemplateBuilder DesktopCapturer::GetObjectTemplateBuilder(
|
||||
v8::Isolate* isolate) {
|
||||
return gin::Wrappable<DesktopCapturer>::GetObjectTemplateBuilder(isolate)
|
||||
// static
|
||||
void DesktopCapturer::BuildPrototype(
|
||||
v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype) {
|
||||
prototype->SetClassName(mate::StringToV8(isolate, "DesktopCapturer"));
|
||||
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
||||
.SetMethod("startHandling", &DesktopCapturer::StartHandling);
|
||||
}
|
||||
|
||||
const char* DesktopCapturer::GetTypeName() {
|
||||
return "DesktopCapturer";
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace electron
|
||||
} // namespace atom
|
||||
|
||||
namespace {
|
||||
|
||||
@@ -222,11 +224,11 @@ void Initialize(v8::Local<v8::Object> exports,
|
||||
v8::Local<v8::Value> unused,
|
||||
v8::Local<v8::Context> context,
|
||||
void* priv) {
|
||||
gin_helper::Dictionary dict(context->GetIsolate(), exports);
|
||||
dict.SetMethod("createDesktopCapturer",
|
||||
&electron::api::DesktopCapturer::Create);
|
||||
v8::Isolate* isolate = context->GetIsolate();
|
||||
mate::Dictionary dict(isolate, exports);
|
||||
dict.SetMethod("createDesktopCapturer", &atom::api::DesktopCapturer::Create);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(electron_browser_desktop_capturer, Initialize)
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_desktop_capturer, Initialize)
|
||||
@@ -2,23 +2,23 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef SHELL_BROWSER_API_ELECTRON_API_DESKTOP_CAPTURER_H_
|
||||
#define SHELL_BROWSER_API_ELECTRON_API_DESKTOP_CAPTURER_H_
|
||||
#ifndef ATOM_BROWSER_API_ATOM_API_DESKTOP_CAPTURER_H_
|
||||
#define ATOM_BROWSER_API_ATOM_API_DESKTOP_CAPTURER_H_
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "atom/browser/api/trackable_object.h"
|
||||
#include "chrome/browser/media/webrtc/desktop_media_list_observer.h"
|
||||
#include "chrome/browser/media/webrtc/native_desktop_media_list.h"
|
||||
#include "gin/handle.h"
|
||||
#include "gin/wrappable.h"
|
||||
#include "native_mate/handle.h"
|
||||
|
||||
namespace electron {
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
class DesktopCapturer : public gin::Wrappable<DesktopCapturer>,
|
||||
class DesktopCapturer : public mate::TrackableObject<DesktopCapturer>,
|
||||
public DesktopMediaListObserver {
|
||||
public:
|
||||
struct Source {
|
||||
@@ -30,32 +30,30 @@ class DesktopCapturer : public gin::Wrappable<DesktopCapturer>,
|
||||
bool fetch_icon = false;
|
||||
};
|
||||
|
||||
static gin::Handle<DesktopCapturer> Create(v8::Isolate* isolate);
|
||||
static mate::Handle<DesktopCapturer> Create(v8::Isolate* isolate);
|
||||
|
||||
static void BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype);
|
||||
|
||||
void StartHandling(bool capture_window,
|
||||
bool capture_screen,
|
||||
const gfx::Size& thumbnail_size,
|
||||
bool fetch_window_icons);
|
||||
|
||||
// gin::Wrappable
|
||||
static gin::WrapperInfo kWrapperInfo;
|
||||
gin::ObjectTemplateBuilder GetObjectTemplateBuilder(
|
||||
v8::Isolate* isolate) override;
|
||||
const char* GetTypeName() override;
|
||||
|
||||
protected:
|
||||
explicit DesktopCapturer(v8::Isolate* isolate);
|
||||
~DesktopCapturer() override;
|
||||
|
||||
// DesktopMediaListObserver:
|
||||
void OnSourceAdded(DesktopMediaList* list, int index) override {}
|
||||
void OnSourceRemoved(DesktopMediaList* list, int index) override {}
|
||||
// DesktopMediaListObserver overrides.
|
||||
void OnSourceAdded(DesktopMediaList* list, int index) override;
|
||||
void OnSourceRemoved(DesktopMediaList* list, int index) override;
|
||||
void OnSourceMoved(DesktopMediaList* list,
|
||||
int old_index,
|
||||
int new_index) override {}
|
||||
void OnSourceNameChanged(DesktopMediaList* list, int index) override {}
|
||||
void OnSourceThumbnailChanged(DesktopMediaList* list, int index) override {}
|
||||
int new_index) override;
|
||||
void OnSourceNameChanged(DesktopMediaList* list, int index) override;
|
||||
void OnSourceThumbnailChanged(DesktopMediaList* list, int index) override;
|
||||
void OnSourceUnchanged(DesktopMediaList* list) override;
|
||||
bool ShouldScheduleNextRefresh(DesktopMediaList* list) override;
|
||||
|
||||
private:
|
||||
void UpdateSourcesList(DesktopMediaList* list);
|
||||
@@ -70,13 +68,11 @@ class DesktopCapturer : public gin::Wrappable<DesktopCapturer>,
|
||||
bool using_directx_capturer_ = false;
|
||||
#endif // defined(OS_WIN)
|
||||
|
||||
base::WeakPtrFactory<DesktopCapturer> weak_ptr_factory_{this};
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(DesktopCapturer);
|
||||
};
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace electron
|
||||
} // namespace atom
|
||||
|
||||
#endif // SHELL_BROWSER_API_ELECTRON_API_DESKTOP_CAPTURER_H_
|
||||
#endif // ATOM_BROWSER_API_ATOM_API_DESKTOP_CAPTURER_H_
|
||||
132
atom/browser/api/atom_api_dialog.cc
Normal file
132
atom/browser/api/atom_api_dialog.cc
Normal file
@@ -0,0 +1,132 @@
|
||||
// Copyright (c) 2013 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "atom/browser/api/atom_api_browser_window.h"
|
||||
#include "atom/browser/native_window.h"
|
||||
#include "atom/browser/ui/certificate_trust.h"
|
||||
#include "atom/browser/ui/file_dialog.h"
|
||||
#include "atom/browser/ui/message_box.h"
|
||||
#include "atom/common/native_mate_converters/callback.h"
|
||||
#include "atom/common/native_mate_converters/file_dialog_converter.h"
|
||||
#include "atom/common/native_mate_converters/file_path_converter.h"
|
||||
#include "atom/common/native_mate_converters/image_converter.h"
|
||||
#include "atom/common/native_mate_converters/net_converter.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "atom/common/promise_util.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
|
||||
namespace {
|
||||
|
||||
int ShowMessageBoxSync(int type,
|
||||
const std::vector<std::string>& buttons,
|
||||
int default_id,
|
||||
int cancel_id,
|
||||
int options,
|
||||
const std::string& title,
|
||||
const std::string& message,
|
||||
const std::string& detail,
|
||||
const std::string& checkbox_label,
|
||||
bool checkbox_checked,
|
||||
const gfx::ImageSkia& icon,
|
||||
atom::NativeWindow* window) {
|
||||
return atom::ShowMessageBoxSync(
|
||||
window, static_cast<atom::MessageBoxType>(type), buttons, default_id,
|
||||
cancel_id, options, title, message, detail, icon);
|
||||
}
|
||||
|
||||
void ResolvePromiseObject(atom::util::Promise promise,
|
||||
int result,
|
||||
bool checkbox_checked) {
|
||||
mate::Dictionary dict = mate::Dictionary::CreateEmpty(promise.isolate());
|
||||
|
||||
dict.Set("response", result);
|
||||
dict.Set("checkboxChecked", checkbox_checked);
|
||||
|
||||
promise.Resolve(dict.GetHandle());
|
||||
}
|
||||
|
||||
v8::Local<v8::Promise> ShowMessageBox(int type,
|
||||
const std::vector<std::string>& buttons,
|
||||
int default_id,
|
||||
int cancel_id,
|
||||
int options,
|
||||
const std::string& title,
|
||||
const std::string& message,
|
||||
const std::string& detail,
|
||||
const std::string& checkbox_label,
|
||||
bool checkbox_checked,
|
||||
const gfx::ImageSkia& icon,
|
||||
atom::NativeWindow* window,
|
||||
mate::Arguments* args) {
|
||||
v8::Isolate* isolate = args->isolate();
|
||||
atom::util::Promise promise(isolate);
|
||||
v8::Local<v8::Promise> handle = promise.GetHandle();
|
||||
|
||||
atom::ShowMessageBox(
|
||||
window, static_cast<atom::MessageBoxType>(type), buttons, default_id,
|
||||
cancel_id, options, title, message, detail, checkbox_label,
|
||||
checkbox_checked, icon,
|
||||
base::BindOnce(&ResolvePromiseObject, std::move(promise)));
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
void ShowOpenDialogSync(const file_dialog::DialogSettings& settings,
|
||||
mate::Arguments* args) {
|
||||
std::vector<base::FilePath> paths;
|
||||
if (file_dialog::ShowOpenDialogSync(settings, &paths))
|
||||
args->Return(paths);
|
||||
}
|
||||
|
||||
v8::Local<v8::Promise> ShowOpenDialog(
|
||||
const file_dialog::DialogSettings& settings,
|
||||
mate::Arguments* args) {
|
||||
atom::util::Promise promise(args->isolate());
|
||||
v8::Local<v8::Promise> handle = promise.GetHandle();
|
||||
file_dialog::ShowOpenDialog(settings, std::move(promise));
|
||||
return handle;
|
||||
}
|
||||
|
||||
void ShowSaveDialogSync(const file_dialog::DialogSettings& settings,
|
||||
mate::Arguments* args) {
|
||||
base::FilePath path;
|
||||
if (file_dialog::ShowSaveDialogSync(settings, &path))
|
||||
args->Return(path);
|
||||
}
|
||||
|
||||
v8::Local<v8::Promise> ShowSaveDialog(
|
||||
const file_dialog::DialogSettings& settings,
|
||||
mate::Arguments* args) {
|
||||
atom::util::Promise promise(args->isolate());
|
||||
v8::Local<v8::Promise> handle = promise.GetHandle();
|
||||
|
||||
file_dialog::ShowSaveDialog(settings, std::move(promise));
|
||||
return handle;
|
||||
}
|
||||
|
||||
void Initialize(v8::Local<v8::Object> exports,
|
||||
v8::Local<v8::Value> unused,
|
||||
v8::Local<v8::Context> context,
|
||||
void* priv) {
|
||||
mate::Dictionary dict(context->GetIsolate(), exports);
|
||||
dict.SetMethod("showMessageBoxSync", &ShowMessageBoxSync);
|
||||
dict.SetMethod("showMessageBox", &ShowMessageBox);
|
||||
dict.SetMethod("showErrorBox", &atom::ShowErrorBox);
|
||||
dict.SetMethod("showOpenDialogSync", &ShowOpenDialogSync);
|
||||
dict.SetMethod("showOpenDialog", &ShowOpenDialog);
|
||||
dict.SetMethod("showSaveDialogSync", &ShowSaveDialogSync);
|
||||
dict.SetMethod("showSaveDialog", &ShowSaveDialog);
|
||||
#if defined(OS_MACOSX) || defined(OS_WIN)
|
||||
dict.SetMethod("showCertificateTrustDialog",
|
||||
&certificate_trust::ShowCertificateTrust);
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_dialog, Initialize)
|
||||
@@ -2,23 +2,22 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "shell/browser/api/electron_api_download_item.h"
|
||||
#include "atom/browser/api/atom_api_download_item.h"
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
|
||||
#include "atom/browser/atom_browser_main_parts.h"
|
||||
#include "atom/common/native_mate_converters/callback.h"
|
||||
#include "atom/common/native_mate_converters/file_dialog_converter.h"
|
||||
#include "atom/common/native_mate_converters/file_path_converter.h"
|
||||
#include "atom/common/native_mate_converters/gurl_converter.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "base/threading/thread_task_runner_handle.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "net/base/filename_util.h"
|
||||
#include "shell/browser/electron_browser_main_parts.h"
|
||||
#include "shell/common/gin_converters/file_dialog_converter.h"
|
||||
#include "shell/common/gin_converters/file_path_converter.h"
|
||||
#include "shell/common/gin_converters/gurl_converter.h"
|
||||
#include "shell/common/gin_helper/dictionary.h"
|
||||
#include "shell/common/gin_helper/object_template_builder.h"
|
||||
#include "shell/common/node_includes.h"
|
||||
|
||||
namespace gin {
|
||||
namespace mate {
|
||||
|
||||
template <>
|
||||
struct Converter<download::DownloadItem::DownloadState> {
|
||||
@@ -46,49 +45,24 @@ struct Converter<download::DownloadItem::DownloadState> {
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace gin
|
||||
} // namespace mate
|
||||
|
||||
namespace electron {
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
namespace {
|
||||
|
||||
// Ordinarily base::SupportsUserData only supports strong links, where the
|
||||
// thing to which the user data is attached owns the user data. But we can't
|
||||
// make the api::DownloadItem owned by the DownloadItem, since it's owned by
|
||||
// V8. So this makes a weak link. The lifetimes of download::DownloadItem and
|
||||
// api::DownloadItem are fully independent, and either one may be destroyed
|
||||
// before the other.
|
||||
struct UserDataLink : base::SupportsUserData::Data {
|
||||
explicit UserDataLink(base::WeakPtr<DownloadItem> item)
|
||||
: download_item(item) {}
|
||||
|
||||
base::WeakPtr<DownloadItem> download_item;
|
||||
};
|
||||
|
||||
const void* kElectronApiDownloadItemKey = &kElectronApiDownloadItemKey;
|
||||
std::map<uint32_t, v8::Global<v8::Object>> g_download_item_objects;
|
||||
|
||||
} // namespace
|
||||
|
||||
gin::WrapperInfo DownloadItem::kWrapperInfo = {gin::kEmbedderNativeGin};
|
||||
|
||||
// static
|
||||
DownloadItem* DownloadItem::FromDownloadItem(
|
||||
download::DownloadItem* download_item) {
|
||||
// ^- say that 7 times fast in a row
|
||||
UserDataLink* data = static_cast<UserDataLink*>(
|
||||
download_item->GetUserData(kElectronApiDownloadItemKey));
|
||||
return data ? data->download_item.get() : nullptr;
|
||||
}
|
||||
|
||||
DownloadItem::DownloadItem(v8::Isolate* isolate,
|
||||
download::DownloadItem* download_item)
|
||||
: download_item_(download_item) {
|
||||
download_item_->AddObserver(this);
|
||||
download_item_->SetUserData(
|
||||
kElectronApiDownloadItemKey,
|
||||
std::make_unique<UserDataLink>(weak_factory_.GetWeakPtr()));
|
||||
Init(isolate);
|
||||
AttachAsUserData(download_item);
|
||||
}
|
||||
|
||||
DownloadItem::~DownloadItem() {
|
||||
@@ -97,23 +71,17 @@ DownloadItem::~DownloadItem() {
|
||||
download_item_->RemoveObserver(this);
|
||||
download_item_->Remove();
|
||||
}
|
||||
}
|
||||
|
||||
bool DownloadItem::CheckAlive() const {
|
||||
if (!download_item_) {
|
||||
gin_helper::ErrorThrower(v8::Isolate::GetCurrent())
|
||||
.ThrowError("DownloadItem used after being destroyed");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
// Remove from the global map.
|
||||
g_download_item_objects.erase(weak_map_id());
|
||||
}
|
||||
|
||||
void DownloadItem::OnDownloadUpdated(download::DownloadItem* item) {
|
||||
if (!CheckAlive())
|
||||
return;
|
||||
if (download_item_->IsDone()) {
|
||||
Emit("done", item->GetState());
|
||||
Unpin();
|
||||
// Destroy the item once item is downloaded.
|
||||
base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
|
||||
GetDestroyClosure());
|
||||
} else {
|
||||
Emit("updated", item->GetState());
|
||||
}
|
||||
@@ -121,66 +89,47 @@ void DownloadItem::OnDownloadUpdated(download::DownloadItem* item) {
|
||||
|
||||
void DownloadItem::OnDownloadDestroyed(download::DownloadItem* download_item) {
|
||||
download_item_ = nullptr;
|
||||
Unpin();
|
||||
// Destroy the native class immediately when downloadItem is destroyed.
|
||||
delete this;
|
||||
}
|
||||
|
||||
void DownloadItem::Pause() {
|
||||
if (!CheckAlive())
|
||||
return;
|
||||
download_item_->Pause();
|
||||
}
|
||||
|
||||
bool DownloadItem::IsPaused() const {
|
||||
if (!CheckAlive())
|
||||
return false;
|
||||
return download_item_->IsPaused();
|
||||
}
|
||||
|
||||
void DownloadItem::Resume() {
|
||||
if (!CheckAlive())
|
||||
return;
|
||||
download_item_->Resume(true /* user_gesture */);
|
||||
}
|
||||
|
||||
bool DownloadItem::CanResume() const {
|
||||
if (!CheckAlive())
|
||||
return false;
|
||||
return download_item_->CanResume();
|
||||
}
|
||||
|
||||
void DownloadItem::Cancel() {
|
||||
if (!CheckAlive())
|
||||
return;
|
||||
download_item_->Cancel(true);
|
||||
}
|
||||
|
||||
int64_t DownloadItem::GetReceivedBytes() const {
|
||||
if (!CheckAlive())
|
||||
return 0;
|
||||
return download_item_->GetReceivedBytes();
|
||||
}
|
||||
|
||||
int64_t DownloadItem::GetTotalBytes() const {
|
||||
if (!CheckAlive())
|
||||
return 0;
|
||||
return download_item_->GetTotalBytes();
|
||||
}
|
||||
|
||||
std::string DownloadItem::GetMimeType() const {
|
||||
if (!CheckAlive())
|
||||
return "";
|
||||
return download_item_->GetMimeType();
|
||||
}
|
||||
|
||||
bool DownloadItem::HasUserGesture() const {
|
||||
if (!CheckAlive())
|
||||
return false;
|
||||
return download_item_->HasUserGesture();
|
||||
}
|
||||
|
||||
std::string DownloadItem::GetFilename() const {
|
||||
if (!CheckAlive())
|
||||
return "";
|
||||
return base::UTF16ToUTF8(
|
||||
net::GenerateFileName(GetURL(), GetContentDisposition(), std::string(),
|
||||
download_item_->GetSuggestedFilename(),
|
||||
@@ -189,32 +138,22 @@ std::string DownloadItem::GetFilename() const {
|
||||
}
|
||||
|
||||
std::string DownloadItem::GetContentDisposition() const {
|
||||
if (!CheckAlive())
|
||||
return "";
|
||||
return download_item_->GetContentDisposition();
|
||||
}
|
||||
|
||||
const GURL& DownloadItem::GetURL() const {
|
||||
if (!CheckAlive())
|
||||
return GURL::EmptyGURL();
|
||||
return download_item_->GetURL();
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> DownloadItem::GetURLChain(v8::Isolate* isolate) const {
|
||||
if (!CheckAlive())
|
||||
return v8::Local<v8::Value>();
|
||||
return gin::ConvertToV8(isolate, download_item_->GetUrlChain());
|
||||
const std::vector<GURL>& DownloadItem::GetURLChain() const {
|
||||
return download_item_->GetUrlChain();
|
||||
}
|
||||
|
||||
download::DownloadItem::DownloadState DownloadItem::GetState() const {
|
||||
if (!CheckAlive())
|
||||
return download::DownloadItem::IN_PROGRESS;
|
||||
return download_item_->GetState();
|
||||
}
|
||||
|
||||
bool DownloadItem::IsDone() const {
|
||||
if (!CheckAlive())
|
||||
return false;
|
||||
return download_item_->IsDone();
|
||||
}
|
||||
|
||||
@@ -236,28 +175,23 @@ void DownloadItem::SetSaveDialogOptions(
|
||||
}
|
||||
|
||||
std::string DownloadItem::GetLastModifiedTime() const {
|
||||
if (!CheckAlive())
|
||||
return "";
|
||||
return download_item_->GetLastModifiedTime();
|
||||
}
|
||||
|
||||
std::string DownloadItem::GetETag() const {
|
||||
if (!CheckAlive())
|
||||
return "";
|
||||
return download_item_->GetETag();
|
||||
}
|
||||
|
||||
double DownloadItem::GetStartTime() const {
|
||||
if (!CheckAlive())
|
||||
return 0;
|
||||
return download_item_->GetStartTime().ToDoubleT();
|
||||
}
|
||||
|
||||
// static
|
||||
gin::ObjectTemplateBuilder DownloadItem::GetObjectTemplateBuilder(
|
||||
v8::Isolate* isolate) {
|
||||
return gin_helper::EventEmitterMixin<DownloadItem>::GetObjectTemplateBuilder(
|
||||
isolate)
|
||||
void DownloadItem::BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype) {
|
||||
prototype->SetClassName(mate::StringToV8(isolate, "DownloadItem"));
|
||||
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
||||
.MakeDestroyable()
|
||||
.SetMethod("pause", &DownloadItem::Pause)
|
||||
.SetMethod("isPaused", &DownloadItem::IsPaused)
|
||||
.SetMethod("resume", &DownloadItem::Resume)
|
||||
@@ -275,8 +209,6 @@ gin::ObjectTemplateBuilder DownloadItem::GetObjectTemplateBuilder(
|
||||
.SetMethod("isDone", &DownloadItem::IsDone)
|
||||
.SetMethod("setSavePath", &DownloadItem::SetSavePath)
|
||||
.SetMethod("getSavePath", &DownloadItem::GetSavePath)
|
||||
.SetProperty("savePath", &DownloadItem::GetSavePath,
|
||||
&DownloadItem::SetSavePath)
|
||||
.SetMethod("setSaveDialogOptions", &DownloadItem::SetSaveDialogOptions)
|
||||
.SetMethod("getSaveDialogOptions", &DownloadItem::GetSaveDialogOptions)
|
||||
.SetMethod("getLastModifiedTime", &DownloadItem::GetLastModifiedTime)
|
||||
@@ -284,25 +216,38 @@ gin::ObjectTemplateBuilder DownloadItem::GetObjectTemplateBuilder(
|
||||
.SetMethod("getStartTime", &DownloadItem::GetStartTime);
|
||||
}
|
||||
|
||||
const char* DownloadItem::GetTypeName() {
|
||||
return "DownloadItem";
|
||||
}
|
||||
|
||||
// static
|
||||
gin::Handle<DownloadItem> DownloadItem::FromOrCreate(
|
||||
v8::Isolate* isolate,
|
||||
download::DownloadItem* item) {
|
||||
DownloadItem* existing = FromDownloadItem(item);
|
||||
mate::Handle<DownloadItem> DownloadItem::Create(v8::Isolate* isolate,
|
||||
download::DownloadItem* item) {
|
||||
auto* existing = TrackableObject::FromWrappedClass(isolate, item);
|
||||
if (existing)
|
||||
return gin::CreateHandle(isolate, existing);
|
||||
return mate::CreateHandle(isolate, static_cast<DownloadItem*>(existing));
|
||||
|
||||
auto handle = gin::CreateHandle(isolate, new DownloadItem(isolate, item));
|
||||
|
||||
handle->Pin(isolate);
|
||||
auto handle = mate::CreateHandle(isolate, new DownloadItem(isolate, item));
|
||||
|
||||
// Reference this object in case it got garbage collected.
|
||||
g_download_item_objects[handle->weak_map_id()] =
|
||||
v8::Global<v8::Object>(isolate, handle.ToV8());
|
||||
return handle;
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace electron
|
||||
} // namespace atom
|
||||
|
||||
namespace {
|
||||
|
||||
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(isolate, exports)
|
||||
.Set("DownloadItem", atom::api::DownloadItem::GetConstructor(isolate)
|
||||
->GetFunction(context)
|
||||
.ToLocalChecked());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_download_item, Initialize)
|
||||
@@ -2,58 +2,32 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef SHELL_BROWSER_API_ELECTRON_API_DOWNLOAD_ITEM_H_
|
||||
#define SHELL_BROWSER_API_ELECTRON_API_DOWNLOAD_ITEM_H_
|
||||
#ifndef ATOM_BROWSER_API_ATOM_API_DOWNLOAD_ITEM_H_
|
||||
#define ATOM_BROWSER_API_ATOM_API_DOWNLOAD_ITEM_H_
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "atom/browser/api/trackable_object.h"
|
||||
#include "atom/browser/ui/file_dialog.h"
|
||||
#include "base/files/file_path.h"
|
||||
#include "base/memory/weak_ptr.h"
|
||||
#include "components/download/public/common/download_item.h"
|
||||
#include "gin/handle.h"
|
||||
#include "gin/wrappable.h"
|
||||
#include "shell/browser/event_emitter_mixin.h"
|
||||
#include "shell/browser/ui/file_dialog.h"
|
||||
#include "shell/common/gin_helper/pinnable.h"
|
||||
#include "native_mate/handle.h"
|
||||
#include "url/gurl.h"
|
||||
|
||||
namespace electron {
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
class DownloadItem : public gin::Wrappable<DownloadItem>,
|
||||
public gin_helper::Pinnable<DownloadItem>,
|
||||
public gin_helper::EventEmitterMixin<DownloadItem>,
|
||||
class DownloadItem : public mate::TrackableObject<DownloadItem>,
|
||||
public download::DownloadItem::Observer {
|
||||
public:
|
||||
static gin::Handle<DownloadItem> FromOrCreate(v8::Isolate* isolate,
|
||||
download::DownloadItem* item);
|
||||
static mate::Handle<DownloadItem> Create(v8::Isolate* isolate,
|
||||
download::DownloadItem* item);
|
||||
|
||||
static DownloadItem* FromDownloadItem(download::DownloadItem*);
|
||||
static void BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype);
|
||||
|
||||
// gin::Wrappable
|
||||
static gin::WrapperInfo kWrapperInfo;
|
||||
gin::ObjectTemplateBuilder GetObjectTemplateBuilder(
|
||||
v8::Isolate* isolate) override;
|
||||
const char* GetTypeName() override;
|
||||
|
||||
// JS API, but also C++ calls it sometimes
|
||||
void SetSavePath(const base::FilePath& path);
|
||||
base::FilePath GetSavePath() const;
|
||||
file_dialog::DialogSettings GetSaveDialogOptions() const;
|
||||
|
||||
private:
|
||||
DownloadItem(v8::Isolate* isolate, download::DownloadItem* download_item);
|
||||
~DownloadItem() override;
|
||||
|
||||
bool CheckAlive() const;
|
||||
|
||||
// download::DownloadItem::Observer
|
||||
void OnDownloadUpdated(download::DownloadItem* download) override;
|
||||
void OnDownloadDestroyed(download::DownloadItem* download) override;
|
||||
|
||||
// JS API
|
||||
void Pause();
|
||||
bool IsPaused() const;
|
||||
void Resume();
|
||||
@@ -66,25 +40,35 @@ class DownloadItem : public gin::Wrappable<DownloadItem>,
|
||||
std::string GetFilename() const;
|
||||
std::string GetContentDisposition() const;
|
||||
const GURL& GetURL() const;
|
||||
v8::Local<v8::Value> GetURLChain(v8::Isolate*) const;
|
||||
const std::vector<GURL>& GetURLChain() const;
|
||||
download::DownloadItem::DownloadState GetState() const;
|
||||
bool IsDone() const;
|
||||
void SetSavePath(const base::FilePath& path);
|
||||
base::FilePath GetSavePath() const;
|
||||
file_dialog::DialogSettings GetSaveDialogOptions() const;
|
||||
void SetSaveDialogOptions(const file_dialog::DialogSettings& options);
|
||||
std::string GetLastModifiedTime() const;
|
||||
std::string GetETag() const;
|
||||
double GetStartTime() const;
|
||||
|
||||
protected:
|
||||
DownloadItem(v8::Isolate* isolate, download::DownloadItem* download_item);
|
||||
~DownloadItem() override;
|
||||
|
||||
// Override download::DownloadItem::Observer methods
|
||||
void OnDownloadUpdated(download::DownloadItem* download) override;
|
||||
void OnDownloadDestroyed(download::DownloadItem* download) override;
|
||||
|
||||
private:
|
||||
base::FilePath save_path_;
|
||||
file_dialog::DialogSettings dialog_options_;
|
||||
download::DownloadItem* download_item_;
|
||||
|
||||
base::WeakPtrFactory<DownloadItem> weak_factory_{this};
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(DownloadItem);
|
||||
};
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace electron
|
||||
} // namespace atom
|
||||
|
||||
#endif // SHELL_BROWSER_API_ELECTRON_API_DOWNLOAD_ITEM_H_
|
||||
#endif // ATOM_BROWSER_API_ATOM_API_DOWNLOAD_ITEM_H_
|
||||
@@ -2,27 +2,25 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "shell/browser/api/event.h"
|
||||
#include "shell/common/gin_helper/dictionary.h"
|
||||
#include "shell/common/gin_helper/event_emitter.h"
|
||||
#include "shell/common/node_includes.h"
|
||||
#include "atom/browser/api/event_emitter.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
|
||||
namespace {
|
||||
|
||||
v8::Local<v8::Object> CreateWithSender(v8::Isolate* isolate,
|
||||
v8::Local<v8::Object> sender) {
|
||||
return gin_helper::internal::CreateEvent(isolate, sender);
|
||||
return mate::internal::CreateJSEvent(isolate, sender, nullptr, base::nullopt);
|
||||
}
|
||||
|
||||
void Initialize(v8::Local<v8::Object> exports,
|
||||
v8::Local<v8::Value> unused,
|
||||
v8::Local<v8::Context> context,
|
||||
void* priv) {
|
||||
gin_helper::Dictionary dict(context->GetIsolate(), exports);
|
||||
mate::Dictionary dict(context->GetIsolate(), exports);
|
||||
dict.SetMethod("createWithSender", &CreateWithSender);
|
||||
dict.SetMethod("createEmpty", &gin_helper::Event::Create);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(electron_browser_event, Initialize)
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_event, Initialize)
|
||||
@@ -2,19 +2,18 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "shell/browser/api/electron_api_global_shortcut.h"
|
||||
#include "atom/browser/api/atom_api_global_shortcut.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#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 "atom/common/node_includes.h"
|
||||
#include "base/stl_util.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "gin/dictionary.h"
|
||||
#include "gin/object_template_builder.h"
|
||||
#include "shell/browser/api/electron_api_system_preferences.h"
|
||||
#include "shell/common/gin_converters/accelerator_converter.h"
|
||||
#include "shell/common/gin_converters/callback_converter.h"
|
||||
#include "shell/common/node_includes.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
#include "base/mac/mac_util.h"
|
||||
@@ -29,14 +28,12 @@ bool RegisteringMediaKeyForUntrustedClient(const ui::Accelerator& accelerator) {
|
||||
if (base::mac::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,
|
||||
ui::VKEY_VOLUME_UP, ui::VKEY_VOLUME_DOWN,
|
||||
ui::VKEY_VOLUME_MUTE};
|
||||
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 =
|
||||
electron::api::SystemPreferences::IsTrustedAccessibilityClient(false);
|
||||
atom::api::SystemPreferences::IsTrustedAccessibilityClient(false);
|
||||
if (!trusted)
|
||||
return true;
|
||||
}
|
||||
@@ -47,13 +44,13 @@ bool RegisteringMediaKeyForUntrustedClient(const ui::Accelerator& accelerator) {
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace electron {
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
gin::WrapperInfo GlobalShortcut::kWrapperInfo = {gin::kEmbedderNativeGin};
|
||||
|
||||
GlobalShortcut::GlobalShortcut(v8::Isolate* isolate) {}
|
||||
GlobalShortcut::GlobalShortcut(v8::Isolate* isolate) {
|
||||
Init(isolate);
|
||||
}
|
||||
|
||||
GlobalShortcut::~GlobalShortcut() {
|
||||
UnregisterAll();
|
||||
@@ -62,7 +59,7 @@ GlobalShortcut::~GlobalShortcut() {
|
||||
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, GlobalShortcutListener
|
||||
// This should never occur, because if it does, GlobalGlobalShortcutListener
|
||||
// notifies us with wrong accelerator.
|
||||
NOTREACHED();
|
||||
return;
|
||||
@@ -76,13 +73,19 @@ bool GlobalShortcut::RegisterAll(
|
||||
std::vector<ui::Accelerator> registered;
|
||||
|
||||
for (auto& accelerator : accelerators) {
|
||||
if (!Register(accelerator, callback)) {
|
||||
#if defined(OS_MACOSX)
|
||||
if (RegisteringMediaKeyForUntrustedClient(accelerator))
|
||||
return false;
|
||||
|
||||
GlobalShortcutListener* listener = GlobalShortcutListener::GetInstance();
|
||||
if (!listener->RegisterAccelerator(accelerator, this)) {
|
||||
// unregister all shortcuts if any failed
|
||||
UnregisterSome(registered);
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif
|
||||
registered.push_back(accelerator);
|
||||
accelerator_callback_map_[accelerator] = callback;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -104,9 +107,10 @@ bool GlobalShortcut::Register(const ui::Accelerator& accelerator,
|
||||
}
|
||||
|
||||
void GlobalShortcut::Unregister(const ui::Accelerator& accelerator) {
|
||||
if (accelerator_callback_map_.erase(accelerator) == 0)
|
||||
if (!ContainsKey(accelerator_callback_map_, accelerator))
|
||||
return;
|
||||
|
||||
accelerator_callback_map_.erase(accelerator);
|
||||
GlobalShortcutListener::GetInstance()->UnregisterAccelerator(accelerator,
|
||||
this);
|
||||
}
|
||||
@@ -119,7 +123,7 @@ void GlobalShortcut::UnregisterSome(
|
||||
}
|
||||
|
||||
bool GlobalShortcut::IsRegistered(const ui::Accelerator& accelerator) {
|
||||
return base::Contains(accelerator_callback_map_, accelerator);
|
||||
return ContainsKey(accelerator_callback_map_, accelerator);
|
||||
}
|
||||
|
||||
void GlobalShortcut::UnregisterAll() {
|
||||
@@ -128,14 +132,15 @@ void GlobalShortcut::UnregisterAll() {
|
||||
}
|
||||
|
||||
// static
|
||||
gin::Handle<GlobalShortcut> GlobalShortcut::Create(v8::Isolate* isolate) {
|
||||
return gin::CreateHandle(isolate, new GlobalShortcut(isolate));
|
||||
mate::Handle<GlobalShortcut> GlobalShortcut::Create(v8::Isolate* isolate) {
|
||||
return mate::CreateHandle(isolate, new GlobalShortcut(isolate));
|
||||
}
|
||||
|
||||
// static
|
||||
gin::ObjectTemplateBuilder GlobalShortcut::GetObjectTemplateBuilder(
|
||||
v8::Isolate* isolate) {
|
||||
return gin::Wrappable<GlobalShortcut>::GetObjectTemplateBuilder(isolate)
|
||||
void GlobalShortcut::BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype) {
|
||||
prototype->SetClassName(mate::StringToV8(isolate, "GlobalShortcut"));
|
||||
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
||||
.SetMethod("registerAll", &GlobalShortcut::RegisterAll)
|
||||
.SetMethod("register", &GlobalShortcut::Register)
|
||||
.SetMethod("isRegistered", &GlobalShortcut::IsRegistered)
|
||||
@@ -143,13 +148,9 @@ gin::ObjectTemplateBuilder GlobalShortcut::GetObjectTemplateBuilder(
|
||||
.SetMethod("unregisterAll", &GlobalShortcut::UnregisterAll);
|
||||
}
|
||||
|
||||
const char* GlobalShortcut::GetTypeName() {
|
||||
return "GlobalShortcut";
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace electron
|
||||
} // namespace atom
|
||||
|
||||
namespace {
|
||||
|
||||
@@ -158,10 +159,10 @@ void Initialize(v8::Local<v8::Object> exports,
|
||||
v8::Local<v8::Context> context,
|
||||
void* priv) {
|
||||
v8::Isolate* isolate = context->GetIsolate();
|
||||
gin::Dictionary dict(isolate, exports);
|
||||
dict.Set("globalShortcut", electron::api::GlobalShortcut::Create(isolate));
|
||||
mate::Dictionary dict(isolate, exports);
|
||||
dict.Set("globalShortcut", atom::api::GlobalShortcut::Create(isolate));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(electron_browser_global_shortcut, Initialize)
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_global_shortcut, Initialize)
|
||||
@@ -2,33 +2,30 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef SHELL_BROWSER_API_ELECTRON_API_GLOBAL_SHORTCUT_H_
|
||||
#define SHELL_BROWSER_API_ELECTRON_API_GLOBAL_SHORTCUT_H_
|
||||
#ifndef ATOM_BROWSER_API_ATOM_API_GLOBAL_SHORTCUT_H_
|
||||
#define ATOM_BROWSER_API_ATOM_API_GLOBAL_SHORTCUT_H_
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "atom/browser/api/trackable_object.h"
|
||||
#include "base/callback.h"
|
||||
#include "chrome/browser/extensions/global_shortcut_listener.h"
|
||||
#include "gin/handle.h"
|
||||
#include "gin/wrappable.h"
|
||||
#include "native_mate/handle.h"
|
||||
#include "ui/base/accelerators/accelerator.h"
|
||||
|
||||
namespace electron {
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
class GlobalShortcut : public extensions::GlobalShortcutListener::Observer,
|
||||
public gin::Wrappable<GlobalShortcut> {
|
||||
public mate::TrackableObject<GlobalShortcut> {
|
||||
public:
|
||||
static gin::Handle<GlobalShortcut> Create(v8::Isolate* isolate);
|
||||
static mate::Handle<GlobalShortcut> Create(v8::Isolate* isolate);
|
||||
|
||||
// gin::Wrappable
|
||||
static gin::WrapperInfo kWrapperInfo;
|
||||
gin::ObjectTemplateBuilder GetObjectTemplateBuilder(
|
||||
v8::Isolate* isolate) override;
|
||||
const char* GetTypeName() override;
|
||||
static void BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype);
|
||||
|
||||
protected:
|
||||
explicit GlobalShortcut(v8::Isolate* isolate);
|
||||
@@ -56,6 +53,6 @@ class GlobalShortcut : public extensions::GlobalShortcutListener::Observer,
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace electron
|
||||
} // namespace atom
|
||||
|
||||
#endif // SHELL_BROWSER_API_ELECTRON_API_GLOBAL_SHORTCUT_H_
|
||||
#endif // ATOM_BROWSER_API_ATOM_API_GLOBAL_SHORTCUT_H_
|
||||
@@ -2,23 +2,23 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "shell/browser/api/electron_api_in_app_purchase.h"
|
||||
#include "atom/browser/api/atom_api_in_app_purchase.h"
|
||||
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "shell/common/gin_helper/dictionary.h"
|
||||
#include "shell/common/gin_helper/object_template_builder.h"
|
||||
#include "shell/common/node_includes.h"
|
||||
#include "atom/common/native_mate_converters/callback.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
|
||||
namespace gin {
|
||||
namespace mate {
|
||||
|
||||
template <>
|
||||
struct Converter<in_app_purchase::Payment> {
|
||||
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
||||
const in_app_purchase::Payment& payment) {
|
||||
gin_helper::Dictionary dict = gin::Dictionary::CreateEmpty(isolate);
|
||||
mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate);
|
||||
dict.SetHidden("simple", true);
|
||||
dict.Set("productIdentifier", payment.productIdentifier);
|
||||
dict.Set("quantity", payment.quantity);
|
||||
@@ -30,7 +30,7 @@ template <>
|
||||
struct Converter<in_app_purchase::Transaction> {
|
||||
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
||||
const in_app_purchase::Transaction& val) {
|
||||
gin_helper::Dictionary dict = gin::Dictionary::CreateEmpty(isolate);
|
||||
mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate);
|
||||
dict.SetHidden("simple", true);
|
||||
dict.Set("transactionIdentifier", val.transactionIdentifier);
|
||||
dict.Set("transactionDate", val.transactionDate);
|
||||
@@ -48,7 +48,7 @@ template <>
|
||||
struct Converter<in_app_purchase::Product> {
|
||||
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
||||
const in_app_purchase::Product& val) {
|
||||
gin_helper::Dictionary dict = gin::Dictionary::CreateEmpty(isolate);
|
||||
mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate);
|
||||
dict.SetHidden("simple", true);
|
||||
dict.Set("productIdentifier", val.productIdentifier);
|
||||
dict.Set("localizedDescription", val.localizedDescription);
|
||||
@@ -67,26 +67,24 @@ struct Converter<in_app_purchase::Product> {
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace gin
|
||||
} // namespace mate
|
||||
|
||||
namespace electron {
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
// static
|
||||
gin::Handle<InAppPurchase> InAppPurchase::Create(v8::Isolate* isolate) {
|
||||
return gin::CreateHandle(isolate, new InAppPurchase(isolate));
|
||||
mate::Handle<InAppPurchase> InAppPurchase::Create(v8::Isolate* isolate) {
|
||||
return mate::CreateHandle(isolate, new InAppPurchase(isolate));
|
||||
}
|
||||
|
||||
// static
|
||||
void InAppPurchase::BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype) {
|
||||
prototype->SetClassName(gin::StringToV8(isolate, "InAppPurchase"));
|
||||
gin_helper::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
||||
prototype->SetClassName(mate::StringToV8(isolate, "InAppPurchase"));
|
||||
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
||||
.SetMethod("canMakePayments", &in_app_purchase::CanMakePayments)
|
||||
.SetMethod("restoreCompletedTransactions",
|
||||
&in_app_purchase::RestoreCompletedTransactions)
|
||||
.SetMethod("getReceiptURL", &in_app_purchase::GetReceiptURL)
|
||||
.SetMethod("purchaseProduct", &InAppPurchase::PurchaseProduct)
|
||||
.SetMethod("finishAllTransactions",
|
||||
@@ -104,9 +102,9 @@ InAppPurchase::~InAppPurchase() {}
|
||||
|
||||
v8::Local<v8::Promise> InAppPurchase::PurchaseProduct(
|
||||
const std::string& product_id,
|
||||
gin::Arguments* args) {
|
||||
mate::Arguments* args) {
|
||||
v8::Isolate* isolate = args->isolate();
|
||||
gin_helper::Promise<bool> promise(isolate);
|
||||
atom::util::Promise promise(isolate);
|
||||
v8::Local<v8::Promise> handle = promise.GetHandle();
|
||||
|
||||
int quantity = 1;
|
||||
@@ -114,7 +112,7 @@ v8::Local<v8::Promise> InAppPurchase::PurchaseProduct(
|
||||
|
||||
in_app_purchase::PurchaseProduct(
|
||||
product_id, quantity,
|
||||
base::BindOnce(gin_helper::Promise<bool>::ResolvePromise,
|
||||
base::BindOnce(atom::util::Promise::ResolvePromise<bool>,
|
||||
std::move(promise)));
|
||||
|
||||
return handle;
|
||||
@@ -122,16 +120,15 @@ v8::Local<v8::Promise> InAppPurchase::PurchaseProduct(
|
||||
|
||||
v8::Local<v8::Promise> InAppPurchase::GetProducts(
|
||||
const std::vector<std::string>& productIDs,
|
||||
gin::Arguments* args) {
|
||||
mate::Arguments* args) {
|
||||
v8::Isolate* isolate = args->isolate();
|
||||
gin_helper::Promise<std::vector<in_app_purchase::Product>> promise(isolate);
|
||||
atom::util::Promise promise(isolate);
|
||||
v8::Local<v8::Promise> handle = promise.GetHandle();
|
||||
|
||||
in_app_purchase::GetProducts(
|
||||
productIDs,
|
||||
base::BindOnce(gin_helper::Promise<
|
||||
std::vector<in_app_purchase::Product>>::ResolvePromise,
|
||||
std::move(promise)));
|
||||
productIDs, base::BindOnce(atom::util::Promise::ResolvePromise<
|
||||
std::vector<in_app_purchase::Product>>,
|
||||
std::move(promise)));
|
||||
|
||||
return handle;
|
||||
}
|
||||
@@ -144,11 +141,11 @@ void InAppPurchase::OnTransactionsUpdated(
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace electron
|
||||
} // namespace atom
|
||||
|
||||
namespace {
|
||||
|
||||
using electron::api::InAppPurchase;
|
||||
using atom::api::InAppPurchase;
|
||||
|
||||
void Initialize(v8::Local<v8::Object> exports,
|
||||
v8::Local<v8::Value> unused,
|
||||
@@ -156,7 +153,7 @@ void Initialize(v8::Local<v8::Object> exports,
|
||||
void* priv) {
|
||||
#if defined(OS_MACOSX)
|
||||
v8::Isolate* isolate = context->GetIsolate();
|
||||
gin_helper::Dictionary dict(isolate, exports);
|
||||
mate::Dictionary dict(isolate, exports);
|
||||
dict.Set("inAppPurchase", InAppPurchase::Create(isolate));
|
||||
dict.Set("InAppPurchase", InAppPurchase::GetConstructor(isolate)
|
||||
->GetFunction(context)
|
||||
@@ -166,4 +163,4 @@ void Initialize(v8::Local<v8::Object> exports,
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(electron_browser_in_app_purchase, Initialize)
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_in_app_purchase, Initialize)
|
||||
@@ -2,27 +2,27 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef SHELL_BROWSER_API_ELECTRON_API_IN_APP_PURCHASE_H_
|
||||
#define SHELL_BROWSER_API_ELECTRON_API_IN_APP_PURCHASE_H_
|
||||
#ifndef ATOM_BROWSER_API_ATOM_API_IN_APP_PURCHASE_H_
|
||||
#define ATOM_BROWSER_API_ATOM_API_IN_APP_PURCHASE_H_
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "gin/handle.h"
|
||||
#include "shell/browser/mac/in_app_purchase.h"
|
||||
#include "shell/browser/mac/in_app_purchase_observer.h"
|
||||
#include "shell/browser/mac/in_app_purchase_product.h"
|
||||
#include "shell/common/gin_helper/event_emitter.h"
|
||||
#include "shell/common/gin_helper/promise.h"
|
||||
#include "atom/browser/api/event_emitter.h"
|
||||
#include "atom/browser/mac/in_app_purchase.h"
|
||||
#include "atom/browser/mac/in_app_purchase_observer.h"
|
||||
#include "atom/browser/mac/in_app_purchase_product.h"
|
||||
#include "atom/common/promise_util.h"
|
||||
#include "native_mate/handle.h"
|
||||
|
||||
namespace electron {
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
class InAppPurchase : public gin_helper::EventEmitter<InAppPurchase>,
|
||||
class InAppPurchase : public mate::EventEmitter<InAppPurchase>,
|
||||
public in_app_purchase::TransactionObserver {
|
||||
public:
|
||||
static gin::Handle<InAppPurchase> Create(v8::Isolate* isolate);
|
||||
static mate::Handle<InAppPurchase> Create(v8::Isolate* isolate);
|
||||
|
||||
static void BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype);
|
||||
@@ -32,10 +32,10 @@ class InAppPurchase : public gin_helper::EventEmitter<InAppPurchase>,
|
||||
~InAppPurchase() override;
|
||||
|
||||
v8::Local<v8::Promise> PurchaseProduct(const std::string& product_id,
|
||||
gin::Arguments* args);
|
||||
mate::Arguments* args);
|
||||
|
||||
v8::Local<v8::Promise> GetProducts(const std::vector<std::string>& productIDs,
|
||||
gin::Arguments* args);
|
||||
mate::Arguments* args);
|
||||
|
||||
// TransactionObserver:
|
||||
void OnTransactionsUpdated(
|
||||
@@ -47,6 +47,6 @@ class InAppPurchase : public gin_helper::EventEmitter<InAppPurchase>,
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace electron
|
||||
} // namespace atom
|
||||
|
||||
#endif // SHELL_BROWSER_API_ELECTRON_API_IN_APP_PURCHASE_H_
|
||||
#endif // ATOM_BROWSER_API_ATOM_API_IN_APP_PURCHASE_H_
|
||||
@@ -2,28 +2,25 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "shell/browser/api/electron_api_menu.h"
|
||||
#include "atom/browser/api/atom_api_menu.h"
|
||||
|
||||
#include <map>
|
||||
#include <utility>
|
||||
#include "atom/browser/native_window.h"
|
||||
#include "atom/common/native_mate_converters/accelerator_converter.h"
|
||||
#include "atom/common/native_mate_converters/callback.h"
|
||||
#include "atom/common/native_mate_converters/image_converter.h"
|
||||
#include "atom/common/native_mate_converters/string16_converter.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "native_mate/constructor.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "native_mate/object_template_builder.h"
|
||||
|
||||
#include "shell/browser/api/ui_event.h"
|
||||
#include "shell/browser/native_window.h"
|
||||
#include "shell/common/gin_converters/accelerator_converter.h"
|
||||
#include "shell/common/gin_converters/callback_converter.h"
|
||||
#include "shell/common/gin_converters/image_converter.h"
|
||||
#include "shell/common/gin_helper/dictionary.h"
|
||||
#include "shell/common/gin_helper/object_template_builder.h"
|
||||
#include "shell/common/node_includes.h"
|
||||
#include "ui/base/models/image_model.h"
|
||||
|
||||
namespace electron {
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
gin::WrapperInfo Menu::kWrapperInfo = {gin::kEmbedderNativeGin};
|
||||
|
||||
Menu::Menu(gin::Arguments* args) : model_(new ElectronMenuModel(this)) {
|
||||
Menu::Menu(v8::Isolate* isolate, v8::Local<v8::Object> wrapper)
|
||||
: model_(new AtomMenuModel(this)) {
|
||||
InitWith(isolate, wrapper);
|
||||
model_->AddObserver(this);
|
||||
}
|
||||
|
||||
@@ -33,82 +30,76 @@ Menu::~Menu() {
|
||||
}
|
||||
}
|
||||
|
||||
bool InvokeBoolMethod(const Menu* menu,
|
||||
const char* method,
|
||||
int command_id,
|
||||
bool default_value = false) {
|
||||
v8::Isolate* isolate = v8::Isolate::GetCurrent();
|
||||
v8::HandleScope scope(isolate);
|
||||
// We need to cast off const here because GetWrapper() is non-const, but
|
||||
// ui::SimpleMenuModel::Delegate's methods are const.
|
||||
v8::Local<v8::Value> val = gin_helper::CallMethod(
|
||||
isolate, const_cast<Menu*>(menu), method, command_id);
|
||||
bool ret = false;
|
||||
return gin::ConvertFromV8(isolate, val, &ret) ? ret : default_value;
|
||||
void Menu::AfterInit(v8::Isolate* isolate) {
|
||||
mate::Dictionary wrappable(isolate, GetWrapper());
|
||||
mate::Dictionary delegate;
|
||||
if (!wrappable.Get("delegate", &delegate))
|
||||
return;
|
||||
|
||||
delegate.Get("isCommandIdChecked", &is_checked_);
|
||||
delegate.Get("isCommandIdEnabled", &is_enabled_);
|
||||
delegate.Get("isCommandIdVisible", &is_visible_);
|
||||
delegate.Get("shouldCommandIdWorkWhenHidden", &works_when_hidden_);
|
||||
delegate.Get("getAcceleratorForCommandId", &get_accelerator_);
|
||||
delegate.Get("shouldRegisterAcceleratorForCommandId",
|
||||
&should_register_accelerator_);
|
||||
delegate.Get("executeCommand", &execute_command_);
|
||||
delegate.Get("menuWillShow", &menu_will_show_);
|
||||
}
|
||||
|
||||
bool Menu::IsCommandIdChecked(int command_id) const {
|
||||
return InvokeBoolMethod(this, "_isCommandIdChecked", command_id);
|
||||
v8::Locker locker(isolate());
|
||||
v8::HandleScope handle_scope(isolate());
|
||||
return is_checked_.Run(GetWrapper(), command_id);
|
||||
}
|
||||
|
||||
bool Menu::IsCommandIdEnabled(int command_id) const {
|
||||
return InvokeBoolMethod(this, "_isCommandIdEnabled", command_id);
|
||||
v8::Locker locker(isolate());
|
||||
v8::HandleScope handle_scope(isolate());
|
||||
return is_enabled_.Run(GetWrapper(), command_id);
|
||||
}
|
||||
|
||||
bool Menu::IsCommandIdVisible(int command_id) const {
|
||||
return InvokeBoolMethod(this, "_isCommandIdVisible", command_id);
|
||||
v8::Locker locker(isolate());
|
||||
v8::HandleScope handle_scope(isolate());
|
||||
return is_visible_.Run(GetWrapper(), command_id);
|
||||
}
|
||||
|
||||
bool Menu::ShouldCommandIdWorkWhenHidden(int command_id) const {
|
||||
return InvokeBoolMethod(this, "_shouldCommandIdWorkWhenHidden", command_id);
|
||||
v8::Locker locker(isolate());
|
||||
v8::HandleScope handle_scope(isolate());
|
||||
return works_when_hidden_.Run(GetWrapper(), command_id);
|
||||
}
|
||||
|
||||
bool Menu::GetAcceleratorForCommandIdWithParams(
|
||||
int command_id,
|
||||
bool use_default_accelerator,
|
||||
ui::Accelerator* accelerator) const {
|
||||
v8::Isolate* isolate = v8::Isolate::GetCurrent();
|
||||
v8::HandleScope scope(isolate);
|
||||
v8::Local<v8::Value> val = gin_helper::CallMethod(
|
||||
isolate, const_cast<Menu*>(this), "_getAcceleratorForCommandId",
|
||||
command_id, use_default_accelerator);
|
||||
return gin::ConvertFromV8(isolate, val, accelerator);
|
||||
v8::Locker locker(isolate());
|
||||
v8::HandleScope handle_scope(isolate());
|
||||
v8::Local<v8::Value> val =
|
||||
get_accelerator_.Run(GetWrapper(), command_id, use_default_accelerator);
|
||||
return mate::ConvertFromV8(isolate(), val, accelerator);
|
||||
}
|
||||
|
||||
bool Menu::ShouldRegisterAcceleratorForCommandId(int command_id) const {
|
||||
return InvokeBoolMethod(this, "_shouldRegisterAcceleratorForCommandId",
|
||||
command_id);
|
||||
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::Isolate* isolate = v8::Isolate::GetCurrent();
|
||||
v8::HandleScope scope(isolate);
|
||||
gin_helper::CallMethod(isolate, const_cast<Menu*>(this), "_executeCommand",
|
||||
CreateEventFromFlags(flags), command_id);
|
||||
v8::Locker locker(isolate());
|
||||
v8::HandleScope handle_scope(isolate());
|
||||
execute_command_.Run(GetWrapper(),
|
||||
mate::internal::CreateEventFromFlags(isolate(), flags),
|
||||
command_id);
|
||||
}
|
||||
|
||||
void Menu::OnMenuWillShow(ui::SimpleMenuModel* source) {
|
||||
v8::Isolate* isolate = v8::Isolate::GetCurrent();
|
||||
v8::HandleScope scope(isolate);
|
||||
gin_helper::CallMethod(isolate, const_cast<Menu*>(this), "_menuWillShow");
|
||||
}
|
||||
|
||||
base::OnceClosure Menu::BindSelfToClosure(base::OnceClosure callback) {
|
||||
// return ((callback, ref) => { callback() }).bind(null, callback, this)
|
||||
v8::Isolate* isolate = v8::Isolate::GetCurrent();
|
||||
v8::Locker locker(isolate);
|
||||
v8::HandleScope scope(isolate);
|
||||
v8::Local<v8::Object> self;
|
||||
if (GetWrapper(isolate).ToLocal(&self)) {
|
||||
v8::Global<v8::Value> ref(isolate, self);
|
||||
return base::BindOnce(
|
||||
[](base::OnceClosure callback, v8::Global<v8::Value> ref) {
|
||||
std::move(callback).Run();
|
||||
},
|
||||
std::move(callback), std::move(ref));
|
||||
} else {
|
||||
return base::DoNothing();
|
||||
}
|
||||
v8::Locker locker(isolate());
|
||||
v8::HandleScope handle_scope(isolate());
|
||||
menu_will_show_.Run(GetWrapper());
|
||||
}
|
||||
|
||||
void Menu::InsertItemAt(int index,
|
||||
@@ -143,15 +134,11 @@ void Menu::InsertSubMenuAt(int index,
|
||||
}
|
||||
|
||||
void Menu::SetIcon(int index, const gfx::Image& image) {
|
||||
model_->SetIcon(index, ui::ImageModel::FromImage(image));
|
||||
model_->SetIcon(index, image);
|
||||
}
|
||||
|
||||
void Menu::SetSublabel(int index, const base::string16& sublabel) {
|
||||
model_->SetSecondaryLabel(index, sublabel);
|
||||
}
|
||||
|
||||
void Menu::SetToolTip(int index, const base::string16& toolTip) {
|
||||
model_->SetToolTip(index, toolTip);
|
||||
model_->SetSublabel(index, sublabel);
|
||||
}
|
||||
|
||||
void Menu::SetRole(int index, const base::string16& role) {
|
||||
@@ -179,11 +166,7 @@ base::string16 Menu::GetLabelAt(int index) const {
|
||||
}
|
||||
|
||||
base::string16 Menu::GetSublabelAt(int index) const {
|
||||
return model_->GetSecondaryLabelAt(index);
|
||||
}
|
||||
|
||||
base::string16 Menu::GetToolTipAt(int index) const {
|
||||
return model_->GetToolTipAt(index);
|
||||
return model_->GetSublabelAt(index);
|
||||
}
|
||||
|
||||
base::string16 Menu::GetAcceleratorTextAt(int index) const {
|
||||
@@ -209,20 +192,19 @@ bool Menu::WorksWhenHiddenAt(int index) const {
|
||||
}
|
||||
|
||||
void Menu::OnMenuWillClose() {
|
||||
Unpin();
|
||||
Emit("menu-will-close");
|
||||
}
|
||||
|
||||
void Menu::OnMenuWillShow() {
|
||||
Pin(v8::Isolate::GetCurrent());
|
||||
Emit("menu-will-show");
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Local<v8::ObjectTemplate> Menu::FillObjectTemplate(
|
||||
v8::Isolate* isolate,
|
||||
v8::Local<v8::ObjectTemplate> templ) {
|
||||
return gin::ObjectTemplateBuilder(isolate, "Menu", templ)
|
||||
void Menu::BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype) {
|
||||
prototype->SetClassName(mate::StringToV8(isolate, "Menu"));
|
||||
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
||||
.MakeDestroyable()
|
||||
.SetMethod("insertItem", &Menu::InsertItemAt)
|
||||
.SetMethod("insertCheckItem", &Menu::InsertCheckItemAt)
|
||||
.SetMethod("insertRadioItem", &Menu::InsertRadioItemAt)
|
||||
@@ -230,7 +212,6 @@ v8::Local<v8::ObjectTemplate> Menu::FillObjectTemplate(
|
||||
.SetMethod("insertSubMenu", &Menu::InsertSubMenuAt)
|
||||
.SetMethod("setIcon", &Menu::SetIcon)
|
||||
.SetMethod("setSublabel", &Menu::SetSublabel)
|
||||
.SetMethod("setToolTip", &Menu::SetToolTip)
|
||||
.SetMethod("setRole", &Menu::SetRole)
|
||||
.SetMethod("clear", &Menu::Clear)
|
||||
.SetMethod("getIndexOfCommandId", &Menu::GetIndexOfCommandId)
|
||||
@@ -238,33 +219,34 @@ v8::Local<v8::ObjectTemplate> Menu::FillObjectTemplate(
|
||||
.SetMethod("getCommandIdAt", &Menu::GetCommandIdAt)
|
||||
.SetMethod("getLabelAt", &Menu::GetLabelAt)
|
||||
.SetMethod("getSublabelAt", &Menu::GetSublabelAt)
|
||||
.SetMethod("getToolTipAt", &Menu::GetToolTipAt)
|
||||
.SetMethod("getAcceleratorTextAt", &Menu::GetAcceleratorTextAt)
|
||||
.SetMethod("isItemCheckedAt", &Menu::IsItemCheckedAt)
|
||||
.SetMethod("isEnabledAt", &Menu::IsEnabledAt)
|
||||
.SetMethod("worksWhenHiddenAt", &Menu::WorksWhenHiddenAt)
|
||||
.SetMethod("isVisibleAt", &Menu::IsVisibleAt)
|
||||
.SetMethod("popupAt", &Menu::PopupAt)
|
||||
.SetMethod("closePopupAt", &Menu::ClosePopupAt)
|
||||
.Build();
|
||||
.SetMethod("closePopupAt", &Menu::ClosePopupAt);
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace electron
|
||||
} // namespace atom
|
||||
|
||||
namespace {
|
||||
|
||||
using electron::api::Menu;
|
||||
using atom::api::Menu;
|
||||
|
||||
void Initialize(v8::Local<v8::Object> exports,
|
||||
v8::Local<v8::Value> unused,
|
||||
v8::Local<v8::Context> context,
|
||||
void* priv) {
|
||||
v8::Isolate* isolate = context->GetIsolate();
|
||||
Menu::SetConstructor(isolate, base::Bind(&Menu::New));
|
||||
|
||||
gin_helper::Dictionary dict(isolate, exports);
|
||||
dict.Set("Menu", Menu::GetConstructor(context));
|
||||
mate::Dictionary dict(isolate, exports);
|
||||
dict.Set(
|
||||
"Menu",
|
||||
Menu::GetConstructor(isolate)->GetFunction(context).ToLocalChecked());
|
||||
#if defined(OS_MACOSX)
|
||||
dict.SetMethod("setApplicationMenu", &Menu::SetApplicationMenu);
|
||||
dict.SetMethod("sendActionToFirstResponder",
|
||||
@@ -274,4 +256,4 @@ void Initialize(v8::Local<v8::Object> exports,
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(electron_browser_menu, Initialize)
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_menu, Initialize)
|
||||
@@ -2,39 +2,29 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef SHELL_BROWSER_API_ELECTRON_API_MENU_H_
|
||||
#define SHELL_BROWSER_API_ELECTRON_API_MENU_H_
|
||||
#ifndef ATOM_BROWSER_API_ATOM_API_MENU_H_
|
||||
#define ATOM_BROWSER_API_ATOM_API_MENU_H_
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "atom/browser/api/atom_api_top_level_window.h"
|
||||
#include "atom/browser/api/trackable_object.h"
|
||||
#include "atom/browser/ui/atom_menu_model.h"
|
||||
#include "base/callback.h"
|
||||
#include "gin/arguments.h"
|
||||
#include "shell/browser/api/electron_api_top_level_window.h"
|
||||
#include "shell/browser/event_emitter_mixin.h"
|
||||
#include "shell/browser/ui/electron_menu_model.h"
|
||||
#include "shell/common/gin_helper/constructible.h"
|
||||
#include "shell/common/gin_helper/pinnable.h"
|
||||
|
||||
namespace electron {
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
class Menu : public gin::Wrappable<Menu>,
|
||||
public gin_helper::EventEmitterMixin<Menu>,
|
||||
public gin_helper::Constructible<Menu>,
|
||||
public gin_helper::Pinnable<Menu>,
|
||||
public ElectronMenuModel::Delegate,
|
||||
public ElectronMenuModel::Observer {
|
||||
class Menu : public mate::TrackableObject<Menu>,
|
||||
public AtomMenuModel::Delegate,
|
||||
public AtomMenuModel::Observer {
|
||||
public:
|
||||
// gin_helper::Constructible
|
||||
static gin::Handle<Menu> New(gin::Arguments* args);
|
||||
static v8::Local<v8::ObjectTemplate> FillObjectTemplate(
|
||||
v8::Isolate*,
|
||||
v8::Local<v8::ObjectTemplate>);
|
||||
static mate::WrappableBase* New(mate::Arguments* args);
|
||||
|
||||
// gin::Wrappable
|
||||
static gin::WrapperInfo kWrapperInfo;
|
||||
static void BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype);
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
// Set the global menubar.
|
||||
@@ -44,15 +34,14 @@ class Menu : public gin::Wrappable<Menu>,
|
||||
static void SendActionToFirstResponder(const std::string& action);
|
||||
#endif
|
||||
|
||||
ElectronMenuModel* model() const { return model_.get(); }
|
||||
AtomMenuModel* model() const { return model_.get(); }
|
||||
|
||||
protected:
|
||||
explicit Menu(gin::Arguments* args);
|
||||
Menu(v8::Isolate* isolate, v8::Local<v8::Object> wrapper);
|
||||
~Menu() override;
|
||||
|
||||
// Returns a new callback which keeps references of the JS wrapper until the
|
||||
// passed |callback| is called.
|
||||
base::OnceClosure BindSelfToClosure(base::OnceClosure callback);
|
||||
// mate::Wrappable:
|
||||
void AfterInit(v8::Isolate* isolate) override;
|
||||
|
||||
// ui::SimpleMenuModel::Delegate:
|
||||
bool IsCommandIdChecked(int command_id) const override;
|
||||
@@ -71,10 +60,10 @@ class Menu : public gin::Wrappable<Menu>,
|
||||
int x,
|
||||
int y,
|
||||
int positioning_item,
|
||||
base::OnceClosure callback) = 0;
|
||||
const base::Closure& callback) = 0;
|
||||
virtual void ClosePopupAt(int32_t window_id) = 0;
|
||||
|
||||
std::unique_ptr<ElectronMenuModel> model_;
|
||||
std::unique_ptr<AtomMenuModel> model_;
|
||||
Menu* parent_ = nullptr;
|
||||
|
||||
// Observable:
|
||||
@@ -97,7 +86,6 @@ class Menu : public gin::Wrappable<Menu>,
|
||||
Menu* menu);
|
||||
void SetIcon(int index, const gfx::Image& image);
|
||||
void SetSublabel(int index, const base::string16& sublabel);
|
||||
void SetToolTip(int index, const base::string16& toolTip);
|
||||
void SetRole(int index, const base::string16& role);
|
||||
void Clear();
|
||||
int GetIndexOfCommandId(int command_id);
|
||||
@@ -105,41 +93,52 @@ class Menu : public gin::Wrappable<Menu>,
|
||||
int GetCommandIdAt(int index) const;
|
||||
base::string16 GetLabelAt(int index) const;
|
||||
base::string16 GetSublabelAt(int index) const;
|
||||
base::string16 GetToolTipAt(int index) const;
|
||||
base::string16 GetAcceleratorTextAt(int index) const;
|
||||
bool IsItemCheckedAt(int index) const;
|
||||
bool IsEnabledAt(int index) const;
|
||||
bool IsVisibleAt(int index) const;
|
||||
bool WorksWhenHiddenAt(int index) const;
|
||||
|
||||
// Stored delegate methods.
|
||||
base::Callback<bool(v8::Local<v8::Value>, int)> is_checked_;
|
||||
base::Callback<bool(v8::Local<v8::Value>, int)> is_enabled_;
|
||||
base::Callback<bool(v8::Local<v8::Value>, int)> is_visible_;
|
||||
base::Callback<bool(v8::Local<v8::Value>, int)> works_when_hidden_;
|
||||
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_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(Menu);
|
||||
};
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace electron
|
||||
} // namespace atom
|
||||
|
||||
namespace gin {
|
||||
namespace mate {
|
||||
|
||||
template <>
|
||||
struct Converter<electron::ElectronMenuModel*> {
|
||||
struct Converter<atom::AtomMenuModel*> {
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
electron::ElectronMenuModel** out) {
|
||||
atom::AtomMenuModel** out) {
|
||||
// null would be tranfered to NULL.
|
||||
if (val->IsNull()) {
|
||||
*out = nullptr;
|
||||
return true;
|
||||
}
|
||||
|
||||
electron::api::Menu* menu;
|
||||
if (!Converter<electron::api::Menu*>::FromV8(isolate, val, &menu))
|
||||
atom::api::Menu* menu;
|
||||
if (!Converter<atom::api::Menu*>::FromV8(isolate, val, &menu))
|
||||
return false;
|
||||
*out = menu->model();
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace gin
|
||||
} // namespace mate
|
||||
|
||||
#endif // SHELL_BROWSER_API_ELECTRON_API_MENU_H_
|
||||
#endif // ATOM_BROWSER_API_ATOM_API_MENU_H_
|
||||
@@ -2,50 +2,49 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef SHELL_BROWSER_API_ELECTRON_API_MENU_MAC_H_
|
||||
#define SHELL_BROWSER_API_ELECTRON_API_MENU_MAC_H_
|
||||
#ifndef ATOM_BROWSER_API_ATOM_API_MENU_MAC_H_
|
||||
#define ATOM_BROWSER_API_ATOM_API_MENU_MAC_H_
|
||||
|
||||
#include "shell/browser/api/electron_api_menu.h"
|
||||
#include "atom/browser/api/atom_api_menu.h"
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
#import "shell/browser/ui/cocoa/electron_menu_controller.h"
|
||||
#import "atom/browser/ui/cocoa/atom_menu_controller.h"
|
||||
|
||||
using base::scoped_nsobject;
|
||||
|
||||
namespace electron {
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
class MenuMac : public Menu {
|
||||
protected:
|
||||
explicit MenuMac(gin::Arguments* args);
|
||||
MenuMac(v8::Isolate* isolate, v8::Local<v8::Object> wrapper);
|
||||
~MenuMac() override;
|
||||
|
||||
void PopupAt(TopLevelWindow* window,
|
||||
int x,
|
||||
int y,
|
||||
int positioning_item,
|
||||
base::OnceClosure callback) override;
|
||||
const base::Closure& callback) override;
|
||||
void PopupOnUI(const base::WeakPtr<NativeWindow>& native_window,
|
||||
int32_t window_id,
|
||||
int x,
|
||||
int y,
|
||||
int positioning_item,
|
||||
base::OnceClosure callback);
|
||||
base::Closure callback);
|
||||
void ClosePopupAt(int32_t window_id) override;
|
||||
void ClosePopupOnUI(int32_t window_id);
|
||||
|
||||
private:
|
||||
friend class Menu;
|
||||
|
||||
void OnClosed(int32_t window_id, base::OnceClosure callback);
|
||||
void OnClosed(int32_t window_id, base::Closure callback);
|
||||
|
||||
scoped_nsobject<ElectronMenuController> menu_controller_;
|
||||
scoped_nsobject<AtomMenuController> menu_controller_;
|
||||
|
||||
// window ID -> open context menu
|
||||
std::map<int32_t, scoped_nsobject<ElectronMenuController>> popup_controllers_;
|
||||
std::map<int32_t, scoped_nsobject<AtomMenuController>> popup_controllers_;
|
||||
|
||||
base::WeakPtrFactory<MenuMac> weak_factory_;
|
||||
|
||||
@@ -54,6 +53,6 @@ class MenuMac : public Menu {
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace electron
|
||||
} // namespace atom
|
||||
|
||||
#endif // SHELL_BROWSER_API_ELECTRON_API_MENU_MAC_H_
|
||||
#endif // ATOM_BROWSER_API_ATOM_API_MENU_MAC_H_
|
||||
@@ -2,21 +2,18 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#import "shell/browser/api/electron_api_menu_mac.h"
|
||||
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#import "atom/browser/api/atom_api_menu_mac.h"
|
||||
|
||||
#include "atom/browser/native_window.h"
|
||||
#include "atom/browser/unresponsive_suppressor.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "base/mac/scoped_sending_event.h"
|
||||
#include "base/message_loop/message_loop_current.h"
|
||||
#include "base/message_loop/message_loop.h"
|
||||
#include "base/strings/sys_string_conversions.h"
|
||||
#include "base/task/post_task.h"
|
||||
#include "content/public/browser/browser_task_traits.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "content/public/browser/web_contents.h"
|
||||
#include "shell/browser/native_window.h"
|
||||
#include "shell/browser/unresponsive_suppressor.h"
|
||||
#include "shell/common/node_includes.h"
|
||||
|
||||
using content::BrowserThread;
|
||||
|
||||
@@ -26,11 +23,12 @@ static scoped_nsobject<NSMenu> applicationMenu_;
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace electron {
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
MenuMac::MenuMac(gin::Arguments* args) : Menu(args), weak_factory_(this) {}
|
||||
MenuMac::MenuMac(v8::Isolate* isolate, v8::Local<v8::Object> wrapper)
|
||||
: Menu(isolate, wrapper), weak_factory_(this) {}
|
||||
|
||||
MenuMac::~MenuMac() = default;
|
||||
|
||||
@@ -38,20 +36,15 @@ void MenuMac::PopupAt(TopLevelWindow* window,
|
||||
int x,
|
||||
int y,
|
||||
int positioning_item,
|
||||
base::OnceClosure callback) {
|
||||
const base::Closure& callback) {
|
||||
NativeWindow* native_window = window->window();
|
||||
if (!native_window)
|
||||
return;
|
||||
|
||||
// Make sure the Menu object would not be garbage-collected until the callback
|
||||
// has run.
|
||||
base::OnceClosure callback_with_ref = BindSelfToClosure(std::move(callback));
|
||||
|
||||
auto popup =
|
||||
base::BindOnce(&MenuMac::PopupOnUI, weak_factory_.GetWeakPtr(),
|
||||
native_window->GetWeakPtr(), window->weak_map_id(), x, y,
|
||||
positioning_item, std::move(callback_with_ref));
|
||||
base::SequencedTaskRunnerHandle::Get()->PostTask(FROM_HERE, std::move(popup));
|
||||
auto popup = base::Bind(&MenuMac::PopupOnUI, weak_factory_.GetWeakPtr(),
|
||||
native_window->GetWeakPtr(), window->weak_map_id(), x,
|
||||
y, positioning_item, callback);
|
||||
base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI}, popup);
|
||||
}
|
||||
|
||||
void MenuMac::PopupOnUI(const base::WeakPtr<NativeWindow>& native_window,
|
||||
@@ -59,17 +52,16 @@ void MenuMac::PopupOnUI(const base::WeakPtr<NativeWindow>& native_window,
|
||||
int x,
|
||||
int y,
|
||||
int positioning_item,
|
||||
base::OnceClosure callback) {
|
||||
base::Closure callback) {
|
||||
if (!native_window)
|
||||
return;
|
||||
NSWindow* nswindow = native_window->GetNativeWindow().GetNativeNSWindow();
|
||||
|
||||
base::OnceClosure close_callback =
|
||||
base::BindOnce(&MenuMac::OnClosed, weak_factory_.GetWeakPtr(), window_id,
|
||||
std::move(callback));
|
||||
popup_controllers_[window_id] = base::scoped_nsobject<ElectronMenuController>(
|
||||
[[ElectronMenuController alloc] initWithModel:model()
|
||||
useDefaultAccelerator:NO]);
|
||||
auto close_callback = base::Bind(
|
||||
&MenuMac::OnClosed, weak_factory_.GetWeakPtr(), window_id, callback);
|
||||
popup_controllers_[window_id] = base::scoped_nsobject<AtomMenuController>([
|
||||
[AtomMenuController alloc] initWithModel:model()
|
||||
useDefaultAccelerator:NO]);
|
||||
NSMenu* menu = [popup_controllers_[window_id] menu];
|
||||
NSView* view = [nswindow contentView];
|
||||
|
||||
@@ -104,7 +96,7 @@ void MenuMac::PopupOnUI(const base::WeakPtr<NativeWindow>& native_window,
|
||||
if (rightmostMenuPoint > screenRight)
|
||||
position.x = position.x - [menu size].width;
|
||||
|
||||
[popup_controllers_[window_id] setCloseCallback:std::move(close_callback)];
|
||||
[popup_controllers_[window_id] setCloseCallback:close_callback];
|
||||
// Make sure events can be pumped while the menu is up.
|
||||
base::MessageLoopCurrent::ScopedNestableTaskAllower allow;
|
||||
|
||||
@@ -116,18 +108,11 @@ void MenuMac::PopupOnUI(const base::WeakPtr<NativeWindow>& native_window,
|
||||
base::mac::ScopedSendingEvent sendingEventScoper;
|
||||
|
||||
// Don't emit unresponsive event when showing menu.
|
||||
electron::UnresponsiveSuppressor suppressor;
|
||||
atom::UnresponsiveSuppressor suppressor;
|
||||
[menu popUpMenuPositioningItem:item atLocation:position inView:view];
|
||||
}
|
||||
|
||||
void MenuMac::ClosePopupAt(int32_t window_id) {
|
||||
auto close_popup = base::BindOnce(&MenuMac::ClosePopupOnUI,
|
||||
weak_factory_.GetWeakPtr(), window_id);
|
||||
base::SequencedTaskRunnerHandle::Get()->PostTask(FROM_HERE,
|
||||
std::move(close_popup));
|
||||
}
|
||||
|
||||
void MenuMac::ClosePopupOnUI(int32_t window_id) {
|
||||
auto controller = popup_controllers_.find(window_id);
|
||||
if (controller != popup_controllers_.end()) {
|
||||
// Close the controller for the window.
|
||||
@@ -142,17 +127,17 @@ void MenuMac::ClosePopupOnUI(int32_t window_id) {
|
||||
}
|
||||
}
|
||||
|
||||
void MenuMac::OnClosed(int32_t window_id, base::OnceClosure callback) {
|
||||
void MenuMac::OnClosed(int32_t window_id, base::Closure callback) {
|
||||
popup_controllers_.erase(window_id);
|
||||
std::move(callback).Run();
|
||||
callback.Run();
|
||||
}
|
||||
|
||||
// static
|
||||
void Menu::SetApplicationMenu(Menu* base_menu) {
|
||||
MenuMac* menu = static_cast<MenuMac*>(base_menu);
|
||||
base::scoped_nsobject<ElectronMenuController> menu_controller(
|
||||
[[ElectronMenuController alloc] initWithModel:menu->model_.get()
|
||||
useDefaultAccelerator:YES]);
|
||||
base::scoped_nsobject<AtomMenuController> menu_controller([
|
||||
[AtomMenuController alloc] initWithModel:menu->model_.get()
|
||||
useDefaultAccelerator:YES]);
|
||||
|
||||
NSRunLoop* currentRunLoop = [NSRunLoop currentRunLoop];
|
||||
[currentRunLoop cancelPerformSelector:@selector(setMainMenu:)
|
||||
@@ -177,13 +162,10 @@ void Menu::SendActionToFirstResponder(const std::string& action) {
|
||||
}
|
||||
|
||||
// static
|
||||
gin::Handle<Menu> Menu::New(gin::Arguments* args) {
|
||||
auto handle =
|
||||
gin::CreateHandle(args->isolate(), static_cast<Menu*>(new MenuMac(args)));
|
||||
gin_helper::CallMethod(args->isolate(), handle.get(), "_init");
|
||||
return handle;
|
||||
mate::WrappableBase* Menu::New(mate::Arguments* args) {
|
||||
return new MenuMac(args->isolate(), args->GetThis());
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace electron
|
||||
} // namespace atom
|
||||
@@ -2,22 +2,22 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "shell/browser/api/electron_api_menu_views.h"
|
||||
#include "atom/browser/api/atom_api_menu_views.h"
|
||||
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
#include "shell/browser/native_window_views.h"
|
||||
#include "shell/browser/unresponsive_suppressor.h"
|
||||
#include "atom/browser/native_window_views.h"
|
||||
#include "atom/browser/unresponsive_suppressor.h"
|
||||
#include "ui/display/screen.h"
|
||||
|
||||
using views::MenuRunner;
|
||||
|
||||
namespace electron {
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
MenuViews::MenuViews(gin::Arguments* args) : Menu(args), weak_factory_(this) {}
|
||||
MenuViews::MenuViews(v8::Isolate* isolate, v8::Local<v8::Object> wrapper)
|
||||
: Menu(isolate, wrapper), weak_factory_(this) {}
|
||||
|
||||
MenuViews::~MenuViews() = default;
|
||||
|
||||
@@ -25,7 +25,7 @@ void MenuViews::PopupAt(TopLevelWindow* window,
|
||||
int x,
|
||||
int y,
|
||||
int positioning_item,
|
||||
base::OnceClosure callback) {
|
||||
const base::Closure& callback) {
|
||||
auto* native_window = static_cast<NativeWindowViews*>(window->window());
|
||||
if (!native_window)
|
||||
return;
|
||||
@@ -42,25 +42,16 @@ void MenuViews::PopupAt(TopLevelWindow* window,
|
||||
int flags = MenuRunner::CONTEXT_MENU | MenuRunner::HAS_MNEMONICS;
|
||||
|
||||
// Don't emit unresponsive event when showing menu.
|
||||
electron::UnresponsiveSuppressor suppressor;
|
||||
|
||||
// Make sure the Menu object would not be garbage-collected until the callback
|
||||
// has run.
|
||||
base::OnceClosure callback_with_ref = BindSelfToClosure(std::move(callback));
|
||||
atom::UnresponsiveSuppressor suppressor;
|
||||
|
||||
// Show the menu.
|
||||
//
|
||||
// Note that while views::MenuRunner accepts RepeatingCallback as close
|
||||
// callback, it is fine passing OnceCallback to it because we reset the
|
||||
// menu runner immediately when the menu is closed.
|
||||
int32_t window_id = window->weak_map_id();
|
||||
auto close_callback = base::AdaptCallbackForRepeating(
|
||||
base::BindOnce(&MenuViews::OnClosed, weak_factory_.GetWeakPtr(),
|
||||
window_id, std::move(callback_with_ref)));
|
||||
auto close_callback = base::Bind(
|
||||
&MenuViews::OnClosed, weak_factory_.GetWeakPtr(), window_id, callback);
|
||||
menu_runners_[window_id] =
|
||||
std::make_unique<MenuRunner>(model(), flags, std::move(close_callback));
|
||||
std::make_unique<MenuRunner>(model(), flags, close_callback);
|
||||
menu_runners_[window_id]->RunMenuAt(
|
||||
native_window->widget(), nullptr, gfx::Rect(location, gfx::Size()),
|
||||
native_window->widget(), NULL, gfx::Rect(location, gfx::Size()),
|
||||
views::MenuAnchorPosition::kTopLeft, ui::MENU_SOURCE_MOUSE);
|
||||
}
|
||||
|
||||
@@ -78,19 +69,16 @@ void MenuViews::ClosePopupAt(int32_t window_id) {
|
||||
}
|
||||
}
|
||||
|
||||
void MenuViews::OnClosed(int32_t window_id, base::OnceClosure callback) {
|
||||
void MenuViews::OnClosed(int32_t window_id, base::Closure callback) {
|
||||
menu_runners_.erase(window_id);
|
||||
std::move(callback).Run();
|
||||
callback.Run();
|
||||
}
|
||||
|
||||
// static
|
||||
gin::Handle<Menu> Menu::New(gin::Arguments* args) {
|
||||
auto handle = gin::CreateHandle(args->isolate(),
|
||||
static_cast<Menu*>(new MenuViews(args)));
|
||||
gin_helper::CallMethod(args->isolate(), handle.get(), "_init");
|
||||
return handle;
|
||||
mate::WrappableBase* Menu::New(mate::Arguments* args) {
|
||||
return new MenuViews(args->isolate(), args->GetThis());
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace electron
|
||||
} // namespace atom
|
||||
@@ -2,24 +2,24 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef SHELL_BROWSER_API_ELECTRON_API_MENU_VIEWS_H_
|
||||
#define SHELL_BROWSER_API_ELECTRON_API_MENU_VIEWS_H_
|
||||
#ifndef ATOM_BROWSER_API_ATOM_API_MENU_VIEWS_H_
|
||||
#define ATOM_BROWSER_API_ATOM_API_MENU_VIEWS_H_
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
|
||||
#include "atom/browser/api/atom_api_menu.h"
|
||||
#include "base/memory/weak_ptr.h"
|
||||
#include "shell/browser/api/electron_api_menu.h"
|
||||
#include "ui/display/screen.h"
|
||||
#include "ui/views/controls/menu/menu_runner.h"
|
||||
|
||||
namespace electron {
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
class MenuViews : public Menu {
|
||||
public:
|
||||
explicit MenuViews(gin::Arguments* args);
|
||||
MenuViews(v8::Isolate* isolate, v8::Local<v8::Object> wrapper);
|
||||
~MenuViews() override;
|
||||
|
||||
protected:
|
||||
@@ -27,11 +27,11 @@ class MenuViews : public Menu {
|
||||
int x,
|
||||
int y,
|
||||
int positioning_item,
|
||||
base::OnceClosure callback) override;
|
||||
const base::Closure& callback) override;
|
||||
void ClosePopupAt(int32_t window_id) override;
|
||||
|
||||
private:
|
||||
void OnClosed(int32_t window_id, base::OnceClosure callback);
|
||||
void OnClosed(int32_t window_id, base::Closure callback);
|
||||
|
||||
// window ID -> open context menu
|
||||
std::map<int32_t, std::unique_ptr<views::MenuRunner>> menu_runners_;
|
||||
@@ -43,6 +43,6 @@ class MenuViews : public Menu {
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace electron
|
||||
} // namespace atom
|
||||
|
||||
#endif // SHELL_BROWSER_API_ELECTRON_API_MENU_VIEWS_H_
|
||||
#endif // ATOM_BROWSER_API_ATOM_API_MENU_VIEWS_H_
|
||||
64
atom/browser/api/atom_api_net.cc
Normal file
64
atom/browser/api/atom_api_net.cc
Normal file
@@ -0,0 +1,64 @@
|
||||
// Copyright (c) 2016 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/browser/api/atom_api_net.h"
|
||||
#include "atom/browser/api/atom_api_url_request.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
Net::Net(v8::Isolate* isolate) {
|
||||
Init(isolate);
|
||||
}
|
||||
|
||||
Net::~Net() {}
|
||||
|
||||
// static
|
||||
v8::Local<v8::Value> Net::Create(v8::Isolate* isolate) {
|
||||
return mate::CreateHandle(isolate, new Net(isolate)).ToV8();
|
||||
}
|
||||
|
||||
// static
|
||||
void Net::BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype) {
|
||||
prototype->SetClassName(mate::StringToV8(isolate, "Net"));
|
||||
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
||||
.SetProperty("URLRequest", &Net::URLRequest);
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> Net::URLRequest(v8::Isolate* isolate) {
|
||||
return URLRequest::GetConstructor(isolate)
|
||||
->GetFunction(isolate->GetCurrentContext())
|
||||
.ToLocalChecked();
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
|
||||
namespace {
|
||||
|
||||
using atom::api::Net;
|
||||
using atom::api::URLRequest;
|
||||
|
||||
void Initialize(v8::Local<v8::Object> exports,
|
||||
v8::Local<v8::Value> unused,
|
||||
v8::Local<v8::Context> context,
|
||||
void* priv) {
|
||||
v8::Isolate* isolate = context->GetIsolate();
|
||||
|
||||
URLRequest::SetConstructor(isolate, base::Bind(URLRequest::New));
|
||||
|
||||
mate::Dictionary dict(isolate, exports);
|
||||
dict.Set("net", Net::Create(isolate));
|
||||
dict.Set("Net",
|
||||
Net::GetConstructor(isolate)->GetFunction(context).ToLocalChecked());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_net, Initialize)
|
||||
@@ -2,23 +2,23 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef SHELL_BROWSER_API_ELECTRON_API_NET_H_
|
||||
#define SHELL_BROWSER_API_ELECTRON_API_NET_H_
|
||||
#ifndef ATOM_BROWSER_API_ATOM_API_NET_H_
|
||||
#define ATOM_BROWSER_API_ATOM_API_NET_H_
|
||||
|
||||
#include "shell/common/gin_helper/wrappable.h"
|
||||
#include "atom/browser/api/event_emitter.h"
|
||||
|
||||
namespace electron {
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
class Net : public gin_helper::Wrappable<Net> {
|
||||
class Net : public mate::EventEmitter<Net> {
|
||||
public:
|
||||
static v8::Local<v8::Value> Create(v8::Isolate* isolate);
|
||||
|
||||
static void BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype);
|
||||
|
||||
v8::Local<v8::Value> URLLoader(v8::Isolate* isolate);
|
||||
v8::Local<v8::Value> URLRequest(v8::Isolate* isolate);
|
||||
|
||||
protected:
|
||||
explicit Net(v8::Isolate* isolate);
|
||||
@@ -30,6 +30,6 @@ class Net : public gin_helper::Wrappable<Net> {
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace electron
|
||||
} // namespace atom
|
||||
|
||||
#endif // SHELL_BROWSER_API_ELECTRON_API_NET_H_
|
||||
#endif // ATOM_BROWSER_API_ATOM_API_NET_H_
|
||||
140
atom/browser/api/atom_api_net_log.cc
Normal file
140
atom/browser/api/atom_api_net_log.cc
Normal file
@@ -0,0 +1,140 @@
|
||||
// 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/api/atom_api_net_log.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "atom/browser/atom_browser_context.h"
|
||||
#include "atom/browser/net/system_network_context_manager.h"
|
||||
#include "atom/common/native_mate_converters/callback.h"
|
||||
#include "atom/common/native_mate_converters/file_path_converter.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "base/command_line.h"
|
||||
#include "chrome/browser/browser_process.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"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
NetLog::NetLog(v8::Isolate* isolate, AtomBrowserContext* browser_context)
|
||||
: browser_context_(browser_context) {
|
||||
Init(isolate);
|
||||
|
||||
net_log_writer_ = g_browser_process->system_network_context_manager()
|
||||
->GetNetExportFileWriter();
|
||||
net_log_writer_->AddObserver(this);
|
||||
}
|
||||
|
||||
NetLog::~NetLog() {
|
||||
net_log_writer_->RemoveObserver(this);
|
||||
}
|
||||
|
||||
void NetLog::StartLogging(mate::Arguments* args) {
|
||||
base::FilePath log_path;
|
||||
if (!args->GetNext(&log_path) || log_path.empty()) {
|
||||
args->ThrowError("The first parameter must be a valid string");
|
||||
return;
|
||||
}
|
||||
|
||||
auto* network_context =
|
||||
content::BrowserContext::GetDefaultStoragePartition(browser_context_)
|
||||
->GetNetworkContext();
|
||||
|
||||
// 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(), network_context);
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
v8::Local<v8::Promise> NetLog::StopLogging(mate::Arguments* args) {
|
||||
util::Promise promise(isolate());
|
||||
v8::Local<v8::Promise> handle = promise.GetHandle();
|
||||
|
||||
if (IsCurrentlyLogging()) {
|
||||
stop_callback_queue_.emplace_back(std::move(promise));
|
||||
net_log_writer_->StopNetLog(nullptr);
|
||||
} else {
|
||||
promise.Resolve(base::FilePath());
|
||||
}
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
void NetLog::OnNewState(const base::DictionaryValue& state) {
|
||||
net_log_state_ = state.CreateDeepCopy();
|
||||
|
||||
if (stop_callback_queue_.empty())
|
||||
return;
|
||||
|
||||
if (GetLoggingState() == "NOT_LOGGING") {
|
||||
for (auto& promise : stop_callback_queue_) {
|
||||
// TODO(zcbenz): Remove the use of CopyablePromise when the
|
||||
// GetFilePathToCompletedLog API accepts OnceCallback.
|
||||
net_log_writer_->GetFilePathToCompletedLog(base::Bind(
|
||||
util::CopyablePromise::ResolveCopyablePromise<const base::FilePath&>,
|
||||
util::CopyablePromise(promise)));
|
||||
}
|
||||
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
|
||||
void NetLog::BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype) {
|
||||
prototype->SetClassName(mate::StringToV8(isolate, "NetLog"));
|
||||
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
||||
.SetProperty("currentlyLogging", &NetLog::IsCurrentlyLogging)
|
||||
.SetProperty("currentlyLoggingPath", &NetLog::GetCurrentlyLoggingPath)
|
||||
.SetMethod("startLogging", &NetLog::StartLogging)
|
||||
.SetMethod("stopLogging", &NetLog::StopLogging);
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
60
atom/browser/api/atom_api_net_log.h
Normal file
60
atom/browser/api/atom_api_net_log.h
Normal file
@@ -0,0 +1,60 @@
|
||||
// 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_API_ATOM_API_NET_LOG_H_
|
||||
#define ATOM_BROWSER_API_ATOM_API_NET_LOG_H_
|
||||
|
||||
#include <list>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "atom/browser/api/trackable_object.h"
|
||||
#include "atom/common/promise_util.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::TrackableObject<NetLog>,
|
||||
public net_log::NetExportFileWriter::StateObserver {
|
||||
public:
|
||||
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);
|
||||
std::string GetLoggingState() const;
|
||||
bool IsCurrentlyLogging() const;
|
||||
std::string GetCurrentlyLoggingPath() const;
|
||||
v8::Local<v8::Promise> StopLogging(mate::Arguments* args);
|
||||
|
||||
protected:
|
||||
explicit NetLog(v8::Isolate* isolate, AtomBrowserContext* browser_context);
|
||||
~NetLog() override;
|
||||
|
||||
// net_log::NetExportFileWriter::StateObserver implementation
|
||||
void OnNewState(const base::DictionaryValue& state) override;
|
||||
|
||||
private:
|
||||
AtomBrowserContext* browser_context_;
|
||||
net_log::NetExportFileWriter* net_log_writer_;
|
||||
std::list<atom::util::Promise> stop_callback_queue_;
|
||||
std::unique_ptr<base::DictionaryValue> net_log_state_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(NetLog);
|
||||
};
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_API_ATOM_API_NET_LOG_H_
|
||||
@@ -2,28 +2,29 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "shell/browser/api/electron_api_notification.h"
|
||||
#include "atom/browser/api/atom_api_notification.h"
|
||||
|
||||
#include "atom/browser/api/atom_api_menu.h"
|
||||
#include "atom/browser/atom_browser_client.h"
|
||||
#include "atom/browser/browser.h"
|
||||
#include "atom/common/native_mate_converters/gfx_converter.h"
|
||||
#include "atom/common/native_mate_converters/image_converter.h"
|
||||
#include "atom/common/native_mate_converters/string16_converter.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "base/guid.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "gin/handle.h"
|
||||
#include "shell/browser/api/electron_api_menu.h"
|
||||
#include "shell/browser/browser.h"
|
||||
#include "shell/browser/electron_browser_client.h"
|
||||
#include "shell/common/gin_converters/image_converter.h"
|
||||
#include "shell/common/gin_helper/dictionary.h"
|
||||
#include "shell/common/gin_helper/object_template_builder.h"
|
||||
#include "shell/common/node_includes.h"
|
||||
#include "native_mate/constructor.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "native_mate/object_template_builder.h"
|
||||
#include "url/gurl.h"
|
||||
|
||||
namespace gin {
|
||||
|
||||
namespace mate {
|
||||
template <>
|
||||
struct Converter<electron::NotificationAction> {
|
||||
struct Converter<atom::NotificationAction> {
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
electron::NotificationAction* out) {
|
||||
gin::Dictionary dict(isolate);
|
||||
atom::NotificationAction* out) {
|
||||
mate::Dictionary dict;
|
||||
if (!ConvertFromV8(isolate, val, &dict))
|
||||
return false;
|
||||
|
||||
@@ -35,27 +36,28 @@ struct Converter<electron::NotificationAction> {
|
||||
}
|
||||
|
||||
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
||||
electron::NotificationAction val) {
|
||||
gin::Dictionary dict = gin::Dictionary::CreateEmpty(isolate);
|
||||
atom::NotificationAction val) {
|
||||
mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate);
|
||||
dict.Set("text", val.text);
|
||||
dict.Set("type", val.type);
|
||||
return ConvertToV8(isolate, dict);
|
||||
return dict.GetHandle();
|
||||
}
|
||||
};
|
||||
} // namespace mate
|
||||
|
||||
} // namespace gin
|
||||
|
||||
namespace electron {
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
gin::WrapperInfo Notification::kWrapperInfo = {gin::kEmbedderNativeGin};
|
||||
Notification::Notification(v8::Isolate* isolate,
|
||||
v8::Local<v8::Object> wrapper,
|
||||
mate::Arguments* args) {
|
||||
InitWith(isolate, wrapper);
|
||||
|
||||
Notification::Notification(gin::Arguments* args) {
|
||||
presenter_ = static_cast<ElectronBrowserClient*>(ElectronBrowserClient::Get())
|
||||
presenter_ = static_cast<AtomBrowserClient*>(AtomBrowserClient::Get())
|
||||
->GetNotificationPresenter();
|
||||
|
||||
gin::Dictionary opts(nullptr);
|
||||
mate::Dictionary opts;
|
||||
if (args->GetNext(&opts)) {
|
||||
opts.Get("title", &title_);
|
||||
opts.Get("subtitle", &subtitle_);
|
||||
@@ -66,9 +68,7 @@ Notification::Notification(gin::Arguments* args) {
|
||||
}
|
||||
opts.Get("silent", &silent_);
|
||||
opts.Get("replyPlaceholder", &reply_placeholder_);
|
||||
opts.Get("urgency", &urgency_);
|
||||
opts.Get("hasReply", &has_reply_);
|
||||
opts.Get("timeoutType", &timeout_type_);
|
||||
opts.Get("actions", &actions_);
|
||||
opts.Get("sound", &sound_);
|
||||
opts.Get("closeButtonText", &close_button_text_);
|
||||
@@ -81,13 +81,12 @@ Notification::~Notification() {
|
||||
}
|
||||
|
||||
// static
|
||||
gin::Handle<Notification> Notification::New(gin_helper::ErrorThrower thrower,
|
||||
gin::Arguments* args) {
|
||||
mate::WrappableBase* Notification::New(mate::Arguments* args) {
|
||||
if (!Browser::Get()->is_ready()) {
|
||||
thrower.ThrowError("Cannot create Notification before app is ready");
|
||||
return gin::Handle<Notification>();
|
||||
args->ThrowError("Cannot create Notification before app is ready");
|
||||
return nullptr;
|
||||
}
|
||||
return gin::CreateHandle(thrower.isolate(), new Notification(args));
|
||||
return new Notification(args->isolate(), args->GetThis(), args);
|
||||
}
|
||||
|
||||
// Getters
|
||||
@@ -111,10 +110,6 @@ bool Notification::GetHasReply() const {
|
||||
return has_reply_;
|
||||
}
|
||||
|
||||
base::string16 Notification::GetTimeoutType() const {
|
||||
return timeout_type_;
|
||||
}
|
||||
|
||||
base::string16 Notification::GetReplyPlaceholder() const {
|
||||
return reply_placeholder_;
|
||||
}
|
||||
@@ -123,11 +118,7 @@ base::string16 Notification::GetSound() const {
|
||||
return sound_;
|
||||
}
|
||||
|
||||
base::string16 Notification::GetUrgency() const {
|
||||
return urgency_;
|
||||
}
|
||||
|
||||
std::vector<electron::NotificationAction> Notification::GetActions() const {
|
||||
std::vector<atom::NotificationAction> Notification::GetActions() const {
|
||||
return actions_;
|
||||
}
|
||||
|
||||
@@ -156,10 +147,6 @@ void Notification::SetHasReply(bool new_has_reply) {
|
||||
has_reply_ = new_has_reply;
|
||||
}
|
||||
|
||||
void Notification::SetTimeoutType(const base::string16& new_timeout_type) {
|
||||
timeout_type_ = new_timeout_type;
|
||||
}
|
||||
|
||||
void Notification::SetReplyPlaceholder(const base::string16& new_placeholder) {
|
||||
reply_placeholder_ = new_placeholder;
|
||||
}
|
||||
@@ -168,12 +155,8 @@ void Notification::SetSound(const base::string16& new_sound) {
|
||||
sound_ = new_sound;
|
||||
}
|
||||
|
||||
void Notification::SetUrgency(const base::string16& new_urgency) {
|
||||
urgency_ = new_urgency;
|
||||
}
|
||||
|
||||
void Notification::SetActions(
|
||||
const std::vector<electron::NotificationAction>& actions) {
|
||||
const std::vector<atom::NotificationAction>& actions) {
|
||||
actions_ = actions;
|
||||
}
|
||||
|
||||
@@ -206,7 +189,6 @@ void Notification::NotificationClosed() {
|
||||
void Notification::Close() {
|
||||
if (notification_) {
|
||||
notification_->Dismiss();
|
||||
notification_->set_delegate(nullptr);
|
||||
notification_.reset();
|
||||
}
|
||||
}
|
||||
@@ -217,7 +199,7 @@ void Notification::Show() {
|
||||
if (presenter_) {
|
||||
notification_ = presenter_->CreateNotification(this, base::GenerateGUID());
|
||||
if (notification_) {
|
||||
electron::NotificationOptions options;
|
||||
atom::NotificationOptions options;
|
||||
options.title = title_;
|
||||
options.subtitle = subtitle_;
|
||||
options.msg = body_;
|
||||
@@ -225,26 +207,26 @@ void Notification::Show() {
|
||||
options.icon = icon_.AsBitmap();
|
||||
options.silent = silent_;
|
||||
options.has_reply = has_reply_;
|
||||
options.timeout_type = timeout_type_;
|
||||
options.reply_placeholder = reply_placeholder_;
|
||||
options.actions = actions_;
|
||||
options.sound = sound_;
|
||||
options.close_button_text = close_button_text_;
|
||||
options.urgency = urgency_;
|
||||
notification_->Show(options);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Notification::IsSupported() {
|
||||
return !!static_cast<ElectronBrowserClient*>(ElectronBrowserClient::Get())
|
||||
return !!static_cast<AtomBrowserClient*>(AtomBrowserClient::Get())
|
||||
->GetNotificationPresenter();
|
||||
}
|
||||
|
||||
v8::Local<v8::ObjectTemplate> Notification::FillObjectTemplate(
|
||||
v8::Isolate* isolate,
|
||||
v8::Local<v8::ObjectTemplate> templ) {
|
||||
return gin::ObjectTemplateBuilder(isolate, "Notification", templ)
|
||||
// static
|
||||
void Notification::BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype) {
|
||||
prototype->SetClassName(mate::StringToV8(isolate, "Notification"));
|
||||
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
||||
.MakeDestroyable()
|
||||
.SetMethod("show", &Notification::Show)
|
||||
.SetMethod("close", &Notification::Close)
|
||||
.SetProperty("title", &Notification::GetTitle, &Notification::SetTitle)
|
||||
@@ -254,38 +236,38 @@ v8::Local<v8::ObjectTemplate> Notification::FillObjectTemplate(
|
||||
.SetProperty("silent", &Notification::GetSilent, &Notification::SetSilent)
|
||||
.SetProperty("hasReply", &Notification::GetHasReply,
|
||||
&Notification::SetHasReply)
|
||||
.SetProperty("timeoutType", &Notification::GetTimeoutType,
|
||||
&Notification::SetTimeoutType)
|
||||
.SetProperty("replyPlaceholder", &Notification::GetReplyPlaceholder,
|
||||
&Notification::SetReplyPlaceholder)
|
||||
.SetProperty("urgency", &Notification::GetUrgency,
|
||||
&Notification::SetUrgency)
|
||||
.SetProperty("sound", &Notification::GetSound, &Notification::SetSound)
|
||||
.SetProperty("actions", &Notification::GetActions,
|
||||
&Notification::SetActions)
|
||||
.SetProperty("closeButtonText", &Notification::GetCloseButtonText,
|
||||
&Notification::SetCloseButtonText)
|
||||
.Build();
|
||||
&Notification::SetCloseButtonText);
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace electron
|
||||
} // namespace atom
|
||||
|
||||
namespace {
|
||||
|
||||
using electron::api::Notification;
|
||||
using atom::api::Notification;
|
||||
|
||||
void Initialize(v8::Local<v8::Object> exports,
|
||||
v8::Local<v8::Value> unused,
|
||||
v8::Local<v8::Context> context,
|
||||
void* priv) {
|
||||
v8::Isolate* isolate = context->GetIsolate();
|
||||
gin_helper::Dictionary dict(isolate, exports);
|
||||
dict.Set("Notification", Notification::GetConstructor(context));
|
||||
Notification::SetConstructor(isolate, base::Bind(&Notification::New));
|
||||
|
||||
mate::Dictionary dict(isolate, exports);
|
||||
dict.Set("Notification", Notification::GetConstructor(isolate)
|
||||
->GetFunction(context)
|
||||
.ToLocalChecked());
|
||||
|
||||
dict.SetMethod("isSupported", &Notification::IsSupported);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(electron_common_notification, Initialize)
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_common_notification, Initialize)
|
||||
97
atom/browser/api/atom_api_notification.h
Normal file
97
atom/browser/api/atom_api_notification.h
Normal file
@@ -0,0 +1,97 @@
|
||||
// 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_BROWSER_API_ATOM_API_NOTIFICATION_H_
|
||||
#define ATOM_BROWSER_API_ATOM_API_NOTIFICATION_H_
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "atom/browser/api/trackable_object.h"
|
||||
#include "atom/browser/notifications/notification.h"
|
||||
#include "atom/browser/notifications/notification_delegate.h"
|
||||
#include "atom/browser/notifications/notification_presenter.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "native_mate/handle.h"
|
||||
#include "ui/gfx/image/image.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
class Notification : public mate::TrackableObject<Notification>,
|
||||
public NotificationDelegate {
|
||||
public:
|
||||
static mate::WrappableBase* New(mate::Arguments* args);
|
||||
static bool IsSupported();
|
||||
|
||||
static void BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype);
|
||||
|
||||
// NotificationDelegate:
|
||||
void NotificationAction(int index) override;
|
||||
void NotificationClick() override;
|
||||
void NotificationReplied(const std::string& reply) override;
|
||||
void NotificationDisplayed() override;
|
||||
void NotificationDestroyed() override;
|
||||
void NotificationClosed() override;
|
||||
|
||||
protected:
|
||||
Notification(v8::Isolate* isolate,
|
||||
v8::Local<v8::Object> wrapper,
|
||||
mate::Arguments* args);
|
||||
~Notification() override;
|
||||
|
||||
void Show();
|
||||
void Close();
|
||||
|
||||
// Prop Getters
|
||||
base::string16 GetTitle() const;
|
||||
base::string16 GetSubtitle() const;
|
||||
base::string16 GetBody() const;
|
||||
bool GetSilent() const;
|
||||
bool GetHasReply() const;
|
||||
base::string16 GetReplyPlaceholder() const;
|
||||
base::string16 GetSound() const;
|
||||
std::vector<atom::NotificationAction> GetActions() const;
|
||||
base::string16 GetCloseButtonText() const;
|
||||
|
||||
// Prop Setters
|
||||
void SetTitle(const base::string16& new_title);
|
||||
void SetSubtitle(const base::string16& new_subtitle);
|
||||
void SetBody(const base::string16& new_body);
|
||||
void SetSilent(bool new_silent);
|
||||
void SetHasReply(bool new_has_reply);
|
||||
void SetReplyPlaceholder(const base::string16& new_reply_placeholder);
|
||||
void SetSound(const base::string16& sound);
|
||||
void SetActions(const std::vector<atom::NotificationAction>& actions);
|
||||
void SetCloseButtonText(const base::string16& text);
|
||||
|
||||
private:
|
||||
base::string16 title_;
|
||||
base::string16 subtitle_;
|
||||
base::string16 body_;
|
||||
gfx::Image icon_;
|
||||
base::string16 icon_path_;
|
||||
bool has_icon_ = false;
|
||||
bool silent_ = false;
|
||||
bool has_reply_ = false;
|
||||
base::string16 reply_placeholder_;
|
||||
base::string16 sound_;
|
||||
std::vector<atom::NotificationAction> actions_;
|
||||
base::string16 close_button_text_;
|
||||
|
||||
atom::NotificationPresenter* presenter_;
|
||||
|
||||
base::WeakPtr<atom::Notification> notification_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(Notification);
|
||||
};
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_API_ATOM_API_NOTIFICATION_H_
|
||||
150
atom/browser/api/atom_api_power_monitor.cc
Normal file
150
atom/browser/api/atom_api_power_monitor.cc
Normal file
@@ -0,0 +1,150 @@
|
||||
// Copyright (c) 2013 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/browser/api/atom_api_power_monitor.h"
|
||||
|
||||
#include "atom/browser/browser.h"
|
||||
#include "atom/common/native_mate_converters/callback.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "base/power_monitor/power_monitor.h"
|
||||
#include "base/power_monitor/power_monitor_device_source.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
|
||||
namespace mate {
|
||||
template <>
|
||||
struct Converter<ui::IdleState> {
|
||||
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
||||
const ui::IdleState& in) {
|
||||
switch (in) {
|
||||
case ui::IDLE_STATE_ACTIVE:
|
||||
return mate::StringToV8(isolate, "active");
|
||||
case ui::IDLE_STATE_IDLE:
|
||||
return mate::StringToV8(isolate, "idle");
|
||||
case ui::IDLE_STATE_LOCKED:
|
||||
return mate::StringToV8(isolate, "locked");
|
||||
case ui::IDLE_STATE_UNKNOWN:
|
||||
default:
|
||||
return mate::StringToV8(isolate, "unknown");
|
||||
}
|
||||
}
|
||||
};
|
||||
} // namespace mate
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
PowerMonitor::PowerMonitor(v8::Isolate* isolate) {
|
||||
#if defined(OS_LINUX)
|
||||
SetShutdownHandler(
|
||||
base::Bind(&PowerMonitor::ShouldShutdown, base::Unretained(this)));
|
||||
#elif defined(OS_MACOSX)
|
||||
Browser::Get()->SetShutdownHandler(
|
||||
base::Bind(&PowerMonitor::ShouldShutdown, base::Unretained(this)));
|
||||
#endif
|
||||
base::PowerMonitor::Get()->AddObserver(this);
|
||||
Init(isolate);
|
||||
#if defined(OS_MACOSX) || defined(OS_WIN)
|
||||
InitPlatformSpecificMonitors();
|
||||
#endif
|
||||
}
|
||||
|
||||
PowerMonitor::~PowerMonitor() {
|
||||
base::PowerMonitor::Get()->RemoveObserver(this);
|
||||
}
|
||||
|
||||
bool PowerMonitor::ShouldShutdown() {
|
||||
return !Emit("shutdown");
|
||||
}
|
||||
|
||||
#if defined(OS_LINUX)
|
||||
void PowerMonitor::BlockShutdown() {
|
||||
PowerObserverLinux::BlockShutdown();
|
||||
}
|
||||
|
||||
void PowerMonitor::UnblockShutdown() {
|
||||
PowerObserverLinux::UnblockShutdown();
|
||||
}
|
||||
#endif
|
||||
|
||||
void PowerMonitor::OnPowerStateChange(bool on_battery_power) {
|
||||
if (on_battery_power)
|
||||
Emit("on-battery");
|
||||
else
|
||||
Emit("on-ac");
|
||||
}
|
||||
|
||||
void PowerMonitor::OnSuspend() {
|
||||
Emit("suspend");
|
||||
}
|
||||
|
||||
void PowerMonitor::OnResume() {
|
||||
Emit("resume");
|
||||
}
|
||||
|
||||
ui::IdleState PowerMonitor::GetSystemIdleState(v8::Isolate* isolate,
|
||||
int idle_threshold) {
|
||||
if (idle_threshold > 0) {
|
||||
return ui::CalculateIdleState(idle_threshold);
|
||||
} else {
|
||||
isolate->ThrowException(v8::Exception::TypeError(mate::StringToV8(
|
||||
isolate, "Invalid idle threshold, must be greater than 0")));
|
||||
return ui::IDLE_STATE_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
int PowerMonitor::GetSystemIdleTime() {
|
||||
return ui::CalculateIdleTime();
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Local<v8::Value> PowerMonitor::Create(v8::Isolate* isolate) {
|
||||
if (!Browser::Get()->is_ready()) {
|
||||
isolate->ThrowException(v8::Exception::Error(mate::StringToV8(
|
||||
isolate,
|
||||
"Cannot require \"powerMonitor\" module before app is ready")));
|
||||
return v8::Null(isolate);
|
||||
}
|
||||
|
||||
return mate::CreateHandle(isolate, new PowerMonitor(isolate)).ToV8();
|
||||
}
|
||||
|
||||
// static
|
||||
void PowerMonitor::BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype) {
|
||||
prototype->SetClassName(mate::StringToV8(isolate, "PowerMonitor"));
|
||||
|
||||
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
||||
.MakeDestroyable()
|
||||
#if defined(OS_LINUX)
|
||||
.SetMethod("blockShutdown", &PowerMonitor::BlockShutdown)
|
||||
.SetMethod("unblockShutdown", &PowerMonitor::UnblockShutdown)
|
||||
#endif
|
||||
.SetMethod("getSystemIdleState", &PowerMonitor::GetSystemIdleState)
|
||||
.SetMethod("getSystemIdleTime", &PowerMonitor::GetSystemIdleTime);
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
|
||||
namespace {
|
||||
|
||||
using atom::api::PowerMonitor;
|
||||
|
||||
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("powerMonitor", PowerMonitor::Create(isolate));
|
||||
dict.Set("PowerMonitor", PowerMonitor::GetConstructor(isolate)
|
||||
->GetFunction(context)
|
||||
.ToLocalChecked());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_power_monitor, Initialize)
|
||||
@@ -2,47 +2,40 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef SHELL_BROWSER_API_ELECTRON_API_POWER_MONITOR_H_
|
||||
#define SHELL_BROWSER_API_ELECTRON_API_POWER_MONITOR_H_
|
||||
#ifndef ATOM_BROWSER_API_ATOM_API_POWER_MONITOR_H_
|
||||
#define ATOM_BROWSER_API_ATOM_API_POWER_MONITOR_H_
|
||||
|
||||
#include "base/power_monitor/power_observer.h"
|
||||
#include "gin/wrappable.h"
|
||||
#include "shell/browser/event_emitter_mixin.h"
|
||||
#include "shell/common/gin_helper/pinnable.h"
|
||||
#include "atom/browser/api/trackable_object.h"
|
||||
#include "atom/browser/lib/power_observer.h"
|
||||
#include "base/compiler_specific.h"
|
||||
#include "native_mate/handle.h"
|
||||
#include "ui/base/idle/idle.h"
|
||||
|
||||
#if defined(OS_LINUX)
|
||||
#include "shell/browser/lib/power_observer_linux.h"
|
||||
#endif
|
||||
|
||||
namespace electron {
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
class PowerMonitor : public gin::Wrappable<PowerMonitor>,
|
||||
public gin_helper::EventEmitterMixin<PowerMonitor>,
|
||||
public gin_helper::Pinnable<PowerMonitor>,
|
||||
public base::PowerObserver {
|
||||
class PowerMonitor : public mate::TrackableObject<PowerMonitor>,
|
||||
public PowerObserver {
|
||||
public:
|
||||
static v8::Local<v8::Value> Create(v8::Isolate* isolate);
|
||||
|
||||
// gin::Wrappable
|
||||
static gin::WrapperInfo kWrapperInfo;
|
||||
gin::ObjectTemplateBuilder GetObjectTemplateBuilder(
|
||||
v8::Isolate* isolate) override;
|
||||
const char* GetTypeName() override;
|
||||
static void BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype);
|
||||
|
||||
private:
|
||||
protected:
|
||||
explicit PowerMonitor(v8::Isolate* isolate);
|
||||
~PowerMonitor() override;
|
||||
|
||||
#if defined(OS_LINUX)
|
||||
void SetListeningForShutdown(bool);
|
||||
#endif
|
||||
|
||||
// Called by native calles.
|
||||
bool ShouldShutdown();
|
||||
|
||||
#if defined(OS_LINUX)
|
||||
// Private JS APIs.
|
||||
void BlockShutdown();
|
||||
void UnblockShutdown();
|
||||
#endif
|
||||
|
||||
#if defined(OS_MACOSX) || defined(OS_WIN)
|
||||
void InitPlatformSpecificMonitors();
|
||||
#endif
|
||||
@@ -52,6 +45,10 @@ class PowerMonitor : public gin::Wrappable<PowerMonitor>,
|
||||
void OnSuspend() override;
|
||||
void OnResume() override;
|
||||
|
||||
private:
|
||||
ui::IdleState GetSystemIdleState(v8::Isolate* isolate, int idle_threshold);
|
||||
int GetSystemIdleTime();
|
||||
|
||||
#if defined(OS_WIN)
|
||||
// Static callback invoked when a message comes in to our messaging window.
|
||||
static LRESULT CALLBACK WndProcStatic(HWND hwnd,
|
||||
@@ -74,17 +71,11 @@ class PowerMonitor : public gin::Wrappable<PowerMonitor>,
|
||||
HWND window_;
|
||||
#endif
|
||||
|
||||
#if defined(OS_LINUX)
|
||||
PowerObserverLinux power_observer_linux_{this};
|
||||
#endif
|
||||
|
||||
v8::Global<v8::Value> pinned_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(PowerMonitor);
|
||||
};
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace electron
|
||||
} // namespace atom
|
||||
|
||||
#endif // SHELL_BROWSER_API_ELECTRON_API_POWER_MONITOR_H_
|
||||
#endif // ATOM_BROWSER_API_ATOM_API_POWER_MONITOR_H_
|
||||
@@ -2,19 +2,17 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "shell/browser/api/electron_api_power_monitor.h"
|
||||
#include "atom/browser/api/atom_api_power_monitor.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#import <ApplicationServices/ApplicationServices.h>
|
||||
#include <ApplicationServices/ApplicationServices.h>
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
@interface MacLockMonitor : NSObject {
|
||||
@private
|
||||
std::vector<electron::api::PowerMonitor*> emitters;
|
||||
std::vector<atom::api::PowerMonitor*> emitters;
|
||||
}
|
||||
|
||||
- (void)addEmitter:(electron::api::PowerMonitor*)monitor_;
|
||||
- (void)addEmitter:(atom::api::PowerMonitor*)monitor_;
|
||||
|
||||
@end
|
||||
|
||||
@@ -24,27 +22,14 @@
|
||||
if ((self = [super init])) {
|
||||
NSDistributedNotificationCenter* distCenter =
|
||||
[NSDistributedNotificationCenter defaultCenter];
|
||||
// A notification that the screen was locked.
|
||||
[distCenter addObserver:self
|
||||
selector:@selector(onScreenLocked:)
|
||||
name:@"com.apple.screenIsLocked"
|
||||
object:nil];
|
||||
// A notification that the screen was unlocked by the user.
|
||||
[distCenter addObserver:self
|
||||
selector:@selector(onScreenUnlocked:)
|
||||
name:@"com.apple.screenIsUnlocked"
|
||||
object:nil];
|
||||
// A notification that the workspace posts before the machine goes to sleep.
|
||||
[distCenter addObserver:self
|
||||
selector:@selector(isSuspending:)
|
||||
name:NSWorkspaceWillSleepNotification
|
||||
object:nil];
|
||||
// A notification that the workspace posts when the machine wakes from
|
||||
// sleep.
|
||||
[distCenter addObserver:self
|
||||
selector:@selector(isResuming:)
|
||||
name:NSWorkspaceDidWakeNotification
|
||||
object:nil];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
@@ -54,37 +39,25 @@
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (void)addEmitter:(electron::api::PowerMonitor*)monitor_ {
|
||||
- (void)addEmitter:(atom::api::PowerMonitor*)monitor_ {
|
||||
self->emitters.push_back(monitor_);
|
||||
}
|
||||
|
||||
- (void)isSuspending:(NSNotification*)notify {
|
||||
for (auto* emitter : self->emitters) {
|
||||
emitter->Emit("suspend");
|
||||
}
|
||||
}
|
||||
|
||||
- (void)isResuming:(NSNotification*)notify {
|
||||
for (auto* emitter : self->emitters) {
|
||||
emitter->Emit("resume");
|
||||
}
|
||||
}
|
||||
|
||||
- (void)onScreenLocked:(NSNotification*)notification {
|
||||
for (auto* emitter : self->emitters) {
|
||||
for (auto*& emitter : self->emitters) {
|
||||
emitter->Emit("lock-screen");
|
||||
}
|
||||
}
|
||||
|
||||
- (void)onScreenUnlocked:(NSNotification*)notification {
|
||||
for (auto* emitter : self->emitters) {
|
||||
for (auto*& emitter : self->emitters) {
|
||||
emitter->Emit("unlock-screen");
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
namespace electron {
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
@@ -98,4 +71,4 @@ void PowerMonitor::InitPlatformSpecificMonitors() {
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace electron
|
||||
} // namespace atom
|
||||
@@ -2,17 +2,16 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "shell/browser/api/electron_api_power_monitor.h"
|
||||
#include "atom/browser/api/atom_api_power_monitor.h"
|
||||
|
||||
#include <windows.h>
|
||||
#include <wtsapi32.h>
|
||||
|
||||
#include "base/win/windows_types.h"
|
||||
#include "base/win/wrapped_window_proc.h"
|
||||
#include "ui/base/win/shell.h"
|
||||
#include "ui/gfx/win/hwnd_util.h"
|
||||
|
||||
namespace electron {
|
||||
namespace atom {
|
||||
|
||||
namespace {
|
||||
|
||||
@@ -35,7 +34,7 @@ void PowerMonitor::InitPlatformSpecificMonitors() {
|
||||
// session lock and unlock events.
|
||||
window_ = CreateWindow(MAKEINTATOM(atom_), 0, 0, 0, 0, 0, 0, HWND_MESSAGE, 0,
|
||||
instance_, 0);
|
||||
gfx::CheckWindowCreated(window_, ::GetLastError());
|
||||
gfx::CheckWindowCreated(window_);
|
||||
gfx::SetWindowUserData(window_, this);
|
||||
|
||||
// Tel windows we want to be notified with session events
|
||||
@@ -59,26 +58,10 @@ LRESULT CALLBACK PowerMonitor::WndProc(HWND hwnd,
|
||||
WPARAM wparam,
|
||||
LPARAM lparam) {
|
||||
if (message == WM_WTSSESSION_CHANGE) {
|
||||
bool should_treat_as_current_session = true;
|
||||
DWORD current_session_id = 0;
|
||||
if (!::ProcessIdToSessionId(::GetCurrentProcessId(), ¤t_session_id)) {
|
||||
LOG(ERROR) << "ProcessIdToSessionId failed, assuming current session";
|
||||
} else {
|
||||
should_treat_as_current_session =
|
||||
(static_cast<DWORD>(lparam) == current_session_id);
|
||||
}
|
||||
if (should_treat_as_current_session) {
|
||||
if (wparam == WTS_SESSION_LOCK) {
|
||||
Emit("lock-screen");
|
||||
} else if (wparam == WTS_SESSION_UNLOCK) {
|
||||
Emit("unlock-screen");
|
||||
}
|
||||
}
|
||||
} else if (message == WM_POWERBROADCAST) {
|
||||
if (wparam == PBT_APMRESUMEAUTOMATIC) {
|
||||
Emit("resume");
|
||||
} else if (wparam == PBT_APMSUSPEND) {
|
||||
Emit("suspend");
|
||||
if (wparam == WTS_SESSION_LOCK) {
|
||||
Emit("lock-screen");
|
||||
} else if (wparam == WTS_SESSION_UNLOCK) {
|
||||
Emit("unlock-screen");
|
||||
}
|
||||
}
|
||||
return ::DefWindowProc(hwnd, message, wparam, lparam);
|
||||
@@ -86,4 +69,4 @@ LRESULT CALLBACK PowerMonitor::WndProc(HWND hwnd,
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace electron
|
||||
} // namespace atom
|
||||
@@ -2,21 +2,20 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "shell/browser/api/electron_api_power_save_blocker.h"
|
||||
#include "atom/browser/api/atom_api_power_save_blocker.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "base/bind_helpers.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "base/task/post_task.h"
|
||||
#include "base/threading/thread_task_runner_handle.h"
|
||||
#include "content/public/browser/device_service.h"
|
||||
#include "gin/dictionary.h"
|
||||
#include "gin/function_template.h"
|
||||
#include "content/public/common/service_manager_connection.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "services/device/public/mojom/constants.mojom.h"
|
||||
#include "services/device/public/mojom/wake_lock_provider.mojom.h"
|
||||
#include "services/service_manager/public/cpp/connector.h"
|
||||
#include "shell/common/node_includes.h"
|
||||
|
||||
namespace gin {
|
||||
namespace mate {
|
||||
|
||||
template <>
|
||||
struct Converter<device::mojom::WakeLockType> {
|
||||
@@ -36,19 +35,19 @@ struct Converter<device::mojom::WakeLockType> {
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace gin
|
||||
} // namespace mate
|
||||
|
||||
namespace electron {
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
gin::WrapperInfo PowerSaveBlocker::kWrapperInfo = {gin::kEmbedderNativeGin};
|
||||
|
||||
PowerSaveBlocker::PowerSaveBlocker(v8::Isolate* isolate)
|
||||
: current_lock_type_(device::mojom::WakeLockType::kPreventAppSuspension),
|
||||
is_wake_lock_active_(false) {}
|
||||
is_wake_lock_active_(false) {
|
||||
Init(isolate);
|
||||
}
|
||||
|
||||
PowerSaveBlocker::~PowerSaveBlocker() = default;
|
||||
PowerSaveBlocker::~PowerSaveBlocker() {}
|
||||
|
||||
void PowerSaveBlocker::UpdatePowerSaveBlocker() {
|
||||
if (wake_lock_types_.empty()) {
|
||||
@@ -86,14 +85,17 @@ void PowerSaveBlocker::UpdatePowerSaveBlocker() {
|
||||
|
||||
device::mojom::WakeLock* PowerSaveBlocker::GetWakeLock() {
|
||||
if (!wake_lock_) {
|
||||
mojo::Remote<device::mojom::WakeLockProvider> wake_lock_provider;
|
||||
content::GetDeviceService().BindWakeLockProvider(
|
||||
wake_lock_provider.BindNewPipeAndPassReceiver());
|
||||
device::mojom::WakeLockProviderPtr wake_lock_provider;
|
||||
DCHECK(content::ServiceManagerConnection::GetForProcess());
|
||||
auto* connector =
|
||||
content::ServiceManagerConnection::GetForProcess()->GetConnector();
|
||||
connector->BindInterface(device::mojom::kServiceName,
|
||||
mojo::MakeRequest(&wake_lock_provider));
|
||||
|
||||
wake_lock_provider->GetWakeLockWithoutContext(
|
||||
device::mojom::WakeLockType::kPreventAppSuspension,
|
||||
device::mojom::WakeLockReason::kOther, ELECTRON_PRODUCT_NAME,
|
||||
wake_lock_.BindNewPipeAndPassReceiver());
|
||||
device::mojom::WakeLockReason::kOther, ATOM_PRODUCT_NAME,
|
||||
mojo::MakeRequest(&wake_lock_));
|
||||
}
|
||||
return wake_lock_.get();
|
||||
}
|
||||
@@ -116,13 +118,16 @@ bool PowerSaveBlocker::IsStarted(int id) {
|
||||
}
|
||||
|
||||
// static
|
||||
gin::Handle<PowerSaveBlocker> PowerSaveBlocker::Create(v8::Isolate* isolate) {
|
||||
return gin::CreateHandle(isolate, new PowerSaveBlocker(isolate));
|
||||
mate::Handle<PowerSaveBlocker> PowerSaveBlocker::Create(v8::Isolate* isolate) {
|
||||
return mate::CreateHandle(isolate, new PowerSaveBlocker(isolate));
|
||||
}
|
||||
|
||||
gin::ObjectTemplateBuilder PowerSaveBlocker::GetObjectTemplateBuilder(
|
||||
v8::Isolate* isolate) {
|
||||
return gin::Wrappable<PowerSaveBlocker>::GetObjectTemplateBuilder(isolate)
|
||||
// static
|
||||
void PowerSaveBlocker::BuildPrototype(
|
||||
v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype) {
|
||||
prototype->SetClassName(mate::StringToV8(isolate, "PowerSaveBlocker"));
|
||||
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
||||
.SetMethod("start", &PowerSaveBlocker::Start)
|
||||
.SetMethod("stop", &PowerSaveBlocker::Stop)
|
||||
.SetMethod("isStarted", &PowerSaveBlocker::IsStarted);
|
||||
@@ -130,7 +135,7 @@ gin::ObjectTemplateBuilder PowerSaveBlocker::GetObjectTemplateBuilder(
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace electron
|
||||
} // namespace atom
|
||||
|
||||
namespace {
|
||||
|
||||
@@ -139,12 +144,10 @@ void Initialize(v8::Local<v8::Object> exports,
|
||||
v8::Local<v8::Context> context,
|
||||
void* priv) {
|
||||
v8::Isolate* isolate = context->GetIsolate();
|
||||
gin::Dictionary dict(isolate, exports);
|
||||
dict.Set("powerSaveBlocker",
|
||||
electron::api::PowerSaveBlocker::Create(isolate));
|
||||
mate::Dictionary dict(isolate, exports);
|
||||
dict.Set("powerSaveBlocker", atom::api::PowerSaveBlocker::Create(isolate));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(electron_browser_power_save_blocker,
|
||||
Initialize)
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_power_save_blocker, Initialize)
|
||||
@@ -2,31 +2,30 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef SHELL_BROWSER_API_ELECTRON_API_POWER_SAVE_BLOCKER_H_
|
||||
#define SHELL_BROWSER_API_ELECTRON_API_POWER_SAVE_BLOCKER_H_
|
||||
#ifndef ATOM_BROWSER_API_ATOM_API_POWER_SAVE_BLOCKER_H_
|
||||
#define ATOM_BROWSER_API_ATOM_API_POWER_SAVE_BLOCKER_H_
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
|
||||
#include "gin/handle.h"
|
||||
#include "gin/object_template_builder.h"
|
||||
#include "gin/wrappable.h"
|
||||
#include "mojo/public/cpp/bindings/remote.h"
|
||||
#include "atom/browser/api/trackable_object.h"
|
||||
#include "native_mate/handle.h"
|
||||
#include "services/device/public/mojom/wake_lock.mojom.h"
|
||||
|
||||
namespace electron {
|
||||
namespace mate {
|
||||
class Dictionary;
|
||||
}
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
class PowerSaveBlocker : public gin::Wrappable<PowerSaveBlocker> {
|
||||
class PowerSaveBlocker : public mate::TrackableObject<PowerSaveBlocker> {
|
||||
public:
|
||||
static gin::Handle<PowerSaveBlocker> Create(v8::Isolate* isolate);
|
||||
static mate::Handle<PowerSaveBlocker> Create(v8::Isolate* isolate);
|
||||
|
||||
// gin::Wrappable
|
||||
gin::ObjectTemplateBuilder GetObjectTemplateBuilder(
|
||||
v8::Isolate* isolate) override;
|
||||
|
||||
static gin::WrapperInfo kWrapperInfo;
|
||||
static void BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype);
|
||||
|
||||
protected:
|
||||
explicit PowerSaveBlocker(v8::Isolate* isolate);
|
||||
@@ -50,13 +49,13 @@ class PowerSaveBlocker : public gin::Wrappable<PowerSaveBlocker> {
|
||||
using WakeLockTypeMap = std::map<int, device::mojom::WakeLockType>;
|
||||
WakeLockTypeMap wake_lock_types_;
|
||||
|
||||
mojo::Remote<device::mojom::WakeLock> wake_lock_;
|
||||
device::mojom::WakeLockPtr wake_lock_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(PowerSaveBlocker);
|
||||
};
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace electron
|
||||
} // namespace atom
|
||||
|
||||
#endif // SHELL_BROWSER_API_ELECTRON_API_POWER_SAVE_BLOCKER_H_
|
||||
#endif // ATOM_BROWSER_API_ATOM_API_POWER_SAVE_BLOCKER_H_
|
||||
316
atom/browser/api/atom_api_protocol.cc
Normal file
316
atom/browser/api/atom_api_protocol.cc
Normal file
@@ -0,0 +1,316 @@
|
||||
// Copyright (c) 2013 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/browser/api/atom_api_protocol.h"
|
||||
|
||||
#include "atom/browser/atom_browser_client.h"
|
||||
#include "atom/browser/atom_browser_main_parts.h"
|
||||
#include "atom/browser/browser.h"
|
||||
#include "atom/browser/net/url_request_async_asar_job.h"
|
||||
#include "atom/browser/net/url_request_buffer_job.h"
|
||||
#include "atom/browser/net/url_request_fetch_job.h"
|
||||
#include "atom/browser/net/url_request_stream_job.h"
|
||||
#include "atom/browser/net/url_request_string_job.h"
|
||||
#include "atom/common/native_mate_converters/callback.h"
|
||||
#include "atom/common/native_mate_converters/value_converter.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "atom/common/options_switches.h"
|
||||
#include "base/command_line.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "content/public/browser/child_process_security_policy.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "url/url_util.h"
|
||||
|
||||
using content::BrowserThread;
|
||||
|
||||
namespace {
|
||||
|
||||
// List of registered custom standard schemes.
|
||||
std::vector<std::string> g_standard_schemes;
|
||||
|
||||
struct SchemeOptions {
|
||||
bool standard = false;
|
||||
bool secure = false;
|
||||
bool bypassCSP = false;
|
||||
bool allowServiceWorkers = false;
|
||||
bool supportFetchAPI = false;
|
||||
bool corsEnabled = false;
|
||||
};
|
||||
|
||||
struct CustomScheme {
|
||||
std::string scheme;
|
||||
SchemeOptions options;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace mate {
|
||||
|
||||
template <>
|
||||
struct Converter<CustomScheme> {
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
CustomScheme* out) {
|
||||
mate::Dictionary dict;
|
||||
if (!ConvertFromV8(isolate, val, &dict))
|
||||
return false;
|
||||
if (!dict.Get("scheme", &(out->scheme)))
|
||||
return false;
|
||||
mate::Dictionary opt;
|
||||
// options are optional. Default values specified in SchemeOptions are used
|
||||
if (dict.Get("privileges", &opt)) {
|
||||
opt.Get("standard", &(out->options.standard));
|
||||
opt.Get("supportFetchAPI", &(out->options.supportFetchAPI));
|
||||
opt.Get("secure", &(out->options.secure));
|
||||
opt.Get("bypassCSP", &(out->options.bypassCSP));
|
||||
opt.Get("allowServiceWorkers", &(out->options.allowServiceWorkers));
|
||||
opt.Get("supportFetchAPI", &(out->options.supportFetchAPI));
|
||||
opt.Get("corsEnabled", &(out->options.corsEnabled));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace mate
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
std::vector<std::string> GetStandardSchemes() {
|
||||
return g_standard_schemes;
|
||||
}
|
||||
|
||||
void RegisterSchemesAsPrivileged(v8::Local<v8::Value> val,
|
||||
mate::Arguments* args) {
|
||||
std::vector<CustomScheme> custom_schemes;
|
||||
if (!mate::ConvertFromV8(args->isolate(), val, &custom_schemes)) {
|
||||
args->ThrowError("Argument must be an array of custom schemes.");
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<std::string> secure_schemes, cspbypassing_schemes, fetch_schemes,
|
||||
service_worker_schemes, cors_schemes;
|
||||
for (const auto& custom_scheme : custom_schemes) {
|
||||
// Register scheme to privileged list (https, wss, data, chrome-extension)
|
||||
if (custom_scheme.options.standard) {
|
||||
auto* policy = content::ChildProcessSecurityPolicy::GetInstance();
|
||||
url::AddStandardScheme(custom_scheme.scheme.c_str(),
|
||||
url::SCHEME_WITH_HOST);
|
||||
g_standard_schemes.push_back(custom_scheme.scheme);
|
||||
policy->RegisterWebSafeScheme(custom_scheme.scheme);
|
||||
}
|
||||
if (custom_scheme.options.secure) {
|
||||
secure_schemes.push_back(custom_scheme.scheme);
|
||||
url::AddSecureScheme(custom_scheme.scheme.c_str());
|
||||
}
|
||||
if (custom_scheme.options.bypassCSP) {
|
||||
cspbypassing_schemes.push_back(custom_scheme.scheme);
|
||||
url::AddCSPBypassingScheme(custom_scheme.scheme.c_str());
|
||||
}
|
||||
if (custom_scheme.options.corsEnabled) {
|
||||
cors_schemes.push_back(custom_scheme.scheme);
|
||||
url::AddCorsEnabledScheme(custom_scheme.scheme.c_str());
|
||||
}
|
||||
if (custom_scheme.options.supportFetchAPI) {
|
||||
fetch_schemes.push_back(custom_scheme.scheme);
|
||||
}
|
||||
if (custom_scheme.options.allowServiceWorkers) {
|
||||
service_worker_schemes.push_back(custom_scheme.scheme);
|
||||
}
|
||||
}
|
||||
|
||||
const auto AppendSchemesToCmdLine = [](const char* switch_name,
|
||||
std::vector<std::string> schemes) {
|
||||
// Add the schemes to command line switches, so child processes can also
|
||||
// register them.
|
||||
base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
|
||||
switch_name, base::JoinString(schemes, ","));
|
||||
};
|
||||
|
||||
AppendSchemesToCmdLine(atom::switches::kSecureSchemes, secure_schemes);
|
||||
AppendSchemesToCmdLine(atom::switches::kBypassCSPSchemes,
|
||||
cspbypassing_schemes);
|
||||
AppendSchemesToCmdLine(atom::switches::kCORSSchemes, cors_schemes);
|
||||
AppendSchemesToCmdLine(atom::switches::kFetchSchemes, fetch_schemes);
|
||||
AppendSchemesToCmdLine(atom::switches::kServiceWorkerSchemes,
|
||||
service_worker_schemes);
|
||||
AppendSchemesToCmdLine(atom::switches::kStandardSchemes, g_standard_schemes);
|
||||
}
|
||||
|
||||
Protocol::Protocol(v8::Isolate* isolate, AtomBrowserContext* browser_context)
|
||||
: browser_context_(browser_context), weak_factory_(this) {
|
||||
Init(isolate);
|
||||
}
|
||||
|
||||
Protocol::~Protocol() {}
|
||||
void Protocol::UnregisterProtocol(const std::string& scheme,
|
||||
mate::Arguments* args) {
|
||||
CompletionCallback callback;
|
||||
args->GetNext(&callback);
|
||||
auto* getter = static_cast<URLRequestContextGetter*>(
|
||||
browser_context_->GetRequestContext());
|
||||
base::PostTaskWithTraitsAndReplyWithResult(
|
||||
FROM_HERE, {content::BrowserThread::IO},
|
||||
base::BindOnce(&Protocol::UnregisterProtocolInIO,
|
||||
base::RetainedRef(getter), scheme),
|
||||
base::BindOnce(&Protocol::OnIOCompleted, GetWeakPtr(), callback));
|
||||
}
|
||||
|
||||
// static
|
||||
Protocol::ProtocolError Protocol::UnregisterProtocolInIO(
|
||||
scoped_refptr<URLRequestContextGetter> request_context_getter,
|
||||
const std::string& scheme) {
|
||||
auto* job_factory = request_context_getter->job_factory();
|
||||
if (!job_factory->HasProtocolHandler(scheme))
|
||||
return PROTOCOL_NOT_REGISTERED;
|
||||
job_factory->SetProtocolHandler(scheme, nullptr);
|
||||
return PROTOCOL_OK;
|
||||
}
|
||||
|
||||
bool IsProtocolHandledInIO(
|
||||
scoped_refptr<URLRequestContextGetter> request_context_getter,
|
||||
const std::string& scheme) {
|
||||
bool is_handled =
|
||||
request_context_getter->job_factory()->IsHandledProtocol(scheme);
|
||||
return is_handled;
|
||||
}
|
||||
|
||||
v8::Local<v8::Promise> Protocol::IsProtocolHandled(const std::string& scheme) {
|
||||
util::Promise promise(isolate());
|
||||
v8::Local<v8::Promise> handle = promise.GetHandle();
|
||||
auto* getter = static_cast<URLRequestContextGetter*>(
|
||||
browser_context_->GetRequestContext());
|
||||
|
||||
base::PostTaskWithTraitsAndReplyWithResult(
|
||||
FROM_HERE, {content::BrowserThread::IO},
|
||||
base::BindOnce(&IsProtocolHandledInIO, base::RetainedRef(getter), scheme),
|
||||
base::BindOnce(util::Promise::ResolvePromise<bool>, std::move(promise)));
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
void Protocol::UninterceptProtocol(const std::string& scheme,
|
||||
mate::Arguments* args) {
|
||||
CompletionCallback callback;
|
||||
args->GetNext(&callback);
|
||||
auto* getter = static_cast<URLRequestContextGetter*>(
|
||||
browser_context_->GetRequestContext());
|
||||
base::PostTaskWithTraitsAndReplyWithResult(
|
||||
FROM_HERE, {content::BrowserThread::IO},
|
||||
base::BindOnce(&Protocol::UninterceptProtocolInIO,
|
||||
base::RetainedRef(getter), scheme),
|
||||
base::BindOnce(&Protocol::OnIOCompleted, GetWeakPtr(), callback));
|
||||
}
|
||||
|
||||
// static
|
||||
Protocol::ProtocolError Protocol::UninterceptProtocolInIO(
|
||||
scoped_refptr<URLRequestContextGetter> request_context_getter,
|
||||
const std::string& scheme) {
|
||||
return request_context_getter->job_factory()->UninterceptProtocol(scheme)
|
||||
? PROTOCOL_OK
|
||||
: PROTOCOL_NOT_INTERCEPTED;
|
||||
}
|
||||
|
||||
void Protocol::OnIOCompleted(const CompletionCallback& callback,
|
||||
ProtocolError error) {
|
||||
// The completion callback is optional.
|
||||
if (callback.is_null())
|
||||
return;
|
||||
|
||||
v8::Locker locker(isolate());
|
||||
v8::HandleScope handle_scope(isolate());
|
||||
|
||||
if (error == PROTOCOL_OK) {
|
||||
callback.Run(v8::Null(isolate()));
|
||||
} else {
|
||||
std::string str = ErrorCodeToString(error);
|
||||
callback.Run(v8::Exception::Error(mate::StringToV8(isolate(), str)));
|
||||
}
|
||||
}
|
||||
|
||||
std::string Protocol::ErrorCodeToString(ProtocolError error) {
|
||||
switch (error) {
|
||||
case PROTOCOL_FAIL:
|
||||
return "Failed to manipulate protocol factory";
|
||||
case PROTOCOL_REGISTERED:
|
||||
return "The scheme has been registered";
|
||||
case PROTOCOL_NOT_REGISTERED:
|
||||
return "The scheme has not been registered";
|
||||
case PROTOCOL_INTERCEPTED:
|
||||
return "The scheme has been intercepted";
|
||||
case PROTOCOL_NOT_INTERCEPTED:
|
||||
return "The scheme has not been intercepted";
|
||||
default:
|
||||
return "Unexpected error";
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
mate::Handle<Protocol> Protocol::Create(v8::Isolate* isolate,
|
||||
AtomBrowserContext* browser_context) {
|
||||
return mate::CreateHandle(isolate, new Protocol(isolate, browser_context));
|
||||
}
|
||||
|
||||
// static
|
||||
void Protocol::BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype) {
|
||||
prototype->SetClassName(mate::StringToV8(isolate, "Protocol"));
|
||||
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
||||
.SetMethod("registerStringProtocol",
|
||||
&Protocol::RegisterProtocol<URLRequestStringJob>)
|
||||
.SetMethod("registerBufferProtocol",
|
||||
&Protocol::RegisterProtocol<URLRequestBufferJob>)
|
||||
.SetMethod("registerFileProtocol",
|
||||
&Protocol::RegisterProtocol<URLRequestAsyncAsarJob>)
|
||||
.SetMethod("registerHttpProtocol",
|
||||
&Protocol::RegisterProtocol<URLRequestFetchJob>)
|
||||
.SetMethod("registerStreamProtocol",
|
||||
&Protocol::RegisterProtocol<URLRequestStreamJob>)
|
||||
.SetMethod("unregisterProtocol", &Protocol::UnregisterProtocol)
|
||||
.SetMethod("isProtocolHandled", &Protocol::IsProtocolHandled)
|
||||
.SetMethod("interceptStringProtocol",
|
||||
&Protocol::InterceptProtocol<URLRequestStringJob>)
|
||||
.SetMethod("interceptBufferProtocol",
|
||||
&Protocol::InterceptProtocol<URLRequestBufferJob>)
|
||||
.SetMethod("interceptFileProtocol",
|
||||
&Protocol::InterceptProtocol<URLRequestAsyncAsarJob>)
|
||||
.SetMethod("interceptHttpProtocol",
|
||||
&Protocol::InterceptProtocol<URLRequestFetchJob>)
|
||||
.SetMethod("interceptStreamProtocol",
|
||||
&Protocol::InterceptProtocol<URLRequestStreamJob>)
|
||||
.SetMethod("uninterceptProtocol", &Protocol::UninterceptProtocol);
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
|
||||
namespace {
|
||||
|
||||
void RegisterSchemesAsPrivileged(v8::Local<v8::Value> val,
|
||||
mate::Arguments* args) {
|
||||
if (atom::Browser::Get()->is_ready()) {
|
||||
args->ThrowError(
|
||||
"protocol.registerSchemesAsPrivileged should be called before "
|
||||
"app is ready");
|
||||
return;
|
||||
}
|
||||
|
||||
atom::api::RegisterSchemesAsPrivileged(val, args);
|
||||
}
|
||||
|
||||
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.SetMethod("registerSchemesAsPrivileged", &RegisterSchemesAsPrivileged);
|
||||
dict.SetMethod("getStandardSchemes", &atom::api::GetStandardSchemes);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_protocol, Initialize)
|
||||
197
atom/browser/api/atom_api_protocol.h
Normal file
197
atom/browser/api/atom_api_protocol.h
Normal file
@@ -0,0 +1,197 @@
|
||||
// Copyright (c) 2013 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ATOM_BROWSER_API_ATOM_API_PROTOCOL_H_
|
||||
#define ATOM_BROWSER_API_ATOM_API_PROTOCOL_H_
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "atom/browser/api/trackable_object.h"
|
||||
#include "atom/browser/atom_browser_context.h"
|
||||
#include "atom/browser/net/atom_url_request_job_factory.h"
|
||||
#include "atom/common/promise_util.h"
|
||||
#include "base/callback.h"
|
||||
#include "base/memory/weak_ptr.h"
|
||||
#include "base/task/post_task.h"
|
||||
#include "content/public/browser/browser_task_traits.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "native_mate/arguments.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "native_mate/handle.h"
|
||||
#include "net/url_request/url_request_context.h"
|
||||
|
||||
namespace base {
|
||||
class DictionaryValue;
|
||||
}
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
std::vector<std::string> GetStandardSchemes();
|
||||
|
||||
void RegisterSchemesAsPrivileged(v8::Local<v8::Value> val,
|
||||
mate::Arguments* args);
|
||||
|
||||
class Protocol : public mate::TrackableObject<Protocol> {
|
||||
public:
|
||||
using Handler =
|
||||
base::Callback<void(const base::DictionaryValue&, v8::Local<v8::Value>)>;
|
||||
using CompletionCallback = base::Callback<void(v8::Local<v8::Value>)>;
|
||||
|
||||
static mate::Handle<Protocol> Create(v8::Isolate* isolate,
|
||||
AtomBrowserContext* browser_context);
|
||||
|
||||
static void BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype);
|
||||
|
||||
protected:
|
||||
Protocol(v8::Isolate* isolate, AtomBrowserContext* browser_context);
|
||||
~Protocol() override;
|
||||
|
||||
private:
|
||||
// Possible errors.
|
||||
enum ProtocolError {
|
||||
PROTOCOL_OK, // no error
|
||||
PROTOCOL_FAIL, // operation failed, should never occur
|
||||
PROTOCOL_REGISTERED,
|
||||
PROTOCOL_NOT_REGISTERED,
|
||||
PROTOCOL_INTERCEPTED,
|
||||
PROTOCOL_NOT_INTERCEPTED,
|
||||
};
|
||||
|
||||
// The protocol handler that will create a protocol handler for certain
|
||||
// request job.
|
||||
template <typename RequestJob>
|
||||
class CustomProtocolHandler
|
||||
: public net::URLRequestJobFactory::ProtocolHandler {
|
||||
public:
|
||||
CustomProtocolHandler(v8::Isolate* isolate,
|
||||
net::URLRequestContextGetter* request_context,
|
||||
const Handler& handler)
|
||||
: isolate_(isolate),
|
||||
request_context_(request_context),
|
||||
handler_(handler) {}
|
||||
~CustomProtocolHandler() override {}
|
||||
|
||||
net::URLRequestJob* MaybeCreateJob(
|
||||
net::URLRequest* request,
|
||||
net::NetworkDelegate* network_delegate) const override {
|
||||
RequestJob* request_job = new RequestJob(request, network_delegate);
|
||||
request_job->SetHandlerInfo(isolate_, request_context_, handler_);
|
||||
return request_job;
|
||||
}
|
||||
|
||||
private:
|
||||
v8::Isolate* isolate_;
|
||||
net::URLRequestContextGetter* request_context_;
|
||||
Protocol::Handler handler_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(CustomProtocolHandler);
|
||||
};
|
||||
|
||||
// Register the protocol with certain request job.
|
||||
template <typename RequestJob>
|
||||
void RegisterProtocol(const std::string& scheme,
|
||||
const Handler& handler,
|
||||
mate::Arguments* args) {
|
||||
CompletionCallback callback;
|
||||
args->GetNext(&callback);
|
||||
auto* getter = static_cast<URLRequestContextGetter*>(
|
||||
browser_context_->GetRequestContext());
|
||||
base::PostTaskWithTraitsAndReplyWithResult(
|
||||
FROM_HERE, {content::BrowserThread::IO},
|
||||
base::BindOnce(&Protocol::RegisterProtocolInIO<RequestJob>,
|
||||
base::RetainedRef(getter), isolate(), scheme, handler),
|
||||
base::BindOnce(&Protocol::OnIOCompleted, GetWeakPtr(), callback));
|
||||
}
|
||||
template <typename RequestJob>
|
||||
static ProtocolError RegisterProtocolInIO(
|
||||
scoped_refptr<URLRequestContextGetter> request_context_getter,
|
||||
v8::Isolate* isolate,
|
||||
const std::string& scheme,
|
||||
const Handler& handler) {
|
||||
auto* job_factory = request_context_getter->job_factory();
|
||||
if (job_factory->IsHandledProtocol(scheme))
|
||||
return PROTOCOL_REGISTERED;
|
||||
auto protocol_handler = std::make_unique<CustomProtocolHandler<RequestJob>>(
|
||||
isolate, request_context_getter.get(), handler);
|
||||
if (job_factory->SetProtocolHandler(scheme, std::move(protocol_handler)))
|
||||
return PROTOCOL_OK;
|
||||
else
|
||||
return PROTOCOL_FAIL;
|
||||
}
|
||||
|
||||
// Unregister the protocol handler that handles |scheme|.
|
||||
void UnregisterProtocol(const std::string& scheme, mate::Arguments* args);
|
||||
static ProtocolError UnregisterProtocolInIO(
|
||||
scoped_refptr<URLRequestContextGetter> request_context_getter,
|
||||
const std::string& scheme);
|
||||
|
||||
// Whether the protocol has handler registered.
|
||||
v8::Local<v8::Promise> IsProtocolHandled(const std::string& scheme);
|
||||
|
||||
// Replace the protocol handler with a new one.
|
||||
template <typename RequestJob>
|
||||
void InterceptProtocol(const std::string& scheme,
|
||||
const Handler& handler,
|
||||
mate::Arguments* args) {
|
||||
CompletionCallback callback;
|
||||
args->GetNext(&callback);
|
||||
auto* getter = static_cast<URLRequestContextGetter*>(
|
||||
browser_context_->GetRequestContext());
|
||||
base::PostTaskWithTraitsAndReplyWithResult(
|
||||
FROM_HERE, {content::BrowserThread::IO},
|
||||
base::BindOnce(&Protocol::InterceptProtocolInIO<RequestJob>,
|
||||
base::RetainedRef(getter), isolate(), scheme, handler),
|
||||
base::BindOnce(&Protocol::OnIOCompleted, GetWeakPtr(), callback));
|
||||
}
|
||||
template <typename RequestJob>
|
||||
static ProtocolError InterceptProtocolInIO(
|
||||
scoped_refptr<URLRequestContextGetter> request_context_getter,
|
||||
v8::Isolate* isolate,
|
||||
const std::string& scheme,
|
||||
const Handler& handler) {
|
||||
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.
|
||||
if (!job_factory->HasProtocolHandler(scheme))
|
||||
return PROTOCOL_FAIL;
|
||||
auto protocol_handler = std::make_unique<CustomProtocolHandler<RequestJob>>(
|
||||
isolate, request_context_getter.get(), handler);
|
||||
if (!job_factory->InterceptProtocol(scheme, std::move(protocol_handler)))
|
||||
return PROTOCOL_INTERCEPTED;
|
||||
return PROTOCOL_OK;
|
||||
}
|
||||
|
||||
// Restore the |scheme| to its original protocol handler.
|
||||
void UninterceptProtocol(const std::string& scheme, mate::Arguments* args);
|
||||
static ProtocolError UninterceptProtocolInIO(
|
||||
scoped_refptr<URLRequestContextGetter> request_context_getter,
|
||||
const std::string& scheme);
|
||||
|
||||
// Convert error code to JS exception and call the callback.
|
||||
void OnIOCompleted(const CompletionCallback& callback, ProtocolError error);
|
||||
|
||||
// Convert error code to string.
|
||||
std::string ErrorCodeToString(ProtocolError error);
|
||||
|
||||
base::WeakPtr<Protocol> GetWeakPtr() { return weak_factory_.GetWeakPtr(); }
|
||||
|
||||
scoped_refptr<AtomBrowserContext> browser_context_;
|
||||
base::WeakPtrFactory<Protocol> weak_factory_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(Protocol);
|
||||
};
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_API_ATOM_API_PROTOCOL_H_
|
||||
90
atom/browser/api/atom_api_render_process_preferences.cc
Normal file
90
atom/browser/api/atom_api_render_process_preferences.cc
Normal file
@@ -0,0 +1,90 @@
|
||||
// Copyright (c) 2016 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/browser/api/atom_api_render_process_preferences.h"
|
||||
|
||||
#include "atom/browser/api/atom_api_web_contents.h"
|
||||
#include "atom/browser/atom_browser_client.h"
|
||||
#include "atom/common/native_mate_converters/value_converter.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "content/public/browser/render_process_host.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "native_mate/object_template_builder.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
namespace {
|
||||
|
||||
bool IsWebContents(v8::Isolate* isolate, content::RenderProcessHost* process) {
|
||||
content::WebContents* web_contents =
|
||||
static_cast<AtomBrowserClient*>(AtomBrowserClient::Get())
|
||||
->GetWebContentsFromProcessID(process->GetID());
|
||||
if (!web_contents)
|
||||
return false;
|
||||
|
||||
auto api_web_contents = WebContents::FromOrCreate(isolate, web_contents);
|
||||
auto type = api_web_contents->GetType();
|
||||
return type == WebContents::Type::BROWSER_WINDOW ||
|
||||
type == WebContents::Type::WEB_VIEW;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
RenderProcessPreferences::RenderProcessPreferences(
|
||||
v8::Isolate* isolate,
|
||||
const atom::RenderProcessPreferences::Predicate& predicate)
|
||||
: preferences_(predicate) {
|
||||
Init(isolate);
|
||||
}
|
||||
|
||||
RenderProcessPreferences::~RenderProcessPreferences() {}
|
||||
|
||||
int RenderProcessPreferences::AddEntry(const base::DictionaryValue& entry) {
|
||||
return preferences_.AddEntry(entry);
|
||||
}
|
||||
|
||||
void RenderProcessPreferences::RemoveEntry(int id) {
|
||||
preferences_.RemoveEntry(id);
|
||||
}
|
||||
|
||||
// static
|
||||
void RenderProcessPreferences::BuildPrototype(
|
||||
v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype) {
|
||||
prototype->SetClassName(
|
||||
mate::StringToV8(isolate, "RenderProcessPreferences"));
|
||||
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
||||
.SetMethod("addEntry", &RenderProcessPreferences::AddEntry)
|
||||
.SetMethod("removeEntry", &RenderProcessPreferences::RemoveEntry);
|
||||
}
|
||||
|
||||
// static
|
||||
mate::Handle<RenderProcessPreferences>
|
||||
RenderProcessPreferences::ForAllWebContents(v8::Isolate* isolate) {
|
||||
return mate::CreateHandle(isolate,
|
||||
new RenderProcessPreferences(
|
||||
isolate, base::Bind(&IsWebContents, isolate)));
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
|
||||
namespace {
|
||||
|
||||
void Initialize(v8::Local<v8::Object> exports,
|
||||
v8::Local<v8::Value> unused,
|
||||
v8::Local<v8::Context> context,
|
||||
void* priv) {
|
||||
mate::Dictionary dict(context->GetIsolate(), exports);
|
||||
dict.SetMethod("forAllWebContents",
|
||||
&atom::api::RenderProcessPreferences::ForAllWebContents);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_render_process_preferences,
|
||||
Initialize)
|
||||
44
atom/browser/api/atom_api_render_process_preferences.h
Normal file
44
atom/browser/api/atom_api_render_process_preferences.h
Normal file
@@ -0,0 +1,44 @@
|
||||
// Copyright (c) 2016 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ATOM_BROWSER_API_ATOM_API_RENDER_PROCESS_PREFERENCES_H_
|
||||
#define ATOM_BROWSER_API_ATOM_API_RENDER_PROCESS_PREFERENCES_H_
|
||||
|
||||
#include "atom/browser/render_process_preferences.h"
|
||||
#include "native_mate/handle.h"
|
||||
#include "native_mate/wrappable.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
class RenderProcessPreferences
|
||||
: public mate::Wrappable<RenderProcessPreferences> {
|
||||
public:
|
||||
static mate::Handle<RenderProcessPreferences> ForAllWebContents(
|
||||
v8::Isolate* isolate);
|
||||
|
||||
static void BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype);
|
||||
|
||||
int AddEntry(const base::DictionaryValue& entry);
|
||||
void RemoveEntry(int id);
|
||||
|
||||
protected:
|
||||
RenderProcessPreferences(
|
||||
v8::Isolate* isolate,
|
||||
const atom::RenderProcessPreferences::Predicate& predicate);
|
||||
~RenderProcessPreferences() override;
|
||||
|
||||
private:
|
||||
atom::RenderProcessPreferences preferences_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(RenderProcessPreferences);
|
||||
};
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_API_ATOM_API_RENDER_PROCESS_PREFERENCES_H_
|
||||
@@ -2,21 +2,18 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "shell/browser/api/electron_api_screen.h"
|
||||
#include "atom/browser/api/atom_api_screen.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
|
||||
#include "atom/browser/api/atom_api_browser_window.h"
|
||||
#include "atom/browser/browser.h"
|
||||
#include "atom/common/native_mate_converters/gfx_converter.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "base/bind.h"
|
||||
#include "gin/dictionary.h"
|
||||
#include "gin/handle.h"
|
||||
#include "shell/browser/browser.h"
|
||||
#include "shell/common/gin_converters/callback_converter.h"
|
||||
#include "shell/common/gin_converters/gfx_converter.h"
|
||||
#include "shell/common/gin_converters/native_window_converter.h"
|
||||
#include "shell/common/gin_helper/dictionary.h"
|
||||
#include "shell/common/gin_helper/object_template_builder.h"
|
||||
#include "shell/common/node_includes.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "native_mate/object_template_builder.h"
|
||||
#include "ui/display/display.h"
|
||||
#include "ui/display/screen.h"
|
||||
#include "ui/gfx/geometry/point.h"
|
||||
@@ -25,7 +22,7 @@
|
||||
#include "ui/display/win/screen_win.h"
|
||||
#endif
|
||||
|
||||
namespace electron {
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
@@ -44,24 +41,24 @@ typename T::iterator FindById(T* container, int id) {
|
||||
std::vector<std::string> MetricsToArray(uint32_t metrics) {
|
||||
std::vector<std::string> array;
|
||||
if (metrics & display::DisplayObserver::DISPLAY_METRIC_BOUNDS)
|
||||
array.emplace_back("bounds");
|
||||
array.push_back("bounds");
|
||||
if (metrics & display::DisplayObserver::DISPLAY_METRIC_WORK_AREA)
|
||||
array.emplace_back("workArea");
|
||||
array.push_back("workArea");
|
||||
if (metrics & display::DisplayObserver::DISPLAY_METRIC_DEVICE_SCALE_FACTOR)
|
||||
array.emplace_back("scaleFactor");
|
||||
array.push_back("scaleFactor");
|
||||
if (metrics & display::DisplayObserver::DISPLAY_METRIC_ROTATION)
|
||||
array.emplace_back("rotation");
|
||||
array.push_back("rotation");
|
||||
return array;
|
||||
}
|
||||
|
||||
void DelayEmit(Screen* screen,
|
||||
base::StringPiece name,
|
||||
const base::StringPiece& name,
|
||||
const display::Display& display) {
|
||||
screen->Emit(name, display);
|
||||
}
|
||||
|
||||
void DelayEmitWithMetrics(Screen* screen,
|
||||
base::StringPiece name,
|
||||
const base::StringPiece& name,
|
||||
const display::Display& display,
|
||||
const std::vector<std::string>& metrics) {
|
||||
screen->Emit(name, display, metrics);
|
||||
@@ -101,13 +98,13 @@ display::Display Screen::GetDisplayMatching(const gfx::Rect& match_rect) {
|
||||
|
||||
#if defined(OS_WIN)
|
||||
|
||||
static gfx::Rect ScreenToDIPRect(electron::NativeWindow* window,
|
||||
static gfx::Rect ScreenToDIPRect(atom::NativeWindow* window,
|
||||
const gfx::Rect& rect) {
|
||||
HWND hwnd = window ? window->GetAcceleratedWidget() : nullptr;
|
||||
return display::win::ScreenWin::ScreenToDIPRect(hwnd, rect);
|
||||
}
|
||||
|
||||
static gfx::Rect DIPToScreenRect(electron::NativeWindow* window,
|
||||
static gfx::Rect DIPToScreenRect(atom::NativeWindow* window,
|
||||
const gfx::Rect& rect) {
|
||||
HWND hwnd = window ? window->GetAcceleratedWidget() : nullptr;
|
||||
return display::win::ScreenWin::DIPToScreenRect(hwnd, rect);
|
||||
@@ -136,29 +133,28 @@ void Screen::OnDisplayMetricsChanged(const display::Display& display,
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Local<v8::Value> Screen::Create(gin_helper::ErrorThrower error_thrower) {
|
||||
v8::Local<v8::Value> Screen::Create(v8::Isolate* isolate) {
|
||||
if (!Browser::Get()->is_ready()) {
|
||||
error_thrower.ThrowError(
|
||||
"The 'screen' module can't be used before the app 'ready' event");
|
||||
return v8::Null(error_thrower.isolate());
|
||||
isolate->ThrowException(v8::Exception::Error(mate::StringToV8(
|
||||
isolate, "Cannot require \"screen\" module before app is ready")));
|
||||
return v8::Null(isolate);
|
||||
}
|
||||
|
||||
display::Screen* screen = display::Screen::GetScreen();
|
||||
if (!screen) {
|
||||
error_thrower.ThrowError("Failed to get screen information");
|
||||
return v8::Null(error_thrower.isolate());
|
||||
isolate->ThrowException(v8::Exception::Error(
|
||||
mate::StringToV8(isolate, "Failed to get screen information")));
|
||||
return v8::Null(isolate);
|
||||
}
|
||||
|
||||
return gin::CreateHandle(error_thrower.isolate(),
|
||||
new Screen(error_thrower.isolate(), screen))
|
||||
.ToV8();
|
||||
return mate::CreateHandle(isolate, new Screen(isolate, screen)).ToV8();
|
||||
}
|
||||
|
||||
// static
|
||||
void Screen::BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype) {
|
||||
prototype->SetClassName(gin::StringToV8(isolate, "Screen"));
|
||||
gin_helper::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
||||
prototype->SetClassName(mate::StringToV8(isolate, "Screen"));
|
||||
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
||||
.SetMethod("getCursorScreenPoint", &Screen::GetCursorScreenPoint)
|
||||
.SetMethod("getPrimaryDisplay", &Screen::GetPrimaryDisplay)
|
||||
.SetMethod("getAllDisplays", &Screen::GetAllDisplays)
|
||||
@@ -174,19 +170,19 @@ void Screen::BuildPrototype(v8::Isolate* isolate,
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace electron
|
||||
} // namespace atom
|
||||
|
||||
namespace {
|
||||
|
||||
using electron::api::Screen;
|
||||
using atom::api::Screen;
|
||||
|
||||
void Initialize(v8::Local<v8::Object> exports,
|
||||
v8::Local<v8::Value> unused,
|
||||
v8::Local<v8::Context> context,
|
||||
void* priv) {
|
||||
v8::Isolate* isolate = context->GetIsolate();
|
||||
gin_helper::Dictionary dict(isolate, exports);
|
||||
dict.SetMethod("createScreen", base::BindRepeating(&Screen::Create));
|
||||
mate::Dictionary dict(isolate, exports);
|
||||
dict.Set("screen", Screen::Create(isolate));
|
||||
dict.Set(
|
||||
"Screen",
|
||||
Screen::GetConstructor(isolate)->GetFunction(context).ToLocalChecked());
|
||||
@@ -194,4 +190,4 @@ void Initialize(v8::Local<v8::Object> exports,
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(electron_common_screen, Initialize)
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_common_screen, Initialize)
|
||||
@@ -2,13 +2,13 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef SHELL_BROWSER_API_ELECTRON_API_SCREEN_H_
|
||||
#define SHELL_BROWSER_API_ELECTRON_API_SCREEN_H_
|
||||
#ifndef ATOM_BROWSER_API_ATOM_API_SCREEN_H_
|
||||
#define ATOM_BROWSER_API_ATOM_API_SCREEN_H_
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "shell/common/gin_helper/error_thrower.h"
|
||||
#include "shell/common/gin_helper/event_emitter.h"
|
||||
#include "atom/browser/api/event_emitter.h"
|
||||
#include "native_mate/handle.h"
|
||||
#include "ui/display/display_observer.h"
|
||||
#include "ui/display/screen.h"
|
||||
|
||||
@@ -18,14 +18,14 @@ class Rect;
|
||||
class Screen;
|
||||
} // namespace gfx
|
||||
|
||||
namespace electron {
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
class Screen : public gin_helper::EventEmitter<Screen>,
|
||||
class Screen : public mate::EventEmitter<Screen>,
|
||||
public display::DisplayObserver {
|
||||
public:
|
||||
static v8::Local<v8::Value> Create(gin_helper::ErrorThrower error_thrower);
|
||||
static v8::Local<v8::Value> Create(v8::Isolate* isolate);
|
||||
|
||||
static void BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype);
|
||||
@@ -54,6 +54,6 @@ class Screen : public gin_helper::EventEmitter<Screen>,
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace electron
|
||||
} // namespace atom
|
||||
|
||||
#endif // SHELL_BROWSER_API_ELECTRON_API_SCREEN_H_
|
||||
#endif // ATOM_BROWSER_API_ATOM_API_SCREEN_H_
|
||||
847
atom/browser/api/atom_api_session.cc
Normal file
847
atom/browser/api/atom_api_session.cc
Normal file
@@ -0,0 +1,847 @@
|
||||
// Copyright (c) 2015 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/browser/api/atom_api_session.h"
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#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"
|
||||
#include "atom/browser/atom_browser_main_parts.h"
|
||||
#include "atom/browser/atom_permission_manager.h"
|
||||
#include "atom/browser/browser.h"
|
||||
#include "atom/browser/media/media_device_id_salt.h"
|
||||
#include "atom/browser/net/atom_cert_verifier.h"
|
||||
#include "atom/browser/session_preferences.h"
|
||||
#include "atom/common/native_mate_converters/callback.h"
|
||||
#include "atom/common/native_mate_converters/content_converter.h"
|
||||
#include "atom/common/native_mate_converters/file_path_converter.h"
|
||||
#include "atom/common/native_mate_converters/gurl_converter.h"
|
||||
#include "atom/common/native_mate_converters/net_converter.h"
|
||||
#include "atom/common/native_mate_converters/value_converter.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "base/files/file_path.h"
|
||||
#include "base/guid.h"
|
||||
#include "base/strings/string_number_conversions.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "base/task/post_task.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_task_traits.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "content/public/browser/download_item_utils.h"
|
||||
#include "content/public/browser/download_manager_delegate.h"
|
||||
#include "content/public/browser/storage_partition.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "native_mate/object_template_builder.h"
|
||||
#include "net/base/completion_repeating_callback.h"
|
||||
#include "net/base/load_flags.h"
|
||||
#include "net/http/http_auth_handler_factory.h"
|
||||
#include "net/http/http_auth_preferences.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"
|
||||
#include "ui/base/l10n/l10n_util.h"
|
||||
|
||||
using content::BrowserThread;
|
||||
using content::StoragePartition;
|
||||
|
||||
namespace {
|
||||
|
||||
struct ClearStorageDataOptions {
|
||||
GURL origin;
|
||||
uint32_t storage_types = StoragePartition::REMOVE_DATA_MASK_ALL;
|
||||
uint32_t quota_types = StoragePartition::QUOTA_MANAGED_STORAGE_MASK_ALL;
|
||||
};
|
||||
|
||||
struct ClearAuthCacheOptions {
|
||||
std::string type;
|
||||
GURL origin;
|
||||
std::string realm;
|
||||
base::string16 username;
|
||||
base::string16 password;
|
||||
net::HttpAuth::Scheme auth_scheme;
|
||||
};
|
||||
|
||||
uint32_t GetStorageMask(const std::vector<std::string>& storage_types) {
|
||||
uint32_t storage_mask = 0;
|
||||
for (const auto& it : storage_types) {
|
||||
auto type = base::ToLowerASCII(it);
|
||||
if (type == "appcache")
|
||||
storage_mask |= StoragePartition::REMOVE_DATA_MASK_APPCACHE;
|
||||
else if (type == "cookies")
|
||||
storage_mask |= StoragePartition::REMOVE_DATA_MASK_COOKIES;
|
||||
else if (type == "filesystem")
|
||||
storage_mask |= StoragePartition::REMOVE_DATA_MASK_FILE_SYSTEMS;
|
||||
else if (type == "indexdb")
|
||||
storage_mask |= StoragePartition::REMOVE_DATA_MASK_INDEXEDDB;
|
||||
else if (type == "localstorage")
|
||||
storage_mask |= StoragePartition::REMOVE_DATA_MASK_LOCAL_STORAGE;
|
||||
else if (type == "shadercache")
|
||||
storage_mask |= StoragePartition::REMOVE_DATA_MASK_SHADER_CACHE;
|
||||
else if (type == "websql")
|
||||
storage_mask |= StoragePartition::REMOVE_DATA_MASK_WEBSQL;
|
||||
else if (type == "serviceworkers")
|
||||
storage_mask |= StoragePartition::REMOVE_DATA_MASK_SERVICE_WORKERS;
|
||||
else if (type == "cachestorage")
|
||||
storage_mask |= StoragePartition::REMOVE_DATA_MASK_CACHE_STORAGE;
|
||||
}
|
||||
return storage_mask;
|
||||
}
|
||||
|
||||
uint32_t GetQuotaMask(const std::vector<std::string>& quota_types) {
|
||||
uint32_t quota_mask = 0;
|
||||
for (const auto& it : quota_types) {
|
||||
auto type = base::ToLowerASCII(it);
|
||||
if (type == "temporary")
|
||||
quota_mask |= StoragePartition::QUOTA_MANAGED_STORAGE_MASK_TEMPORARY;
|
||||
else if (type == "persistent")
|
||||
quota_mask |= StoragePartition::QUOTA_MANAGED_STORAGE_MASK_PERSISTENT;
|
||||
else if (type == "syncable")
|
||||
quota_mask |= StoragePartition::QUOTA_MANAGED_STORAGE_MASK_SYNCABLE;
|
||||
}
|
||||
return quota_mask;
|
||||
}
|
||||
|
||||
net::HttpAuth::Scheme GetAuthSchemeFromString(const std::string& scheme) {
|
||||
if (scheme == "basic")
|
||||
return net::HttpAuth::AUTH_SCHEME_BASIC;
|
||||
if (scheme == "digest")
|
||||
return net::HttpAuth::AUTH_SCHEME_DIGEST;
|
||||
if (scheme == "ntlm")
|
||||
return net::HttpAuth::AUTH_SCHEME_NTLM;
|
||||
if (scheme == "negotiate")
|
||||
return net::HttpAuth::AUTH_SCHEME_NEGOTIATE;
|
||||
return net::HttpAuth::AUTH_SCHEME_MAX;
|
||||
}
|
||||
|
||||
void SetUserAgentInIO(scoped_refptr<net::URLRequestContextGetter> getter,
|
||||
const std::string& accept_lang,
|
||||
const std::string& user_agent) {
|
||||
getter->GetURLRequestContext()->set_http_user_agent_settings(
|
||||
new net::StaticHttpUserAgentSettings(
|
||||
net::HttpUtil::GenerateAcceptLanguageHeader(accept_lang),
|
||||
user_agent));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace mate {
|
||||
|
||||
template <>
|
||||
struct Converter<ClearStorageDataOptions> {
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
ClearStorageDataOptions* out) {
|
||||
mate::Dictionary options;
|
||||
if (!ConvertFromV8(isolate, val, &options))
|
||||
return false;
|
||||
options.Get("origin", &out->origin);
|
||||
std::vector<std::string> types;
|
||||
if (options.Get("storages", &types))
|
||||
out->storage_types = GetStorageMask(types);
|
||||
if (options.Get("quotas", &types))
|
||||
out->quota_types = GetQuotaMask(types);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Converter<ClearAuthCacheOptions> {
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
ClearAuthCacheOptions* out) {
|
||||
mate::Dictionary options;
|
||||
if (!ConvertFromV8(isolate, val, &options))
|
||||
return false;
|
||||
options.Get("type", &out->type);
|
||||
options.Get("origin", &out->origin);
|
||||
options.Get("realm", &out->realm);
|
||||
options.Get("username", &out->username);
|
||||
options.Get("password", &out->password);
|
||||
std::string scheme;
|
||||
if (options.Get("scheme", &scheme))
|
||||
out->auth_scheme = GetAuthSchemeFromString(scheme);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Converter<atom::VerifyRequestParams> {
|
||||
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
||||
atom::VerifyRequestParams val) {
|
||||
mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate);
|
||||
dict.Set("hostname", val.hostname);
|
||||
dict.Set("certificate", val.certificate);
|
||||
dict.Set("verificationResult", val.default_result);
|
||||
dict.Set("errorCode", val.error_code);
|
||||
return dict.GetHandle();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace mate
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
namespace {
|
||||
|
||||
const char kPersistPrefix[] = "persist:";
|
||||
|
||||
// Referenced session objects.
|
||||
std::map<uint32_t, v8::Global<v8::Object>> g_sessions;
|
||||
|
||||
void SetCertVerifyProcInIO(
|
||||
const scoped_refptr<net::URLRequestContextGetter>& context_getter,
|
||||
const AtomCertVerifier::VerifyProc& proc) {
|
||||
auto* request_context = context_getter->GetURLRequestContext();
|
||||
static_cast<AtomCertVerifier*>(request_context->cert_verifier())
|
||||
->SetVerifyProc(proc);
|
||||
}
|
||||
|
||||
void ClearHostResolverCacheInIO(
|
||||
const scoped_refptr<net::URLRequestContextGetter>& context_getter,
|
||||
util::Promise promise) {
|
||||
auto* request_context = context_getter->GetURLRequestContext();
|
||||
auto* cache = request_context->host_resolver()->GetHostCache();
|
||||
if (cache) {
|
||||
cache->clear();
|
||||
DCHECK_EQ(0u, cache->size());
|
||||
base::PostTaskWithTraits(
|
||||
FROM_HERE, {BrowserThread::UI},
|
||||
base::BindOnce(util::Promise::ResolveEmptyPromise, std::move(promise)));
|
||||
}
|
||||
}
|
||||
|
||||
void ClearAuthCacheInIO(
|
||||
const scoped_refptr<net::URLRequestContextGetter>& context_getter,
|
||||
const ClearAuthCacheOptions& options,
|
||||
util::Promise promise) {
|
||||
auto* request_context = context_getter->GetURLRequestContext();
|
||||
auto* network_session =
|
||||
request_context->http_transaction_factory()->GetSession();
|
||||
if (network_session) {
|
||||
if (options.type == "password") {
|
||||
auto* auth_cache = network_session->http_auth_cache();
|
||||
if (!options.origin.is_empty()) {
|
||||
auth_cache->Remove(
|
||||
options.origin, options.realm, options.auth_scheme,
|
||||
net::AuthCredentials(options.username, options.password));
|
||||
} else {
|
||||
auth_cache->ClearAllEntries();
|
||||
}
|
||||
} else if (options.type == "clientCertificate") {
|
||||
auto* client_auth_cache = network_session->ssl_client_auth_cache();
|
||||
client_auth_cache->Remove(net::HostPortPair::FromURL(options.origin));
|
||||
}
|
||||
network_session->CloseAllConnections();
|
||||
}
|
||||
base::PostTaskWithTraits(
|
||||
FROM_HERE, {BrowserThread::UI},
|
||||
base::BindOnce(util::Promise::ResolveEmptyPromise, std::move(promise)));
|
||||
}
|
||||
|
||||
void AllowNTLMCredentialsForDomainsInIO(
|
||||
const scoped_refptr<net::URLRequestContextGetter>& context_getter,
|
||||
const std::string& domains) {
|
||||
auto* request_context = context_getter->GetURLRequestContext();
|
||||
auto* auth_handler = request_context->http_auth_handler_factory();
|
||||
if (auth_handler) {
|
||||
auto* auth_preferences = const_cast<net::HttpAuthPreferences*>(
|
||||
auth_handler->http_auth_preferences());
|
||||
if (auth_preferences)
|
||||
auth_preferences->SetServerWhitelist(domains);
|
||||
}
|
||||
}
|
||||
|
||||
void DownloadIdCallback(content::DownloadManager* download_manager,
|
||||
const base::FilePath& path,
|
||||
const std::vector<GURL>& url_chain,
|
||||
const std::string& mime_type,
|
||||
int64_t offset,
|
||||
int64_t length,
|
||||
const std::string& last_modified,
|
||||
const std::string& etag,
|
||||
const base::Time& start_time,
|
||||
uint32_t id) {
|
||||
download_manager->CreateDownloadItem(
|
||||
base::GenerateGUID(), id, path, path, url_chain, GURL(), GURL(), GURL(),
|
||||
GURL(), base::nullopt, mime_type, mime_type, start_time, base::Time(),
|
||||
etag, last_modified, offset, length, std::string(),
|
||||
download::DownloadItem::INTERRUPTED,
|
||||
download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
|
||||
download::DOWNLOAD_INTERRUPT_REASON_NETWORK_TIMEOUT, false, base::Time(),
|
||||
false, std::vector<download::DownloadItem::ReceivedSlice>());
|
||||
}
|
||||
|
||||
void DestroyGlobalHandle(v8::Isolate* isolate,
|
||||
const v8::Global<v8::Value>& global_handle) {
|
||||
v8::Locker locker(isolate);
|
||||
v8::HandleScope handle_scope(isolate);
|
||||
if (!global_handle.IsEmpty()) {
|
||||
v8::Local<v8::Value> local_handle = global_handle.Get(isolate);
|
||||
v8::Local<v8::Object> object;
|
||||
if (local_handle->IsObject() &&
|
||||
local_handle->ToObject(isolate->GetCurrentContext()).ToLocal(&object)) {
|
||||
void* ptr = object->GetAlignedPointerFromInternalField(0);
|
||||
if (!ptr)
|
||||
return;
|
||||
delete static_cast<mate::WrappableBase*>(ptr);
|
||||
object->SetAlignedPointerInInternalField(0, nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
Session::Session(v8::Isolate* isolate, AtomBrowserContext* browser_context)
|
||||
: network_emulation_token_(base::UnguessableToken::Create()),
|
||||
browser_context_(browser_context) {
|
||||
// Observe DownloadManager to get download notifications.
|
||||
content::BrowserContext::GetDownloadManager(browser_context)
|
||||
->AddObserver(this);
|
||||
|
||||
new SessionPreferences(browser_context);
|
||||
|
||||
Init(isolate);
|
||||
AttachAsUserData(browser_context);
|
||||
}
|
||||
|
||||
Session::~Session() {
|
||||
content::BrowserContext::GetDownloadManager(browser_context())
|
||||
->RemoveObserver(this);
|
||||
DestroyGlobalHandle(isolate(), cookies_);
|
||||
DestroyGlobalHandle(isolate(), web_request_);
|
||||
DestroyGlobalHandle(isolate(), protocol_);
|
||||
DestroyGlobalHandle(isolate(), net_log_);
|
||||
g_sessions.erase(weak_map_id());
|
||||
}
|
||||
|
||||
void Session::OnDownloadCreated(content::DownloadManager* manager,
|
||||
download::DownloadItem* item) {
|
||||
if (item->IsSavePackageDownload())
|
||||
return;
|
||||
|
||||
v8::Locker locker(isolate());
|
||||
v8::HandleScope handle_scope(isolate());
|
||||
auto handle = DownloadItem::Create(isolate(), item);
|
||||
if (item->GetState() == download::DownloadItem::INTERRUPTED)
|
||||
handle->SetSavePath(item->GetTargetFilePath());
|
||||
content::WebContents* web_contents =
|
||||
content::DownloadItemUtils::GetWebContents(item);
|
||||
bool prevent_default = Emit("will-download", handle, web_contents);
|
||||
if (prevent_default) {
|
||||
item->Cancel(true);
|
||||
item->Remove();
|
||||
}
|
||||
}
|
||||
|
||||
v8::Local<v8::Promise> Session::ResolveProxy(mate::Arguments* args) {
|
||||
v8::Isolate* isolate = args->isolate();
|
||||
util::Promise promise(isolate);
|
||||
v8::Local<v8::Promise> handle = promise.GetHandle();
|
||||
|
||||
GURL url;
|
||||
args->GetNext(&url);
|
||||
|
||||
browser_context_->GetResolveProxyHelper()->ResolveProxy(
|
||||
url,
|
||||
base::Bind(util::CopyablePromise::ResolveCopyablePromise<std::string>,
|
||||
util::CopyablePromise(promise)));
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
v8::Local<v8::Promise> Session::GetCacheSize() {
|
||||
auto* isolate = v8::Isolate::GetCurrent();
|
||||
auto promise = util::Promise(isolate);
|
||||
auto handle = promise.GetHandle();
|
||||
|
||||
content::BrowserContext::GetDefaultStoragePartition(browser_context_.get())
|
||||
->GetNetworkContext()
|
||||
->ComputeHttpCacheSize(base::Time(), base::Time::Max(),
|
||||
base::BindOnce(
|
||||
[](util::Promise promise, bool is_upper_bound,
|
||||
int64_t size_or_error) {
|
||||
if (size_or_error < 0) {
|
||||
promise.RejectWithErrorMessage(
|
||||
net::ErrorToString(size_or_error));
|
||||
} else {
|
||||
promise.Resolve(size_or_error);
|
||||
}
|
||||
},
|
||||
std::move(promise)));
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
v8::Local<v8::Promise> Session::ClearCache() {
|
||||
auto* isolate = v8::Isolate::GetCurrent();
|
||||
auto promise = util::Promise(isolate);
|
||||
auto handle = promise.GetHandle();
|
||||
|
||||
content::BrowserContext::GetDefaultStoragePartition(browser_context_.get())
|
||||
->GetNetworkContext()
|
||||
->ClearHttpCache(base::Time(), base::Time::Max(), nullptr,
|
||||
base::BindOnce(util::Promise::ResolveEmptyPromise,
|
||||
std::move(promise)));
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
v8::Local<v8::Promise> Session::ClearStorageData(mate::Arguments* args) {
|
||||
v8::Isolate* isolate = args->isolate();
|
||||
util::Promise promise(isolate);
|
||||
v8::Local<v8::Promise> handle = promise.GetHandle();
|
||||
|
||||
ClearStorageDataOptions options;
|
||||
args->GetNext(&options);
|
||||
|
||||
auto* storage_partition =
|
||||
content::BrowserContext::GetStoragePartition(browser_context(), nullptr);
|
||||
if (options.storage_types & StoragePartition::REMOVE_DATA_MASK_COOKIES) {
|
||||
// Reset media device id salt when cookies are cleared.
|
||||
// https://w3c.github.io/mediacapture-main/#dom-mediadeviceinfo-deviceid
|
||||
MediaDeviceIDSalt::Reset(browser_context()->prefs());
|
||||
}
|
||||
|
||||
storage_partition->ClearData(
|
||||
options.storage_types, options.quota_types, options.origin, base::Time(),
|
||||
base::Time::Max(),
|
||||
base::Bind(util::CopyablePromise::ResolveEmptyCopyablePromise,
|
||||
util::CopyablePromise(promise)));
|
||||
return handle;
|
||||
}
|
||||
|
||||
void Session::FlushStorageData() {
|
||||
auto* storage_partition =
|
||||
content::BrowserContext::GetStoragePartition(browser_context(), nullptr);
|
||||
storage_partition->Flush();
|
||||
}
|
||||
|
||||
v8::Local<v8::Promise> Session::SetProxy(mate::Arguments* args) {
|
||||
v8::Isolate* isolate = args->isolate();
|
||||
util::Promise promise(isolate);
|
||||
v8::Local<v8::Promise> handle = promise.GetHandle();
|
||||
|
||||
mate::Dictionary options;
|
||||
args->GetNext(&options);
|
||||
|
||||
if (!browser_context_->in_memory_pref_store()) {
|
||||
promise.Resolve();
|
||||
return handle;
|
||||
}
|
||||
|
||||
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,
|
||||
std::make_unique<base::Value>(ProxyConfigDictionary::CreatePacScript(
|
||||
pac_url, true /* pac_mandatory */)),
|
||||
WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
|
||||
} else {
|
||||
browser_context_->in_memory_pref_store()->SetValue(
|
||||
proxy_config::prefs::kProxy,
|
||||
std::make_unique<base::Value>(ProxyConfigDictionary::CreateFixedServers(
|
||||
proxy_rules, bypass_list)),
|
||||
WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
|
||||
}
|
||||
|
||||
base::ThreadTaskRunnerHandle::Get()->PostTask(
|
||||
FROM_HERE,
|
||||
base::BindOnce(util::Promise::ResolveEmptyPromise, std::move(promise)));
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
void Session::SetDownloadPath(const base::FilePath& path) {
|
||||
browser_context_->prefs()->SetFilePath(prefs::kDownloadDefaultDirectory,
|
||||
path);
|
||||
}
|
||||
|
||||
void Session::EnableNetworkEmulation(const mate::Dictionary& options) {
|
||||
auto conditions = network::mojom::NetworkConditions::New();
|
||||
|
||||
options.Get("offline", &conditions->offline);
|
||||
options.Get("downloadThroughput", &conditions->download_throughput);
|
||||
options.Get("uploadThroughput", &conditions->upload_throughput);
|
||||
double latency = 0.0;
|
||||
if (options.Get("latency", &latency) && latency) {
|
||||
conditions->latency = base::TimeDelta::FromMillisecondsD(latency);
|
||||
}
|
||||
|
||||
auto* network_context = content::BrowserContext::GetDefaultStoragePartition(
|
||||
browser_context_.get())
|
||||
->GetNetworkContext();
|
||||
network_context->SetNetworkConditions(network_emulation_token_,
|
||||
std::move(conditions));
|
||||
}
|
||||
|
||||
void Session::DisableNetworkEmulation() {
|
||||
auto* network_context = content::BrowserContext::GetDefaultStoragePartition(
|
||||
browser_context_.get())
|
||||
->GetNetworkContext();
|
||||
network_context->SetNetworkConditions(
|
||||
network_emulation_token_, network::mojom::NetworkConditions::New());
|
||||
}
|
||||
|
||||
void WrapVerifyProc(base::Callback<void(const VerifyRequestParams& request,
|
||||
base::Callback<void(int)>)> proc,
|
||||
const VerifyRequestParams& request,
|
||||
base::OnceCallback<void(int)> cb) {
|
||||
if (proc.is_null()) {
|
||||
LOG(ERROR) << "WrapVerifyProc (proc=null)";
|
||||
return;
|
||||
}
|
||||
proc.Run(request, base::AdaptCallbackForRepeating(std::move(cb)));
|
||||
}
|
||||
|
||||
void Session::SetCertVerifyProc(v8::Local<v8::Value> val,
|
||||
mate::Arguments* args) {
|
||||
base::Callback<void(const VerifyRequestParams& request,
|
||||
base::Callback<void(int)>)>
|
||||
proc;
|
||||
if (!(val->IsNull() || mate::ConvertFromV8(args->isolate(), val, &proc))) {
|
||||
args->ThrowError("Must pass null or function");
|
||||
return;
|
||||
}
|
||||
|
||||
base::PostTaskWithTraits(
|
||||
FROM_HERE, {BrowserThread::IO},
|
||||
base::BindOnce(&SetCertVerifyProcInIO,
|
||||
WrapRefCounted(browser_context_->GetRequestContext()),
|
||||
base::Bind(&WrapVerifyProc, proc)));
|
||||
}
|
||||
|
||||
void Session::SetPermissionRequestHandler(v8::Local<v8::Value> val,
|
||||
mate::Arguments* args) {
|
||||
auto* permission_manager = static_cast<AtomPermissionManager*>(
|
||||
browser_context()->GetPermissionControllerDelegate());
|
||||
if (val->IsNull()) {
|
||||
permission_manager->SetPermissionRequestHandler(
|
||||
AtomPermissionManager::RequestHandler());
|
||||
return;
|
||||
}
|
||||
using StatusCallback =
|
||||
base::RepeatingCallback<void(blink::mojom::PermissionStatus)>;
|
||||
using RequestHandler =
|
||||
base::Callback<void(content::WebContents*, content::PermissionType,
|
||||
StatusCallback, const base::Value&)>;
|
||||
auto handler = std::make_unique<RequestHandler>();
|
||||
if (!mate::ConvertFromV8(args->isolate(), val, handler.get())) {
|
||||
args->ThrowError("Must pass null or function");
|
||||
return;
|
||||
}
|
||||
permission_manager->SetPermissionRequestHandler(base::BindRepeating(
|
||||
[](RequestHandler* handler, content::WebContents* web_contents,
|
||||
content::PermissionType permission_type,
|
||||
AtomPermissionManager::StatusCallback callback,
|
||||
const base::Value& details) {
|
||||
handler->Run(web_contents, permission_type,
|
||||
base::AdaptCallbackForRepeating(std::move(callback)),
|
||||
details);
|
||||
},
|
||||
base::Owned(std::move(handler))));
|
||||
}
|
||||
|
||||
void Session::SetPermissionCheckHandler(v8::Local<v8::Value> val,
|
||||
mate::Arguments* args) {
|
||||
AtomPermissionManager::CheckHandler handler;
|
||||
if (!(val->IsNull() || mate::ConvertFromV8(args->isolate(), val, &handler))) {
|
||||
args->ThrowError("Must pass null or function");
|
||||
return;
|
||||
}
|
||||
auto* permission_manager = static_cast<AtomPermissionManager*>(
|
||||
browser_context()->GetPermissionControllerDelegate());
|
||||
permission_manager->SetPermissionCheckHandler(handler);
|
||||
}
|
||||
|
||||
v8::Local<v8::Promise> Session::ClearHostResolverCache(mate::Arguments* args) {
|
||||
v8::Isolate* isolate = args->isolate();
|
||||
util::Promise promise(isolate);
|
||||
v8::Local<v8::Promise> handle = promise.GetHandle();
|
||||
|
||||
base::PostTaskWithTraits(
|
||||
FROM_HERE, {BrowserThread::IO},
|
||||
base::BindOnce(&ClearHostResolverCacheInIO,
|
||||
WrapRefCounted(browser_context_->GetRequestContext()),
|
||||
std::move(promise)));
|
||||
return handle;
|
||||
}
|
||||
|
||||
v8::Local<v8::Promise> Session::ClearAuthCache(mate::Arguments* args) {
|
||||
v8::Isolate* isolate = args->isolate();
|
||||
util::Promise promise(isolate);
|
||||
v8::Local<v8::Promise> handle = promise.GetHandle();
|
||||
|
||||
ClearAuthCacheOptions options;
|
||||
if (!args->GetNext(&options)) {
|
||||
promise.RejectWithErrorMessage("Must specify options object");
|
||||
return handle;
|
||||
}
|
||||
|
||||
base::PostTaskWithTraits(
|
||||
FROM_HERE, {BrowserThread::IO},
|
||||
base::BindOnce(&ClearAuthCacheInIO,
|
||||
WrapRefCounted(browser_context_->GetRequestContext()),
|
||||
options, std::move(promise)));
|
||||
return handle;
|
||||
}
|
||||
|
||||
void Session::AllowNTLMCredentialsForDomains(const std::string& domains) {
|
||||
base::PostTaskWithTraits(
|
||||
FROM_HERE, {BrowserThread::IO},
|
||||
base::BindOnce(&AllowNTLMCredentialsForDomainsInIO,
|
||||
WrapRefCounted(browser_context_->GetRequestContext()),
|
||||
domains));
|
||||
}
|
||||
|
||||
void Session::SetUserAgent(const std::string& user_agent,
|
||||
mate::Arguments* args) {
|
||||
browser_context_->SetUserAgent(user_agent);
|
||||
|
||||
std::string accept_lang = g_browser_process->GetApplicationLocale();
|
||||
args->GetNext(&accept_lang);
|
||||
|
||||
scoped_refptr<net::URLRequestContextGetter> getter(
|
||||
browser_context_->GetRequestContext());
|
||||
getter->GetNetworkTaskRunner()->PostTask(
|
||||
FROM_HERE,
|
||||
base::BindOnce(&SetUserAgentInIO, getter, accept_lang, user_agent));
|
||||
}
|
||||
|
||||
std::string Session::GetUserAgent() {
|
||||
return browser_context_->GetUserAgent();
|
||||
}
|
||||
|
||||
v8::Local<v8::Promise> Session::GetBlobData(v8::Isolate* isolate,
|
||||
const std::string& uuid) {
|
||||
util::Promise promise(isolate);
|
||||
v8::Local<v8::Promise> handle = promise.GetHandle();
|
||||
|
||||
AtomBlobReader* blob_reader = browser_context()->GetBlobReader();
|
||||
base::PostTaskWithTraits(
|
||||
FROM_HERE, {BrowserThread::IO},
|
||||
base::BindOnce(&AtomBlobReader::StartReading,
|
||||
base::Unretained(blob_reader), uuid, std::move(promise)));
|
||||
return handle;
|
||||
}
|
||||
|
||||
void Session::CreateInterruptedDownload(const mate::Dictionary& options) {
|
||||
int64_t offset = 0, length = 0;
|
||||
double start_time = 0.0;
|
||||
std::string mime_type, last_modified, etag;
|
||||
base::FilePath path;
|
||||
std::vector<GURL> url_chain;
|
||||
options.Get("path", &path);
|
||||
options.Get("urlChain", &url_chain);
|
||||
options.Get("mimeType", &mime_type);
|
||||
options.Get("offset", &offset);
|
||||
options.Get("length", &length);
|
||||
options.Get("lastModified", &last_modified);
|
||||
options.Get("eTag", &etag);
|
||||
options.Get("startTime", &start_time);
|
||||
if (path.empty() || url_chain.empty() || length == 0) {
|
||||
isolate()->ThrowException(v8::Exception::Error(mate::StringToV8(
|
||||
isolate(), "Must pass non-empty path, urlChain and length.")));
|
||||
return;
|
||||
}
|
||||
if (offset >= length) {
|
||||
isolate()->ThrowException(v8::Exception::Error(mate::StringToV8(
|
||||
isolate(), "Must pass an offset value less than length.")));
|
||||
return;
|
||||
}
|
||||
auto* download_manager =
|
||||
content::BrowserContext::GetDownloadManager(browser_context());
|
||||
download_manager->GetDelegate()->GetNextId(base::Bind(
|
||||
&DownloadIdCallback, download_manager, path, url_chain, mime_type, offset,
|
||||
length, last_modified, etag, base::Time::FromDoubleT(start_time)));
|
||||
}
|
||||
|
||||
void Session::SetPreloads(
|
||||
const std::vector<base::FilePath::StringType>& preloads) {
|
||||
auto* prefs = SessionPreferences::FromBrowserContext(browser_context());
|
||||
DCHECK(prefs);
|
||||
prefs->set_preloads(preloads);
|
||||
}
|
||||
|
||||
std::vector<base::FilePath::StringType> Session::GetPreloads() const {
|
||||
auto* prefs = SessionPreferences::FromBrowserContext(browser_context());
|
||||
DCHECK(prefs);
|
||||
return prefs->preloads();
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> Session::Cookies(v8::Isolate* isolate) {
|
||||
if (cookies_.IsEmpty()) {
|
||||
auto handle = Cookies::Create(isolate, browser_context());
|
||||
cookies_.Reset(isolate, handle.ToV8());
|
||||
}
|
||||
return v8::Local<v8::Value>::New(isolate, cookies_);
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> Session::Protocol(v8::Isolate* isolate) {
|
||||
if (protocol_.IsEmpty()) {
|
||||
auto handle = atom::api::Protocol::Create(isolate, browser_context());
|
||||
protocol_.Reset(isolate, handle.ToV8());
|
||||
}
|
||||
return v8::Local<v8::Value>::New(isolate, protocol_);
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> Session::WebRequest(v8::Isolate* isolate) {
|
||||
if (web_request_.IsEmpty()) {
|
||||
auto handle = atom::api::WebRequest::Create(isolate, browser_context());
|
||||
web_request_.Reset(isolate, handle.ToV8());
|
||||
}
|
||||
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) {
|
||||
auto* existing = TrackableObject::FromWrappedClass(isolate, browser_context);
|
||||
if (existing)
|
||||
return mate::CreateHandle(isolate, static_cast<Session*>(existing));
|
||||
|
||||
auto handle =
|
||||
mate::CreateHandle(isolate, new Session(isolate, browser_context));
|
||||
|
||||
// The Sessions should never be garbage collected, since the common pattern is
|
||||
// to use partition strings, instead of using the Session object directly.
|
||||
g_sessions[handle->weak_map_id()] =
|
||||
v8::Global<v8::Object>(isolate, handle.ToV8());
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
// static
|
||||
mate::Handle<Session> Session::FromPartition(
|
||||
v8::Isolate* isolate,
|
||||
const std::string& partition,
|
||||
const base::DictionaryValue& options) {
|
||||
scoped_refptr<AtomBrowserContext> browser_context;
|
||||
if (partition.empty()) {
|
||||
browser_context = AtomBrowserContext::From("", false, options);
|
||||
} else if (base::StartsWith(partition, kPersistPrefix,
|
||||
base::CompareCase::SENSITIVE)) {
|
||||
std::string name = partition.substr(8);
|
||||
browser_context = AtomBrowserContext::From(name, false, options);
|
||||
} else {
|
||||
browser_context = AtomBrowserContext::From(partition, true, options);
|
||||
}
|
||||
return CreateFrom(isolate, browser_context.get());
|
||||
}
|
||||
|
||||
// static
|
||||
void Session::BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype) {
|
||||
prototype->SetClassName(mate::StringToV8(isolate, "Session"));
|
||||
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
||||
.MakeDestroyable()
|
||||
.SetMethod("resolveProxy", &Session::ResolveProxy)
|
||||
.SetMethod("getCacheSize", &Session::GetCacheSize)
|
||||
.SetMethod("clearCache", &Session::ClearCache)
|
||||
.SetMethod("clearStorageData", &Session::ClearStorageData)
|
||||
.SetMethod("flushStorageData", &Session::FlushStorageData)
|
||||
.SetMethod("setProxy", &Session::SetProxy)
|
||||
.SetMethod("setDownloadPath", &Session::SetDownloadPath)
|
||||
.SetMethod("enableNetworkEmulation", &Session::EnableNetworkEmulation)
|
||||
.SetMethod("disableNetworkEmulation", &Session::DisableNetworkEmulation)
|
||||
.SetMethod("setCertificateVerifyProc", &Session::SetCertVerifyProc)
|
||||
.SetMethod("setPermissionRequestHandler",
|
||||
&Session::SetPermissionRequestHandler)
|
||||
.SetMethod("setPermissionCheckHandler",
|
||||
&Session::SetPermissionCheckHandler)
|
||||
.SetMethod("clearHostResolverCache", &Session::ClearHostResolverCache)
|
||||
.SetMethod("clearAuthCache", &Session::ClearAuthCache)
|
||||
.SetMethod("allowNTLMCredentialsForDomains",
|
||||
&Session::AllowNTLMCredentialsForDomains)
|
||||
.SetMethod("setUserAgent", &Session::SetUserAgent)
|
||||
.SetMethod("getUserAgent", &Session::GetUserAgent)
|
||||
.SetMethod("getBlobData", &Session::GetBlobData)
|
||||
.SetMethod("createInterruptedDownload",
|
||||
&Session::CreateInterruptedDownload)
|
||||
.SetMethod("setPreloads", &Session::SetPreloads)
|
||||
.SetMethod("getPreloads", &Session::GetPreloads)
|
||||
.SetProperty("cookies", &Session::Cookies)
|
||||
.SetProperty("netLog", &Session::NetLog)
|
||||
.SetProperty("protocol", &Session::Protocol)
|
||||
.SetProperty("webRequest", &Session::WebRequest);
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
|
||||
namespace {
|
||||
|
||||
using atom::api::Cookies;
|
||||
using atom::api::NetLog;
|
||||
using atom::api::Protocol;
|
||||
using atom::api::Session;
|
||||
|
||||
v8::Local<v8::Value> FromPartition(const std::string& partition,
|
||||
mate::Arguments* args) {
|
||||
if (!atom::Browser::Get()->is_ready()) {
|
||||
args->ThrowError("Session can only be received when app is ready");
|
||||
return v8::Null(args->isolate());
|
||||
}
|
||||
base::DictionaryValue options;
|
||||
args->GetNext(&options);
|
||||
return Session::FromPartition(args->isolate(), partition, options).ToV8();
|
||||
}
|
||||
|
||||
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(
|
||||
"Session",
|
||||
Session::GetConstructor(isolate)->GetFunction(context).ToLocalChecked());
|
||||
dict.Set(
|
||||
"Cookies",
|
||||
Cookies::GetConstructor(isolate)->GetFunction(context).ToLocalChecked());
|
||||
dict.Set(
|
||||
"NetLog",
|
||||
NetLog::GetConstructor(isolate)->GetFunction(context).ToLocalChecked());
|
||||
dict.Set(
|
||||
"Protocol",
|
||||
Protocol::GetConstructor(isolate)->GetFunction(context).ToLocalChecked());
|
||||
dict.SetMethod("fromPartition", &FromPartition);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_session, Initialize)
|
||||
121
atom/browser/api/atom_api_session.h
Normal file
121
atom/browser/api/atom_api_session.h
Normal file
@@ -0,0 +1,121 @@
|
||||
// Copyright (c) 2015 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ATOM_BROWSER_API_ATOM_API_SESSION_H_
|
||||
#define ATOM_BROWSER_API_ATOM_API_SESSION_H_
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "atom/browser/api/trackable_object.h"
|
||||
#include "atom/browser/atom_blob_reader.h"
|
||||
#include "atom/browser/net/resolve_proxy_helper.h"
|
||||
#include "atom/common/promise_util.h"
|
||||
#include "base/values.h"
|
||||
#include "content/public/browser/download_manager.h"
|
||||
#include "native_mate/handle.h"
|
||||
|
||||
class GURL;
|
||||
|
||||
namespace base {
|
||||
class FilePath;
|
||||
}
|
||||
|
||||
namespace mate {
|
||||
class Arguments;
|
||||
class Dictionary;
|
||||
} // namespace mate
|
||||
|
||||
namespace net {
|
||||
class ProxyConfig;
|
||||
}
|
||||
|
||||
namespace atom {
|
||||
|
||||
class AtomBrowserContext;
|
||||
|
||||
namespace api {
|
||||
|
||||
class Session : public mate::TrackableObject<Session>,
|
||||
public content::DownloadManager::Observer {
|
||||
public:
|
||||
enum class CacheAction {
|
||||
CLEAR,
|
||||
STATS,
|
||||
};
|
||||
|
||||
// Gets or creates Session from the |browser_context|.
|
||||
static mate::Handle<Session> CreateFrom(v8::Isolate* isolate,
|
||||
AtomBrowserContext* browser_context);
|
||||
|
||||
// Gets the Session of |partition|.
|
||||
static mate::Handle<Session> FromPartition(
|
||||
v8::Isolate* isolate,
|
||||
const std::string& partition,
|
||||
const base::DictionaryValue& options = base::DictionaryValue());
|
||||
|
||||
AtomBrowserContext* browser_context() const { return browser_context_.get(); }
|
||||
|
||||
// mate::TrackableObject:
|
||||
static void BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype);
|
||||
|
||||
// Methods.
|
||||
v8::Local<v8::Promise> ResolveProxy(mate::Arguments* args);
|
||||
v8::Local<v8::Promise> GetCacheSize();
|
||||
v8::Local<v8::Promise> ClearCache();
|
||||
v8::Local<v8::Promise> ClearStorageData(mate::Arguments* args);
|
||||
void FlushStorageData();
|
||||
v8::Local<v8::Promise> SetProxy(mate::Arguments* args);
|
||||
void SetDownloadPath(const base::FilePath& path);
|
||||
void EnableNetworkEmulation(const mate::Dictionary& options);
|
||||
void DisableNetworkEmulation();
|
||||
void SetCertVerifyProc(v8::Local<v8::Value> proc, mate::Arguments* args);
|
||||
void SetPermissionRequestHandler(v8::Local<v8::Value> val,
|
||||
mate::Arguments* args);
|
||||
void SetPermissionCheckHandler(v8::Local<v8::Value> val,
|
||||
mate::Arguments* args);
|
||||
v8::Local<v8::Promise> ClearHostResolverCache(mate::Arguments* args);
|
||||
v8::Local<v8::Promise> ClearAuthCache(mate::Arguments* args);
|
||||
void AllowNTLMCredentialsForDomains(const std::string& domains);
|
||||
void SetUserAgent(const std::string& user_agent, mate::Arguments* args);
|
||||
std::string GetUserAgent();
|
||||
v8::Local<v8::Promise> GetBlobData(v8::Isolate* isolate,
|
||||
const std::string& uuid);
|
||||
void CreateInterruptedDownload(const mate::Dictionary& options);
|
||||
void SetPreloads(const std::vector<base::FilePath::StringType>& preloads);
|
||||
std::vector<base::FilePath::StringType> GetPreloads() const;
|
||||
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);
|
||||
~Session() override;
|
||||
|
||||
// content::DownloadManager::Observer:
|
||||
void OnDownloadCreated(content::DownloadManager* manager,
|
||||
download::DownloadItem* item) override;
|
||||
|
||||
private:
|
||||
// Cached object.
|
||||
v8::Global<v8::Value> cookies_;
|
||||
v8::Global<v8::Value> protocol_;
|
||||
v8::Global<v8::Value> web_request_;
|
||||
v8::Global<v8::Value> net_log_;
|
||||
|
||||
// The client id to enable the network throttler.
|
||||
base::UnguessableToken network_emulation_token_;
|
||||
|
||||
scoped_refptr<AtomBrowserContext> browser_context_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(Session);
|
||||
};
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_API_ATOM_API_SESSION_H_
|
||||
@@ -2,18 +2,16 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "shell/browser/api/electron_api_system_preferences.h"
|
||||
#include "atom/browser/api/atom_api_system_preferences.h"
|
||||
|
||||
#include "shell/common/gin_converters/callback_converter.h"
|
||||
#include "shell/common/gin_converters/value_converter.h"
|
||||
#include "shell/common/gin_helper/dictionary.h"
|
||||
#include "shell/common/gin_helper/object_template_builder.h"
|
||||
#include "shell/common/node_includes.h"
|
||||
#include "atom/common/native_mate_converters/callback.h"
|
||||
#include "atom/common/native_mate_converters/value_converter.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "ui/gfx/animation/animation.h"
|
||||
#include "ui/gfx/color_utils.h"
|
||||
#include "ui/native_theme/native_theme.h"
|
||||
|
||||
namespace electron {
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
@@ -32,23 +30,23 @@ SystemPreferences::~SystemPreferences() {
|
||||
|
||||
#if !defined(OS_MACOSX)
|
||||
bool SystemPreferences::IsDarkMode() {
|
||||
return ui::NativeTheme::GetInstanceForNativeUi()->ShouldUseDarkColors();
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool SystemPreferences::IsInvertedColorScheme() {
|
||||
return ui::NativeTheme::GetInstanceForNativeUi()
|
||||
->GetPlatformHighContrastColorScheme() ==
|
||||
ui::NativeTheme::PlatformHighContrastColorScheme::kDark;
|
||||
return color_utils::IsInvertedColorScheme();
|
||||
}
|
||||
|
||||
#if !defined(OS_WIN)
|
||||
bool SystemPreferences::IsHighContrastColorScheme() {
|
||||
return ui::NativeTheme::GetInstanceForNativeUi()->UsesHighContrastColors();
|
||||
return false;
|
||||
}
|
||||
#endif // !defined(OS_WIN)
|
||||
|
||||
v8::Local<v8::Value> SystemPreferences::GetAnimationSettings(
|
||||
v8::Isolate* isolate) {
|
||||
gin_helper::Dictionary dict = gin::Dictionary::CreateEmpty(isolate);
|
||||
mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate);
|
||||
dict.SetHidden("simple", true);
|
||||
dict.Set("shouldRenderRichAnimation",
|
||||
gfx::Animation::ShouldRenderRichAnimation());
|
||||
@@ -60,21 +58,20 @@ v8::Local<v8::Value> SystemPreferences::GetAnimationSettings(
|
||||
}
|
||||
|
||||
// static
|
||||
gin::Handle<SystemPreferences> SystemPreferences::Create(v8::Isolate* isolate) {
|
||||
return gin::CreateHandle(isolate, new SystemPreferences(isolate));
|
||||
mate::Handle<SystemPreferences> SystemPreferences::Create(
|
||||
v8::Isolate* isolate) {
|
||||
return mate::CreateHandle(isolate, new SystemPreferences(isolate));
|
||||
}
|
||||
|
||||
// static
|
||||
void SystemPreferences::BuildPrototype(
|
||||
v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype) {
|
||||
prototype->SetClassName(gin::StringToV8(isolate, "SystemPreferences"));
|
||||
gin_helper::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
||||
prototype->SetClassName(mate::StringToV8(isolate, "SystemPreferences"));
|
||||
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
||||
#if defined(OS_WIN) || defined(OS_MACOSX)
|
||||
.SetMethod("getColor", &SystemPreferences::GetColor)
|
||||
.SetMethod("getAccentColor", &SystemPreferences::GetAccentColor)
|
||||
.SetMethod("getMediaAccessStatus",
|
||||
&SystemPreferences::GetMediaAccessStatus)
|
||||
#endif
|
||||
|
||||
#if defined(OS_WIN)
|
||||
@@ -114,6 +111,8 @@ void SystemPreferences::BuildPrototype(
|
||||
.SetMethod("promptTouchID", &SystemPreferences::PromptTouchID)
|
||||
.SetMethod("isTrustedAccessibilityClient",
|
||||
&SystemPreferences::IsTrustedAccessibilityClient)
|
||||
.SetMethod("getMediaAccessStatus",
|
||||
&SystemPreferences::GetMediaAccessStatus)
|
||||
.SetMethod("askForMediaAccess", &SystemPreferences::AskForMediaAccess)
|
||||
#endif
|
||||
.SetMethod("isInvertedColorScheme",
|
||||
@@ -127,18 +126,18 @@ void SystemPreferences::BuildPrototype(
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace electron
|
||||
} // namespace atom
|
||||
|
||||
namespace {
|
||||
|
||||
using electron::api::SystemPreferences;
|
||||
using atom::api::SystemPreferences;
|
||||
|
||||
void Initialize(v8::Local<v8::Object> exports,
|
||||
v8::Local<v8::Value> unused,
|
||||
v8::Local<v8::Context> context,
|
||||
void* priv) {
|
||||
v8::Isolate* isolate = context->GetIsolate();
|
||||
gin_helper::Dictionary dict(isolate, exports);
|
||||
mate::Dictionary dict(isolate, exports);
|
||||
dict.Set("systemPreferences", SystemPreferences::Create(isolate));
|
||||
dict.Set("SystemPreferences", SystemPreferences::GetConstructor(isolate)
|
||||
->GetFunction(context)
|
||||
@@ -147,5 +146,4 @@ void Initialize(v8::Local<v8::Object> exports,
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(electron_browser_system_preferences,
|
||||
Initialize)
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_system_preferences, Initialize)
|
||||
@@ -2,25 +2,29 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef SHELL_BROWSER_API_ELECTRON_API_SYSTEM_PREFERENCES_H_
|
||||
#define SHELL_BROWSER_API_ELECTRON_API_SYSTEM_PREFERENCES_H_
|
||||
#ifndef ATOM_BROWSER_API_ATOM_API_SYSTEM_PREFERENCES_H_
|
||||
#define ATOM_BROWSER_API_ATOM_API_SYSTEM_PREFERENCES_H_
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "atom/browser/api/event_emitter.h"
|
||||
#include "atom/common/promise_util.h"
|
||||
#include "base/callback.h"
|
||||
#include "base/values.h"
|
||||
#include "gin/handle.h"
|
||||
#include "shell/common/gin_helper/error_thrower.h"
|
||||
#include "shell/common/gin_helper/event_emitter.h"
|
||||
#include "shell/common/gin_helper/promise.h"
|
||||
#include "native_mate/handle.h"
|
||||
|
||||
#if defined(OS_WIN)
|
||||
#include "shell/browser/browser.h"
|
||||
#include "shell/browser/browser_observer.h"
|
||||
#include "atom/browser/browser.h"
|
||||
#include "atom/browser/browser_observer.h"
|
||||
#include "ui/gfx/sys_color_change_listener.h"
|
||||
#endif
|
||||
|
||||
namespace electron {
|
||||
namespace base {
|
||||
class DictionaryValue;
|
||||
}
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
@@ -32,7 +36,7 @@ enum NotificationCenterKind {
|
||||
};
|
||||
#endif
|
||||
|
||||
class SystemPreferences : public gin_helper::EventEmitter<SystemPreferences>
|
||||
class SystemPreferences : public mate::EventEmitter<SystemPreferences>
|
||||
#if defined(OS_WIN)
|
||||
,
|
||||
public BrowserObserver,
|
||||
@@ -40,17 +44,14 @@ class SystemPreferences : public gin_helper::EventEmitter<SystemPreferences>
|
||||
#endif
|
||||
{
|
||||
public:
|
||||
static gin::Handle<SystemPreferences> Create(v8::Isolate* isolate);
|
||||
static mate::Handle<SystemPreferences> Create(v8::Isolate* isolate);
|
||||
|
||||
static void BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype);
|
||||
|
||||
#if defined(OS_WIN) || defined(OS_MACOSX)
|
||||
std::string GetAccentColor();
|
||||
std::string GetColor(gin_helper::ErrorThrower thrower,
|
||||
const std::string& color);
|
||||
std::string GetMediaAccessStatus(const std::string& media_type,
|
||||
gin_helper::Arguments* args);
|
||||
std::string GetColor(const std::string& color, mate::Arguments* args);
|
||||
#endif
|
||||
#if defined(OS_WIN)
|
||||
bool IsAeroGlassEnabled();
|
||||
@@ -64,36 +65,35 @@ class SystemPreferences : public gin_helper::EventEmitter<SystemPreferences>
|
||||
void OnFinishLaunching(const base::DictionaryValue& launch_info) override;
|
||||
|
||||
#elif defined(OS_MACOSX)
|
||||
using NotificationCallback = base::RepeatingCallback<
|
||||
void(const std::string&, base::DictionaryValue, const std::string&)>;
|
||||
using NotificationCallback =
|
||||
base::Callback<void(const std::string&, const base::DictionaryValue&)>;
|
||||
|
||||
void PostNotification(const std::string& name,
|
||||
base::DictionaryValue user_info,
|
||||
gin_helper::Arguments* args);
|
||||
const base::DictionaryValue& user_info,
|
||||
mate::Arguments* args);
|
||||
int SubscribeNotification(const std::string& name,
|
||||
const NotificationCallback& callback);
|
||||
void UnsubscribeNotification(int id);
|
||||
void PostLocalNotification(const std::string& name,
|
||||
base::DictionaryValue user_info);
|
||||
const base::DictionaryValue& user_info);
|
||||
int SubscribeLocalNotification(const std::string& name,
|
||||
const NotificationCallback& callback);
|
||||
void UnsubscribeLocalNotification(int request_id);
|
||||
void PostWorkspaceNotification(const std::string& name,
|
||||
base::DictionaryValue user_info);
|
||||
const base::DictionaryValue& user_info);
|
||||
int SubscribeWorkspaceNotification(const std::string& name,
|
||||
const NotificationCallback& callback);
|
||||
void UnsubscribeWorkspaceNotification(int request_id);
|
||||
v8::Local<v8::Value> GetUserDefault(const std::string& name,
|
||||
const std::string& type);
|
||||
void RegisterDefaults(gin_helper::Arguments* args);
|
||||
void RegisterDefaults(mate::Arguments* args);
|
||||
void SetUserDefault(const std::string& name,
|
||||
const std::string& type,
|
||||
gin_helper::Arguments* args);
|
||||
mate::Arguments* args);
|
||||
void RemoveUserDefault(const std::string& name);
|
||||
bool IsSwipeTrackingFromScrollEventsEnabled();
|
||||
|
||||
std::string GetSystemColor(gin_helper::ErrorThrower thrower,
|
||||
const std::string& color);
|
||||
std::string GetSystemColor(const std::string& color, mate::Arguments* args);
|
||||
|
||||
bool CanPromptTouchID();
|
||||
v8::Local<v8::Promise> PromptTouchID(v8::Isolate* isolate,
|
||||
@@ -101,6 +101,10 @@ class SystemPreferences : public gin_helper::EventEmitter<SystemPreferences>
|
||||
|
||||
static bool IsTrustedAccessibilityClient(bool prompt);
|
||||
|
||||
// TODO(codebytere): Write tests for these methods once we
|
||||
// are running tests on a Mojave machine
|
||||
std::string GetMediaAccessStatus(const std::string& media_type,
|
||||
mate::Arguments* args);
|
||||
v8::Local<v8::Promise> AskForMediaAccess(v8::Isolate* isolate,
|
||||
const std::string& media_type);
|
||||
|
||||
@@ -108,7 +112,7 @@ class SystemPreferences : public gin_helper::EventEmitter<SystemPreferences>
|
||||
// are running tests on a Mojave machine
|
||||
v8::Local<v8::Value> GetEffectiveAppearance(v8::Isolate* isolate);
|
||||
v8::Local<v8::Value> GetAppLevelAppearance(v8::Isolate* isolate);
|
||||
void SetAppLevelAppearance(gin_helper::Arguments* args);
|
||||
void SetAppLevelAppearance(mate::Arguments* args);
|
||||
#endif
|
||||
bool IsDarkMode();
|
||||
bool IsInvertedColorScheme();
|
||||
@@ -161,6 +165,6 @@ class SystemPreferences : public gin_helper::EventEmitter<SystemPreferences>
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace electron
|
||||
} // namespace atom
|
||||
|
||||
#endif // SHELL_BROWSER_API_ELECTRON_API_SYSTEM_PREFERENCES_H_
|
||||
#endif // ATOM_BROWSER_API_ATOM_API_SYSTEM_PREFERENCES_H_
|
||||
@@ -2,18 +2,20 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "shell/browser/api/electron_api_system_preferences.h"
|
||||
#include "atom/browser/api/atom_api_system_preferences.h"
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#import <AVFoundation/AVFoundation.h>
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import <LocalAuthentication/LocalAuthentication.h>
|
||||
#import <Security/Security.h>
|
||||
|
||||
#include "atom/browser/mac/atom_application.h"
|
||||
#include "atom/browser/mac/dict_util.h"
|
||||
#include "atom/browser/ui/cocoa/NSColor+Hex.h"
|
||||
#include "atom/common/native_mate_converters/gurl_converter.h"
|
||||
#include "atom/common/native_mate_converters/value_converter.h"
|
||||
#include "base/mac/scoped_cftyperef.h"
|
||||
#include "base/mac/sdk_forward_declarations.h"
|
||||
#include "base/sequenced_task_runner.h"
|
||||
@@ -21,18 +23,11 @@
|
||||
#include "base/strings/sys_string_conversions.h"
|
||||
#include "base/threading/sequenced_task_runner_handle.h"
|
||||
#include "base/values.h"
|
||||
#include "chrome/browser/media/webrtc/system_media_capture_permissions_mac.h"
|
||||
#include "native_mate/object_template_builder.h"
|
||||
#include "net/base/mac/url_conversions.h"
|
||||
#include "shell/browser/mac/dict_util.h"
|
||||
#include "shell/browser/mac/electron_application.h"
|
||||
#include "shell/browser/ui/cocoa/NSColor+Hex.h"
|
||||
#include "shell/common/gin_converters/gurl_converter.h"
|
||||
#include "shell/common/gin_converters/value_converter.h"
|
||||
#include "shell/common/process_util.h"
|
||||
#include "ui/native_theme/native_theme.h"
|
||||
|
||||
namespace gin {
|
||||
|
||||
namespace mate {
|
||||
template <>
|
||||
struct Converter<NSAppearance*> {
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
@@ -44,7 +39,7 @@ struct Converter<NSAppearance*> {
|
||||
}
|
||||
|
||||
std::string name;
|
||||
if (!gin::ConvertFromV8(isolate, val, &name)) {
|
||||
if (!mate::ConvertFromV8(isolate, val, &name)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -69,21 +64,20 @@ struct Converter<NSAppearance*> {
|
||||
}
|
||||
|
||||
if ([val.name isEqualToString:NSAppearanceNameAqua]) {
|
||||
return gin::ConvertToV8(isolate, "light");
|
||||
return mate::ConvertToV8(isolate, "light");
|
||||
}
|
||||
if (@available(macOS 10.14, *)) {
|
||||
if ([val.name isEqualToString:NSAppearanceNameDarkAqua]) {
|
||||
return gin::ConvertToV8(isolate, "dark");
|
||||
return mate::ConvertToV8(isolate, "dark");
|
||||
}
|
||||
}
|
||||
|
||||
return gin::ConvertToV8(isolate, "unknown");
|
||||
return mate::ConvertToV8(isolate, "unknown");
|
||||
}
|
||||
};
|
||||
} // namespace mate
|
||||
|
||||
} // namespace gin
|
||||
|
||||
namespace electron {
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
@@ -104,17 +98,15 @@ AVMediaType ParseMediaType(const std::string& media_type) {
|
||||
}
|
||||
}
|
||||
|
||||
std::string ConvertSystemPermission(
|
||||
system_media_permissions::SystemPermission value) {
|
||||
using SystemPermission = system_media_permissions::SystemPermission;
|
||||
switch (value) {
|
||||
case SystemPermission::kNotDetermined:
|
||||
std::string ConvertAuthorizationStatus(AVAuthorizationStatusMac status) {
|
||||
switch (status) {
|
||||
case AVAuthorizationStatusNotDeterminedMac:
|
||||
return "not-determined";
|
||||
case SystemPermission::kRestricted:
|
||||
case AVAuthorizationStatusRestrictedMac:
|
||||
return "restricted";
|
||||
case SystemPermission::kDenied:
|
||||
case AVAuthorizationStatusDeniedMac:
|
||||
return "denied";
|
||||
case SystemPermission::kAllowed:
|
||||
case AVAuthorizationStatusAuthorizedMac:
|
||||
return "granted";
|
||||
default:
|
||||
return "unknown";
|
||||
@@ -124,8 +116,8 @@ std::string ConvertSystemPermission(
|
||||
} // namespace
|
||||
|
||||
void SystemPreferences::PostNotification(const std::string& name,
|
||||
base::DictionaryValue user_info,
|
||||
gin_helper::Arguments* args) {
|
||||
const base::DictionaryValue& user_info,
|
||||
mate::Arguments* args) {
|
||||
bool immediate = false;
|
||||
args->GetNext(&immediate);
|
||||
|
||||
@@ -148,8 +140,9 @@ void SystemPreferences::UnsubscribeNotification(int request_id) {
|
||||
DoUnsubscribeNotification(request_id, kNSDistributedNotificationCenter);
|
||||
}
|
||||
|
||||
void SystemPreferences::PostLocalNotification(const std::string& name,
|
||||
base::DictionaryValue user_info) {
|
||||
void SystemPreferences::PostLocalNotification(
|
||||
const std::string& name,
|
||||
const base::DictionaryValue& user_info) {
|
||||
NSNotificationCenter* center = [NSNotificationCenter defaultCenter];
|
||||
[center postNotificationName:base::SysUTF8ToNSString(name)
|
||||
object:nil
|
||||
@@ -168,7 +161,7 @@ void SystemPreferences::UnsubscribeLocalNotification(int request_id) {
|
||||
|
||||
void SystemPreferences::PostWorkspaceNotification(
|
||||
const std::string& name,
|
||||
base::DictionaryValue user_info) {
|
||||
const base::DictionaryValue& user_info) {
|
||||
NSNotificationCenter* center =
|
||||
[[NSWorkspace sharedWorkspace] notificationCenter];
|
||||
[center postNotificationName:base::SysUTF8ToNSString(name)
|
||||
@@ -213,20 +206,15 @@ int SystemPreferences::DoSubscribeNotification(
|
||||
object:nil
|
||||
queue:nil
|
||||
usingBlock:^(NSNotification* notification) {
|
||||
std::string object = "";
|
||||
if ([notification.object isKindOfClass:[NSString class]]) {
|
||||
object = base::SysNSStringToUTF8(notification.object);
|
||||
}
|
||||
|
||||
if (notification.userInfo) {
|
||||
std::unique_ptr<base::DictionaryValue> user_info =
|
||||
NSDictionaryToDictionaryValue(notification.userInfo);
|
||||
if (user_info) {
|
||||
copied_callback.Run(
|
||||
base::SysNSStringToUTF8(notification.name),
|
||||
NSDictionaryToDictionaryValue(notification.userInfo),
|
||||
object);
|
||||
base::SysNSStringToUTF8(notification.name), *user_info);
|
||||
} else {
|
||||
copied_callback.Run(
|
||||
base::SysNSStringToUTF8(notification.name),
|
||||
base::DictionaryValue(), object);
|
||||
base::DictionaryValue());
|
||||
}
|
||||
}];
|
||||
return request_id;
|
||||
@@ -262,7 +250,7 @@ v8::Local<v8::Value> SystemPreferences::GetUserDefault(
|
||||
NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
|
||||
NSString* key = base::SysUTF8ToNSString(name);
|
||||
if (type == "string") {
|
||||
return gin::StringToV8(
|
||||
return mate::StringToV8(
|
||||
isolate(), base::SysNSStringToUTF8([defaults stringForKey:key]));
|
||||
} else if (type == "boolean") {
|
||||
return v8::Boolean::New(isolate(), [defaults boolForKey:key]);
|
||||
@@ -273,20 +261,26 @@ v8::Local<v8::Value> SystemPreferences::GetUserDefault(
|
||||
} else if (type == "double") {
|
||||
return v8::Number::New(isolate(), [defaults doubleForKey:key]);
|
||||
} else if (type == "url") {
|
||||
return gin::ConvertToV8(isolate(),
|
||||
net::GURLWithNSURL([defaults URLForKey:key]));
|
||||
return mate::ConvertToV8(isolate(),
|
||||
net::GURLWithNSURL([defaults URLForKey:key]));
|
||||
} else if (type == "array") {
|
||||
return gin::ConvertToV8(isolate(),
|
||||
NSArrayToListValue([defaults arrayForKey:key]));
|
||||
std::unique_ptr<base::ListValue> list =
|
||||
NSArrayToListValue([defaults arrayForKey:key]);
|
||||
if (list == nullptr)
|
||||
list.reset(new base::ListValue());
|
||||
return mate::ConvertToV8(isolate(), *list);
|
||||
} else if (type == "dictionary") {
|
||||
return gin::ConvertToV8(isolate(), NSDictionaryToDictionaryValue(
|
||||
[defaults dictionaryForKey:key]));
|
||||
std::unique_ptr<base::DictionaryValue> dictionary =
|
||||
NSDictionaryToDictionaryValue([defaults dictionaryForKey:key]);
|
||||
if (dictionary == nullptr)
|
||||
dictionary.reset(new base::DictionaryValue());
|
||||
return mate::ConvertToV8(isolate(), *dictionary);
|
||||
} else {
|
||||
return v8::Undefined(isolate());
|
||||
}
|
||||
}
|
||||
|
||||
void SystemPreferences::RegisterDefaults(gin_helper::Arguments* args) {
|
||||
void SystemPreferences::RegisterDefaults(mate::Arguments* args) {
|
||||
base::DictionaryValue value;
|
||||
|
||||
if (!args->GetNext(&value)) {
|
||||
@@ -310,69 +304,87 @@ void SystemPreferences::RegisterDefaults(gin_helper::Arguments* args) {
|
||||
|
||||
void SystemPreferences::SetUserDefault(const std::string& name,
|
||||
const std::string& type,
|
||||
gin_helper::Arguments* args) {
|
||||
mate::Arguments* args) {
|
||||
const auto throwConversionError = [&] {
|
||||
args->ThrowError("Unable to convert value to: " + type);
|
||||
};
|
||||
|
||||
NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
|
||||
NSString* key = base::SysUTF8ToNSString(name);
|
||||
if (type == "string") {
|
||||
std::string value;
|
||||
if (args->GetNext(&value)) {
|
||||
[defaults setObject:base::SysUTF8ToNSString(value) forKey:key];
|
||||
if (!args->GetNext(&value)) {
|
||||
throwConversionError();
|
||||
return;
|
||||
}
|
||||
|
||||
[defaults setObject:base::SysUTF8ToNSString(value) forKey:key];
|
||||
} else if (type == "boolean") {
|
||||
bool value;
|
||||
if (args->GetNext(&value)) {
|
||||
[defaults setBool:value forKey:key];
|
||||
if (!args->GetNext(&value)) {
|
||||
throwConversionError();
|
||||
return;
|
||||
}
|
||||
|
||||
[defaults setBool:value forKey:key];
|
||||
} else if (type == "float") {
|
||||
float value;
|
||||
if (args->GetNext(&value)) {
|
||||
[defaults setFloat:value forKey:key];
|
||||
if (!args->GetNext(&value)) {
|
||||
throwConversionError();
|
||||
return;
|
||||
}
|
||||
|
||||
[defaults setFloat:value forKey:key];
|
||||
} else if (type == "integer") {
|
||||
int value;
|
||||
if (args->GetNext(&value)) {
|
||||
[defaults setInteger:value forKey:key];
|
||||
if (!args->GetNext(&value)) {
|
||||
throwConversionError();
|
||||
return;
|
||||
}
|
||||
|
||||
[defaults setInteger:value forKey:key];
|
||||
} else if (type == "double") {
|
||||
double value;
|
||||
if (args->GetNext(&value)) {
|
||||
[defaults setDouble:value forKey:key];
|
||||
if (!args->GetNext(&value)) {
|
||||
throwConversionError();
|
||||
return;
|
||||
}
|
||||
|
||||
[defaults setDouble:value forKey:key];
|
||||
} else if (type == "url") {
|
||||
GURL value;
|
||||
if (args->GetNext(&value)) {
|
||||
if (NSURL* url = net::NSURLWithGURL(value)) {
|
||||
[defaults setURL:url forKey:key];
|
||||
return;
|
||||
}
|
||||
if (!args->GetNext(&value)) {
|
||||
throwConversionError();
|
||||
return;
|
||||
}
|
||||
|
||||
if (NSURL* url = net::NSURLWithGURL(value)) {
|
||||
[defaults setURL:url forKey:key];
|
||||
}
|
||||
} else if (type == "array") {
|
||||
base::ListValue value;
|
||||
if (args->GetNext(&value)) {
|
||||
if (NSArray* array = ListValueToNSArray(value)) {
|
||||
[defaults setObject:array forKey:key];
|
||||
return;
|
||||
}
|
||||
if (!args->GetNext(&value)) {
|
||||
throwConversionError();
|
||||
return;
|
||||
}
|
||||
|
||||
if (NSArray* array = ListValueToNSArray(value)) {
|
||||
[defaults setObject:array forKey:key];
|
||||
}
|
||||
} else if (type == "dictionary") {
|
||||
base::DictionaryValue value;
|
||||
if (args->GetNext(&value)) {
|
||||
if (NSDictionary* dict = DictionaryValueToNSDictionary(value)) {
|
||||
[defaults setObject:dict forKey:key];
|
||||
return;
|
||||
}
|
||||
if (!args->GetNext(&value)) {
|
||||
throwConversionError();
|
||||
return;
|
||||
}
|
||||
|
||||
if (NSDictionary* dict = DictionaryValueToNSDictionary(value)) {
|
||||
[defaults setObject:dict forKey:key];
|
||||
}
|
||||
} else {
|
||||
args->ThrowError("Invalid type: " + type);
|
||||
return;
|
||||
}
|
||||
|
||||
args->ThrowError("Unable to convert value to: " + type);
|
||||
}
|
||||
|
||||
std::string SystemPreferences::GetAccentColor() {
|
||||
@@ -383,8 +395,8 @@ std::string SystemPreferences::GetAccentColor() {
|
||||
return base::SysNSStringToUTF8([sysColor RGBAValue]);
|
||||
}
|
||||
|
||||
std::string SystemPreferences::GetSystemColor(gin_helper::ErrorThrower thrower,
|
||||
const std::string& color) {
|
||||
std::string SystemPreferences::GetSystemColor(const std::string& color,
|
||||
mate::Arguments* args) {
|
||||
NSColor* sysColor = nil;
|
||||
if (color == "blue") {
|
||||
sysColor = [NSColor systemBlueColor];
|
||||
@@ -405,7 +417,7 @@ std::string SystemPreferences::GetSystemColor(gin_helper::ErrorThrower thrower,
|
||||
} else if (color == "yellow") {
|
||||
sysColor = [NSColor systemYellowColor];
|
||||
} else {
|
||||
thrower.ThrowError("Unknown system color: " + color);
|
||||
args->ThrowError("Unknown system color: " + color);
|
||||
return "";
|
||||
}
|
||||
|
||||
@@ -429,7 +441,7 @@ bool SystemPreferences::CanPromptTouchID() {
|
||||
v8::Local<v8::Promise> SystemPreferences::PromptTouchID(
|
||||
v8::Isolate* isolate,
|
||||
const std::string& reason) {
|
||||
gin_helper::Promise<void> promise(isolate);
|
||||
util::Promise promise(isolate);
|
||||
v8::Local<v8::Promise> handle = promise.GetHandle();
|
||||
|
||||
if (@available(macOS 10.12.2, *)) {
|
||||
@@ -446,7 +458,7 @@ v8::Local<v8::Promise> SystemPreferences::PromptTouchID(
|
||||
scoped_refptr<base::SequencedTaskRunner> runner =
|
||||
base::SequencedTaskRunnerHandle::Get();
|
||||
|
||||
__block gin_helper::Promise<void> p = std::move(promise);
|
||||
__block util::Promise p = std::move(promise);
|
||||
[context
|
||||
evaluateAccessControl:access_control
|
||||
operation:LAAccessControlOperationUseKeySign
|
||||
@@ -457,14 +469,14 @@ v8::Local<v8::Promise> SystemPreferences::PromptTouchID(
|
||||
[error.localizedDescription UTF8String]);
|
||||
runner->PostTask(
|
||||
FROM_HERE,
|
||||
base::BindOnce(
|
||||
gin_helper::Promise<void>::RejectPromise,
|
||||
std::move(p), std::move(err_msg)));
|
||||
base::BindOnce(util::Promise::RejectPromise,
|
||||
std::move(p),
|
||||
std::move(err_msg)));
|
||||
} else {
|
||||
runner->PostTask(
|
||||
FROM_HERE,
|
||||
base::BindOnce(
|
||||
gin_helper::Promise<void>::ResolvePromise,
|
||||
util::Promise::ResolveEmptyPromise,
|
||||
std::move(p)));
|
||||
}
|
||||
}];
|
||||
@@ -481,23 +493,18 @@ bool SystemPreferences::IsTrustedAccessibilityClient(bool prompt) {
|
||||
return AXIsProcessTrustedWithOptions((CFDictionaryRef)options);
|
||||
}
|
||||
|
||||
std::string SystemPreferences::GetColor(gin_helper::ErrorThrower thrower,
|
||||
const std::string& color) {
|
||||
std::string SystemPreferences::GetColor(const std::string& color,
|
||||
mate::Arguments* args) {
|
||||
NSColor* sysColor = nil;
|
||||
if (color == "alternate-selected-control-text") {
|
||||
sysColor = [NSColor alternateSelectedControlTextColor];
|
||||
EmitWarning(
|
||||
node::Environment::GetCurrent(thrower.isolate()),
|
||||
"'alternate-selected-control-text' is deprecated as an input to "
|
||||
"getColor. Use 'selected-content-background' instead.",
|
||||
"electron");
|
||||
} else if (color == "control-background") {
|
||||
sysColor = [NSColor controlBackgroundColor];
|
||||
} else if (color == "control") {
|
||||
sysColor = [NSColor controlColor];
|
||||
} else if (color == "control-text") {
|
||||
sysColor = [NSColor controlTextColor];
|
||||
} else if (color == "disabled-control-text") {
|
||||
} else if (color == "disabled-control") {
|
||||
sysColor = [NSColor disabledControlTextColor];
|
||||
} else if (color == "find-highlight") {
|
||||
if (@available(macOS 10.14, *))
|
||||
@@ -563,26 +570,24 @@ std::string SystemPreferences::GetColor(gin_helper::ErrorThrower thrower,
|
||||
} else if (color == "window-frame-text") {
|
||||
sysColor = [NSColor windowFrameTextColor];
|
||||
} else {
|
||||
thrower.ThrowError("Unknown color: " + color);
|
||||
args->ThrowError("Unknown color: " + color);
|
||||
return "";
|
||||
}
|
||||
|
||||
if (sysColor)
|
||||
return base::SysNSStringToUTF8([sysColor hexadecimalValue]);
|
||||
return "";
|
||||
return base::SysNSStringToUTF8([sysColor hexadecimalValue]);
|
||||
}
|
||||
|
||||
std::string SystemPreferences::GetMediaAccessStatus(
|
||||
const std::string& media_type,
|
||||
gin_helper::Arguments* args) {
|
||||
if (media_type == "camera") {
|
||||
return ConvertSystemPermission(
|
||||
system_media_permissions::CheckSystemVideoCapturePermission());
|
||||
} else if (media_type == "microphone") {
|
||||
return ConvertSystemPermission(
|
||||
system_media_permissions::CheckSystemAudioCapturePermission());
|
||||
} else if (media_type == "screen") {
|
||||
return ConvertSystemPermission(
|
||||
system_media_permissions::CheckSystemScreenCapturePermission());
|
||||
mate::Arguments* args) {
|
||||
if (auto type = ParseMediaType(media_type)) {
|
||||
if (@available(macOS 10.14, *)) {
|
||||
return ConvertAuthorizationStatus(
|
||||
[AVCaptureDevice authorizationStatusForMediaType:type]);
|
||||
} else {
|
||||
// access always allowed pre-10.14 Mojave
|
||||
return ConvertAuthorizationStatus(AVAuthorizationStatusAuthorizedMac);
|
||||
}
|
||||
} else {
|
||||
args->ThrowError("Invalid media type");
|
||||
return std::string();
|
||||
@@ -592,12 +597,12 @@ std::string SystemPreferences::GetMediaAccessStatus(
|
||||
v8::Local<v8::Promise> SystemPreferences::AskForMediaAccess(
|
||||
v8::Isolate* isolate,
|
||||
const std::string& media_type) {
|
||||
gin_helper::Promise<bool> promise(isolate);
|
||||
util::Promise promise(isolate);
|
||||
v8::Local<v8::Promise> handle = promise.GetHandle();
|
||||
|
||||
if (auto type = ParseMediaType(media_type)) {
|
||||
if (@available(macOS 10.14, *)) {
|
||||
__block gin_helper::Promise<bool> p = std::move(promise);
|
||||
__block util::Promise p = std::move(promise);
|
||||
[AVCaptureDevice requestAccessForMediaType:type
|
||||
completionHandler:^(BOOL granted) {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
@@ -621,8 +626,8 @@ void SystemPreferences::RemoveUserDefault(const std::string& name) {
|
||||
}
|
||||
|
||||
bool SystemPreferences::IsDarkMode() {
|
||||
if (@available(macOS 10.14, *)) {
|
||||
return ui::NativeTheme::GetInstanceForNativeUi()->ShouldUseDarkColors();
|
||||
if (@available(macOS 10.15, *)) {
|
||||
return ui::NativeTheme::GetInstanceForNativeUi()->SystemDarkModeEnabled();
|
||||
}
|
||||
NSString* mode = [[NSUserDefaults standardUserDefaults]
|
||||
stringForKey:@"AppleInterfaceStyle"];
|
||||
@@ -636,7 +641,7 @@ bool SystemPreferences::IsSwipeTrackingFromScrollEventsEnabled() {
|
||||
v8::Local<v8::Value> SystemPreferences::GetEffectiveAppearance(
|
||||
v8::Isolate* isolate) {
|
||||
if (@available(macOS 10.14, *)) {
|
||||
return gin::ConvertToV8(
|
||||
return mate::ConvertToV8(
|
||||
isolate, [NSApplication sharedApplication].effectiveAppearance);
|
||||
}
|
||||
return v8::Null(isolate);
|
||||
@@ -645,13 +650,13 @@ v8::Local<v8::Value> SystemPreferences::GetEffectiveAppearance(
|
||||
v8::Local<v8::Value> SystemPreferences::GetAppLevelAppearance(
|
||||
v8::Isolate* isolate) {
|
||||
if (@available(macOS 10.14, *)) {
|
||||
return gin::ConvertToV8(isolate,
|
||||
[NSApplication sharedApplication].appearance);
|
||||
return mate::ConvertToV8(isolate,
|
||||
[NSApplication sharedApplication].appearance);
|
||||
}
|
||||
return v8::Null(isolate);
|
||||
}
|
||||
|
||||
void SystemPreferences::SetAppLevelAppearance(gin_helper::Arguments* args) {
|
||||
void SystemPreferences::SetAppLevelAppearance(mate::Arguments* args) {
|
||||
if (@available(macOS 10.14, *)) {
|
||||
NSAppearance* appearance;
|
||||
if (args->GetNext(&appearance)) {
|
||||
@@ -664,4 +669,4 @@ void SystemPreferences::SetAppLevelAppearance(gin_helper::Arguments* args) {
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace electron
|
||||
} // namespace atom
|
||||
@@ -3,70 +3,33 @@
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include <dwmapi.h>
|
||||
#include <windows.devices.enumeration.h>
|
||||
#include <wrl/client.h>
|
||||
#include <iomanip>
|
||||
|
||||
#include "shell/browser/api/electron_api_system_preferences.h"
|
||||
#include "atom/browser/api/atom_api_system_preferences.h"
|
||||
|
||||
#include "base/win/core_winrt_util.h"
|
||||
#include "base/win/windows_types.h"
|
||||
#include "atom/common/color_util.h"
|
||||
#include "base/win/wrapped_window_proc.h"
|
||||
#include "shell/common/color_util.h"
|
||||
#include "ui/base/win/shell.h"
|
||||
#include "ui/gfx/color_utils.h"
|
||||
#include "ui/gfx/win/hwnd_util.h"
|
||||
|
||||
namespace electron {
|
||||
namespace atom {
|
||||
|
||||
namespace {
|
||||
|
||||
const wchar_t kSystemPreferencesWindowClass[] =
|
||||
L"Electron_SystemPreferencesHostWindow";
|
||||
|
||||
using ABI::Windows::Devices::Enumeration::DeviceAccessStatus;
|
||||
using ABI::Windows::Devices::Enumeration::DeviceClass;
|
||||
using ABI::Windows::Devices::Enumeration::IDeviceAccessInformation;
|
||||
using ABI::Windows::Devices::Enumeration::IDeviceAccessInformationStatics;
|
||||
using Microsoft::WRL::ComPtr;
|
||||
bool g_is_high_contract_color_scheme = false;
|
||||
bool g_is_high_contract_color_scheme_initialized = false;
|
||||
|
||||
DeviceAccessStatus GetDeviceAccessStatus(DeviceClass device_class) {
|
||||
ComPtr<IDeviceAccessInformationStatics> dev_access_info_statics;
|
||||
HRESULT hr = base::win::GetActivationFactory<
|
||||
IDeviceAccessInformationStatics,
|
||||
RuntimeClass_Windows_Devices_Enumeration_DeviceAccessInformation>(
|
||||
&dev_access_info_statics);
|
||||
if (FAILED(hr)) {
|
||||
VLOG(1) << "IDeviceAccessInformationStatics failed: " << hr;
|
||||
return DeviceAccessStatus::DeviceAccessStatus_Allowed;
|
||||
}
|
||||
|
||||
ComPtr<IDeviceAccessInformation> dev_access_info;
|
||||
hr = dev_access_info_statics->CreateFromDeviceClass(device_class,
|
||||
&dev_access_info);
|
||||
if (FAILED(hr)) {
|
||||
VLOG(1) << "IDeviceAccessInformation failed: " << hr;
|
||||
return DeviceAccessStatus::DeviceAccessStatus_Allowed;
|
||||
}
|
||||
|
||||
auto status = DeviceAccessStatus::DeviceAccessStatus_Unspecified;
|
||||
dev_access_info->get_CurrentStatus(&status);
|
||||
return status;
|
||||
}
|
||||
|
||||
std::string ConvertDeviceAccessStatus(DeviceAccessStatus value) {
|
||||
switch (value) {
|
||||
case DeviceAccessStatus::DeviceAccessStatus_Unspecified:
|
||||
return "not-determined";
|
||||
case DeviceAccessStatus::DeviceAccessStatus_Allowed:
|
||||
return "granted";
|
||||
case DeviceAccessStatus::DeviceAccessStatus_DeniedBySystem:
|
||||
return "restricted";
|
||||
case DeviceAccessStatus::DeviceAccessStatus_DeniedByUser:
|
||||
return "denied";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
void UpdateHighContrastColorScheme() {
|
||||
HIGHCONTRAST high_contrast = {0};
|
||||
high_contrast.cbSize = sizeof(HIGHCONTRAST);
|
||||
g_is_high_contract_color_scheme =
|
||||
SystemParametersInfo(SPI_GETHIGHCONTRAST, 0, &high_contrast, 0) &&
|
||||
((high_contrast.dwFlags & HCF_HIGHCONTRASTON) != 0);
|
||||
g_is_high_contract_color_scheme_initialized = true;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
@@ -77,6 +40,12 @@ bool SystemPreferences::IsAeroGlassEnabled() {
|
||||
return ui::win::IsAeroGlassEnabled();
|
||||
}
|
||||
|
||||
bool SystemPreferences::IsHighContrastColorScheme() {
|
||||
if (!g_is_high_contract_color_scheme_initialized)
|
||||
UpdateHighContrastColorScheme();
|
||||
return g_is_high_contract_color_scheme;
|
||||
}
|
||||
|
||||
std::string hexColorDWORDToRGBA(DWORD color) {
|
||||
DWORD rgba = color << 8 | color >> 24;
|
||||
std::ostringstream stream;
|
||||
@@ -95,8 +64,8 @@ std::string SystemPreferences::GetAccentColor() {
|
||||
return hexColorDWORDToRGBA(color);
|
||||
}
|
||||
|
||||
std::string SystemPreferences::GetColor(gin_helper::ErrorThrower thrower,
|
||||
const std::string& color) {
|
||||
std::string SystemPreferences::GetColor(const std::string& color,
|
||||
mate::Arguments* args) {
|
||||
int id;
|
||||
if (color == "3d-dark-shadow") {
|
||||
id = COLOR_3DDKSHADOW;
|
||||
@@ -159,31 +128,13 @@ std::string SystemPreferences::GetColor(gin_helper::ErrorThrower thrower,
|
||||
} else if (color == "window-text") {
|
||||
id = COLOR_WINDOWTEXT;
|
||||
} else {
|
||||
thrower.ThrowError("Unknown color: " + color);
|
||||
args->ThrowError("Unknown color: " + color);
|
||||
return "";
|
||||
}
|
||||
|
||||
return ToRGBHex(color_utils::GetSysSkColor(id));
|
||||
}
|
||||
|
||||
std::string SystemPreferences::GetMediaAccessStatus(
|
||||
const std::string& media_type,
|
||||
gin_helper::Arguments* args) {
|
||||
if (media_type == "camera") {
|
||||
return ConvertDeviceAccessStatus(
|
||||
GetDeviceAccessStatus(DeviceClass::DeviceClass_VideoCapture));
|
||||
} else if (media_type == "microphone") {
|
||||
return ConvertDeviceAccessStatus(
|
||||
GetDeviceAccessStatus(DeviceClass::DeviceClass_AudioCapture));
|
||||
} else if (media_type == "screen") {
|
||||
return ConvertDeviceAccessStatus(
|
||||
DeviceAccessStatus::DeviceAccessStatus_Allowed);
|
||||
} else {
|
||||
args->ThrowError("Invalid media type");
|
||||
return std::string();
|
||||
}
|
||||
}
|
||||
|
||||
void SystemPreferences::InitializeWindow() {
|
||||
invertered_color_scheme_ = IsInvertedColorScheme();
|
||||
high_contrast_color_scheme_ = IsHighContrastColorScheme();
|
||||
@@ -210,7 +161,7 @@ void SystemPreferences::InitializeWindow() {
|
||||
// receive broadcast messages like "WM_DWMCOLORIZATIONCOLORCHANGED".
|
||||
window_ = CreateWindow(MAKEINTATOM(atom_), 0, WS_POPUP, 0, 0, 0, 0, 0, 0,
|
||||
instance_, 0);
|
||||
gfx::CheckWindowCreated(window_, ::GetLastError());
|
||||
gfx::CheckWindowCreated(window_);
|
||||
gfx::SetWindowUserData(window_, this);
|
||||
}
|
||||
|
||||
@@ -237,6 +188,9 @@ LRESULT CALLBACK SystemPreferences::WndProc(HWND hwnd,
|
||||
Emit("accent-color-changed", hexColorDWORDToRGBA(new_color));
|
||||
current_color_ = new_color_string;
|
||||
}
|
||||
} else if (message == WM_SYSCOLORCHANGE ||
|
||||
(message == WM_SETTINGCHANGE && wparam == SPI_SETHIGHCONTRAST)) {
|
||||
UpdateHighContrastColorScheme();
|
||||
}
|
||||
return ::DefWindowProc(hwnd, message, wparam, lparam);
|
||||
}
|
||||
@@ -264,4 +218,4 @@ void SystemPreferences::OnFinishLaunching(
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace electron
|
||||
} // namespace atom
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user