Compare commits

..

7 Commits

Author SHA1 Message Date
Electron Bot
b7f20f1878 Bump v4.0.0-beta.2 2018-10-11 16:27:07 -07:00
trop[bot]
e9e0219ae8 fix: update and enable osr (backport: 4-0-x) (#15084)
* fix: update and enable osr

* fix: update MacHelper view to call GetNativeView

* style: move stuff around to make more sense

* chore: move OSR related things in SetOwnerWindow to CommonWebContentsDelegate

* fix: avoid crashing when GetOffscreenRenderWidgetHostView is called

* fix: specify default for current_device_scale_factor_
2018-10-11 10:01:27 -07:00
trop[bot]
24b809f2bc build: add "apply_patches" flag to gclient (#15082) 2018-10-11 10:41:11 -05:00
trop[bot]
cfbb22b380 Revert "FIXME: disable isCurrentlyAudible test to unblock merge" (#15083)
This reverts commit c8a9a3f63c.
2018-10-11 10:39:30 -05:00
Electron Bot
f9ae1aa999 Bump v4.0.0-beta.1 2018-10-10 22:01:00 -07:00
Samuel Attard
f1ec2237e7 Revert "Bump v4.0.0-beta.1"
This reverts commit 35df516e28.
2018-10-11 15:54:52 +11:00
Electron Bot
35df516e28 Bump v4.0.0-beta.1 2018-10-10 20:50:05 -07:00
1888 changed files with 162717 additions and 100285 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +0,0 @@
#!/bin/bash
set -e
mkdir -p ~/.ssh
echo "|1|B3r+7aO0/x90IdefihIjxIoJrrk=|OJddGDfhbuLFc1bUyy84hhIw57M= ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==
|1|rGlEvW55DtzNZp+pzw9gvyOyKi4=|LLWr+7qlkAlw3YGGVfLHHxB/kR0= ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==" >> ~/.ssh/known_hosts

View File

@@ -1,3 +1,4 @@
*
!tools/xvfb-init.sh
!tools/run-electron.sh
!build/install-build-deps.sh

View File

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

View File

@@ -1,34 +1,12 @@
{
"extends": "standard",
"parser": "@typescript-eslint/parser",
"plugins": ["@typescript-eslint"],
"env": {
"browser": true
},
"rules": {
"no-var": "error",
"no-unused-vars": 0,
"no-global-assign": 0,
"@typescript-eslint/no-unused-vars": ["error", {
"vars": "all",
"args": "after-used",
"ignoreRestSiblings": false
}],
"prefer-const": ["error", {
"destructuring": "all"
}],
"node/no-deprecated-api": 0
},
"parserOptions": {
"ecmaVersion": 6,
"sourceType": "module"
},
"overrides": [
{
"files": "*.js",
"rules": {
"@typescript-eslint/no-unused-vars": "off"
}
}
]
}]
}
}

29
.github/CODEOWNERS vendored
View File

@@ -3,20 +3,19 @@
# 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
# Everything that falls through the cracks:
* @electron/reviewers
# ...except the Admin WG maintains this file.
/.github/CODEOWNERS @electron/wg-admin
# filename patterns
*browser_view* @electron/browserview
*notification* @electron/notifications
*pdf* @electron/printing
*printing* @electron/printing
*updater* @electron/updater
# 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
# directories
/.github/ @electron/electrocats
/default_app/ @electron/docs
/docs/ @electron/docs
/docs-translations/ @electron/i18n
/npm/ @electron/electrocats

38
.github/ISSUE_TEMPLATE.md vendored Normal file
View File

@@ -0,0 +1,38 @@
<!--
Thanks for opening an issue! A few things to keep in mind:
- The issue tracker is only for bugs and feature requests.
- Before reporting a bug, please try reproducing your issue against
the latest version of Electron.
- If you need general advice, join our Slack: http://atom-slack.herokuapp.com
-->
* Output of `node_modules/.bin/electron --version`:
* Operating System (Platform and Version):
<!-- If this used to work -->
* Output of `node_modules/.bin/electron --version` on last known working Electron version (if applicable):
### Expected behavior
<!-- What do you think should happen? -->
### Actual behavior
<!-- What actually happens? -->
### How to reproduce
<!--
Your best chance of getting this bug looked at quickly is to provide a REPOSITORY that can be cloned and run.
You can fork https://github.com/electron/electron-quick-start and include a link to the branch with your changes.
If you provide a URL, please list the commands required to clone/setup/run your repo e.g.
$ git clone $YOUR_URL -b $BRANCH
$ npm install
$ npm start || electron .
-->

View File

@@ -4,55 +4,29 @@ about: Create a report to help us improve Electron
---
<!-- As an open source project with a dedicated but small maintainer team, it can sometimes take a long time for issues to be addressed so please be patient and we will get back to you as soon as we can.
-->
* Output of `node_modules/.bin/electron --version`:
* Operating System (Platform and Version):
* Output of `node_modules/.bin/electron --version` on last known working Electron version (if applicable):
### Preflight Checklist
<!-- Please ensure you've completed the following steps by replacing [ ] with [x]-->
**Expected Behavior**
A clear and concise description of what you expected to happen.
* [ ] I have read the [Contributing Guidelines](https://github.com/electron/electron/blob/master/CONTRIBUTING.md) for this project.
* [ ] I agree to follow the [Code of Conduct](https://github.com/electron/electron/blob/master/CODE_OF_CONDUCT.md) that this project adheres to.
* [ ] I have searched the issue tracker for an issue that matches the one I want to file, without success.
**Actual behavior**
A clear and concise description of what actually happened.
### Issue Details
**To Reproduce**
Your best chance of getting this bug looked at quickly is to provide a REPOSITORY that can be cloned and run.
* **Electron Version:**
* <!-- (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:**
* <!-- (if applicable) e.g. 3.1.0 -->
You can fork [electron-quick-start](https://github.com/electron/electron-quick-start) and include a link to the branch with your changes.
### Expected Behavior
<!-- A clear and concise description of what you expected to happen. -->
### Actual Behavior
<!-- A clear and concise description of what actually happened. -->
### To Reproduce
<!--
Your best chance of getting this bug looked at quickly is to provide an example.
-->
<!--
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.
-->
<!--
If you provide a URL, please list the commands required to clone/setup/run your repo e.g.
```sh
$ git clone $YOUR_URL -b $BRANCH
$ npm install
$ npm start || electron .
```
-->
**Screenshots**
If applicable, add screenshots to help explain your problem.
### Screenshots
<!-- If applicable, add screenshots to help explain your problem. -->
### Additional Information
<!-- Add any other context about the problem here. -->
**Additional Information**
Add any other context about the problem here.

View File

@@ -4,24 +4,14 @@ about: Suggest an idea for Electron
---
<!-- As an open source project with a dedicated but small maintainer team, it can sometimes take a long time for issues to be addressed so please be patient and we will get back to you as soon as we can.
-->
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is.
### Preflight Checklist
<!-- Please ensure you've completed the following steps by replacing [ ] with [x]-->
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
* [ ] I have read the [Contributing Guidelines](https://github.com/electron/electron/blob/master/CONTRIBUTING.md) for this project.
* [ ] I agree to follow the [Code of Conduct](https://github.com/electron/electron/blob/master/CODE_OF_CONDUCT.md) that this project adheres to.
* [ ] I have searched the issue tracker for a feature request that matches the one I want to file, without success.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
### Problem Description
<!-- Is your feature request related to a problem? Please add a clear and concise description of what the problem is. -->
### Proposed Solution
<!-- Describe the solution you'd like in a clear and concise manner -->
### Alternatives Considered
<!-- A clear and concise description of any alternative solutions or features you've considered. -->
### Additional Information
<!-- Add any other context about the problem here. -->
**Additional context**
Add any other context or screenshots about the feature request here.

View File

@@ -0,0 +1,13 @@
---
name: Mac App Store Private API Rejection
about: Your app was rejected from the Mac App Store for using private API's
---
* Electron Version:
**Rejection Email**
Paste the contents of your rejection email here, censoring any private information such as app names.
**Additional Information**
Add any other context about the problem here.

View File

@@ -1,25 +0,0 @@
---
name: Mac App Store Private API Rejection
about: Your app was rejected from the Mac App Store for using private API's
---
<!-- As an open source project with a dedicated but small maintainer team, it can sometimes take a long time for issues to be addressed so please be patient and we will get back to you as soon as we can.
-->
### Preflight Checklist
<!-- Please ensure you've completed the following steps by replacing [ ] with [x]-->
* [ ] I have read the [Contributing Guidelines](https://github.com/electron/electron/blob/master/CONTRIBUTING.md) for this project.
* [ ] I agree to follow the [Code of Conduct](https://github.com/electron/electron/blob/master/CODE_OF_CONDUCT.md) that this project adheres to.
### Issue Details
* **Electron Version:**
* <!-- (output of `node_modules/.bin/electron --version`) e.g. 4.0.3 -->
### Rejection Email
<!-- Paste the contents of your rejection email here, censoring any private information such as app names.-->
### Additional Information
<!-- Add any other context about the problem here. -->

View File

@@ -4,7 +4,6 @@ about: Do not create an issue for security reports, send an email to security@el
---
### Notice
Do not create an issue for security reports, send an email to:
**DO NOT** create an issue for security reports.
Send an email to: **security@electronjs.org**.
security@electronjs.org

View File

@@ -1,4 +1,4 @@
#### Description of Change
##### Description of Change
<!--
Thank you for your Pull Request. Please provide a description above and review
the requirements below.
@@ -6,7 +6,7 @@ the requirements below.
Contributors guide: https://github.com/electron/electron/blob/master/CONTRIBUTING.md
-->
#### Checklist
##### Checklist
<!-- Remove items that do not apply. For completed items, change [ ] to [x]. -->
- [ ] PR description included and stakeholders cc'd
@@ -14,8 +14,9 @@ Contributors guide: https://github.com/electron/electron/blob/master/CONTRIBUTIN
- [ ] tests are [changed or added](https://github.com/electron/electron/blob/master/docs/development/testing.md)
- [ ] relevant documentation is changed or added
- [ ] PR title follows semantic [commit guidelines](https://github.com/electron/electron/blob/master/docs/development/pull-requests.md#commit-message-guidelines)
- [ ] [PR release notes](https://github.com/electron/clerk/blob/master/README.md) describe the change in a way relevant to app developers, and are [capitalized, punctuated, and past tense](https://github.com/electron/clerk/blob/master/README.md#examples).
#### Release Notes
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 -->
##### Release Notes
<!-- Used to describe release notes for future release versions. See https://github.com/electron/clerk/blob/master/README.md for details. -->
Notes: <!-- One-line Change Summary Here-->

18
.github/config.yml vendored
View File

@@ -1,3 +1,13 @@
# Configuration for new-issue-welcome - https://github.com/behaviorbot/new-issue-welcome
# Comment to be posted to on first time issues
newIssueWelcomeComment: |
👋 Thanks for opening your first issue here! If you're reporting a 🐞 bug, please make sure you include steps to reproduce it. We get a lot of issues on this repo, so please be patient and we will get back to you as soon as we can.
To help make it easier for us to investigate your issue, please follow the [contributing guidelines](https://github.com/electron/electron/blob/master/CONTRIBUTING.md).
# Configuration for new-pr-welcome - https://github.com/behaviorbot/new-pr-welcome
# Comment to be posted to on PRs from first time contributors in your repository
newPRWelcomeComment: |
💖 Thanks for opening this pull request! 💖
@@ -26,16 +36,18 @@ newPRWelcomeComment: |
firstPRMergeComment: >
Congrats on merging your first pull request! 🎉🎉🎉
# Users authorized to run manual trop backports
# Configuration for trop - https://github.com/codebytere/trop
watchedProject:
name: Backports
authorizedUsers:
- alexeykuzmin
- BinaryMuse
- ckerr
- codebytere
- deepak1556
- jkleinsc
- MarshallOfSound
- miniak
- nitsakh
- nornagon
- zcbenz

10
.github/main.workflow vendored
View File

@@ -1,10 +0,0 @@
workflow "Clerk" {
#TODO(codebytere): make this work properly on pull_request
on = "repository_dispatch"
resolves = "Check release notes"
}
action "Check release notes" {
uses = "electron/clerk@master"
secrets = [ "GITHUB_TOKEN" ]
}

18
.gitignore vendored
View File

@@ -16,6 +16,13 @@
*.vcxproj.user
*.xcodeproj
/.idea/
/brightray/brightray.opensdf
/brightray/brightray.sdf
/brightray/brightray.sln
/brightray/brightray.suo
/brightray/brightray.v12.suo
/brightray/brightray.vcxproj*
/brightray/brightray.xcodeproj/
/dist/
/external_binaries/
/out/
@@ -37,7 +44,7 @@
/vendor/pyyaml
node_modules/
SHASUMS256.txt
**/package-lock.json
**/yarn.lock
compile_commands.json
.envrc
@@ -56,12 +63,3 @@ spec/.hash
# Eslint Cache
.eslintcache
# Generated native addon files
/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

31
.vsts/lint.yml Normal file
View File

@@ -0,0 +1,31 @@
pool:
vmImage: 'Ubuntu 16.04'
steps:
- bash: |
# "depot_tools" has to be checkout into "//third_party/depot_tools" so pylint.py can a "pylintrc" file.
git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git "${AGENT_BUILDDIRECTORY}/third_party/depot_tools"
echo "##vso[task.setvariable variable=PATH]$PATH:${AGENT_BUILDDIRECTORY}/third_party/depot_tools"
displayName: Setup Depot Tools
- bash: |
chromium_revision="$(grep -A1 chromium_version DEPS | tr -d '\n' | cut -d\' -f4)"
buildtools_revision="$(curl -sL "https://chromium.googlesource.com/chromium/src/+/${chromium_revision}/DEPS?format=TEXT" | base64 -d | grep buildtools_revision -A1 | tr -d '\n' | cut -d\' -f4)"
git clone https://chromium.googlesource.com/chromium/buildtools "${AGENT_TEMPDIRECTORY}/buildtools"
(cd "${AGENT_TEMPDIRECTORY}/buildtools" && git checkout "$buildtools_revision")
echo "##vso[task.setvariable variable=CHROMIUM_BUILDTOOLS_PATH]$AGENT_TEMPDIRECTORY/buildtools"
download_from_google_storage --bucket chromium-gn -s "${AGENT_TEMPDIRECTORY}/buildtools/linux64/gn.sha1"
displayName: Download gn binary
- bash: |
# gn.py tries to find a gclient root folder starting from the current dir.
# When it fails and returns "None" path, the whole script fails. Let's "fix" it.
touch .gclient
# Another option would be to checkout "buildtools" inside the Electron checkout,
# but then we would lint its contents (at least gn format), and it doesn't pass it.
npm install
npm run lint
displayName: Run Lint

944
BUILD.gn

File diff suppressed because it is too large Load Diff

View File

@@ -28,18 +28,6 @@ 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!
### 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.
## [Pull Requests](https://electronjs.org/docs/development/pull-requests)
Pull Requests are the way concrete changes are made to the code, documentation,
@@ -69,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)

75
DEPS
View File

@@ -5,17 +5,14 @@ gclient_gn_args = [
'checkout_android_native_support',
'checkout_libaom',
'checkout_nacl',
'checkout_oculus_sdk',
'checkout_openxr'
'checkout_oculus_sdk'
]
vars = {
'chromium_version':
'78.0.3904.130',
'69.0.3497.106',
'node_version':
'v12.8.1',
'nan_version':
'2ee313aaca52e2b478965ac50eb5082520380d1b',
'5654c276d0497ff9a0bb0d7550b9073b2e2e7d3f',
'boto_version': 'f7574aa6cc2c819430c1f05e9a1a1a666ef8169b',
'pyyaml_version': '3.12',
@@ -24,33 +21,18 @@ vars = {
'boto_git': 'https://github.com/boto',
'chromium_git': 'https://chromium.googlesource.com',
'electron_git': 'https://github.com/electron',
'nodejs_git': 'https://github.com/nodejs',
'requests_git': 'https://github.com/kennethreitz',
'yaml_git': 'https://github.com/yaml',
# KEEP IN SYNC WITH utils.js FILE
'yarn_version': '1.15.2',
# To be able to build clean Chromium from sources.
'apply_patches': True,
# 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,
# It's only needed to parse the native tests configurations.
'checkout_pyyaml': False,
# Python "requests" module is used for releases only.
'checkout_requests': False,
# 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,
@@ -61,8 +43,6 @@ vars = {
True,
'checkout_oculus_sdk':
False,
'checkout_openxr':
False,
'build_with_chromium':
True,
'checkout_android':
@@ -72,41 +52,32 @@ vars = {
}
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',
},
'src/third_party/electron_node': {
'url': (Var("nodejs_git")) + '/node.git@' + (Var("node_version")),
'condition': 'checkout_node and process_deps',
},
'src/electron/vendor/pyyaml': {
'url': (Var("yaml_git")) + '/pyyaml.git@' + (Var("pyyaml_version")),
'condition': 'checkout_pyyaml and process_deps',
},
'src':
(Var("chromium_git")) + '/chromium/src.git@' + (Var("chromium_version")),
'src/third_party/electron_node':
(Var("electron_git")) + '/node.git@' + (Var("node_version")),
'src/electron/vendor/pyyaml':
(Var("yaml_git")) + '/pyyaml.git@' + (Var("pyyaml_version")),
'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': 'apply_patches',
'pattern': 'src/electron',
'action': [
'python',
'src/electron/script/apply_all_patches.py',
'src/electron/patches/config.json',
'src/electron/script/apply-patches',
'--project-root=.',
'--commit',
],
},
{
@@ -114,8 +85,10 @@ hooks = [
'pattern': 'src/electron/script/update-external-binaries.py',
'condition': 'download_external_binaries',
'action': [
'python3',
'python',
'src/electron/script/update-external-binaries.py',
'--root-url=http://github.com/electron/electron-frameworks/releases/download',
'--version=v1.4.0',
],
},
{
@@ -124,29 +97,29 @@ hooks = [
'action': [
'python',
'-c',
'import os, subprocess; os.chdir(os.path.join("src", "electron")); subprocess.check_call(["python", "script/lib/npx.py", "yarn@' + (Var("yarn_version")) + '", "install", "--frozen-lockfile"]);',
'import os; os.chdir("src"); os.chdir("electron"); os.system("npm install")',
],
},
{
'name': 'setup_boto',
'pattern': 'src/electron',
'condition': 'checkout_boto and process_deps',
'condition': 'checkout_boto',
'action': [
'python',
'-c',
'import os, subprocess; os.chdir(os.path.join("src", "electron", "vendor", "boto")); subprocess.check_call(["python", "setup.py", "build"]);',
'import os; os.chdir("src"); os.chdir("electron"); os.chdir("vendor"); os.chdir("boto"); os.system("python setup.py build");',
],
},
{
'name': 'setup_requests',
'pattern': 'src/electron',
'condition': 'checkout_requests and process_deps',
'condition': 'checkout_requests',
'action': [
'python',
'-c',
'import os, subprocess; os.chdir(os.path.join("src", "electron", "vendor", "requests")); subprocess.check_call(["python", "setup.py", "build"]);',
'import os; os.chdir("src"); os.chdir("electron"); os.chdir("vendor"); os.chdir("requests"); os.system("python setup.py build");',
],
},
}
]
recursedeps = [

View File

@@ -10,21 +10,18 @@ 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 dpkg --add-architecture i386
RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y \
curl \
libnotify-bin \
locales \
lsb-release \
nano \
python-dbus \
python-dbusmock \
python-pip \
python-setuptools \
sudo \
vim-nox \
wget \
g++-multilib \
libgl1:i386 \
&& /setup/install-build-deps.sh --syms --no-prompt --no-chromeos-fonts --lib32 --arm \
&& rm -rf /var/lib/apt/lists/*
@@ -36,9 +33,6 @@ RUN curl -sL https://deb.nodesource.com/setup_10.x | bash - \
# 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

View File

@@ -19,6 +19,8 @@ RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y \
libcap-dev \
libcups2-dev \
libdbus-1-dev \
libgconf-2-4 \
libgconf2-dev \
libgnome-keyring-dev \
libgtk2.0-0 \
libgtk2.0-dev \

View File

@@ -1,4 +1,4 @@
FROM arm64v8/ubuntu:18.04
FROM arm64v8/ubuntu:16.04
RUN groupadd --gid 1000 builduser \
&& useradd --uid 1000 --gid builduser --shell /bin/bash --create-home builduser
@@ -22,6 +22,8 @@ RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y \
libcap-dev \
libcups2-dev \
libdbus-1-dev \
libgconf-2-4 \
libgconf2-dev \
libgnome-keyring-dev \
libgtk2.0-0 \
libgtk2.0-dev \
@@ -39,6 +41,7 @@ RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y \
nano \
python-setuptools \
python-pip \
python-dbusmock \
sudo \
unzip \
wget \
@@ -53,9 +56,6 @@ RUN curl -sL https://deb.nodesource.com/setup_10.x | bash - \
# 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
ADD tools/xvfb-init.sh /etc/init.d/xvfb
RUN chmod a+x /etc/init.d/xvfb

View File

@@ -1 +0,0 @@
7.1.10

View File

@@ -1,4 +1,4 @@
Copyright (c) 2013-2019 GitHub Inc.
Copyright (c) 2013-2018 GitHub Inc.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the

View File

@@ -2,10 +2,11 @@
[![CircleCI Build Status](https://circleci.com/gh/electron/electron/tree/master.svg?style=shield)](https://circleci.com/gh/electron/electron/tree/master)
[![AppVeyor Build Status](https://ci.appveyor.com/api/projects/status/4lggi9dpjc1qob7k/branch/master?svg=true)](https://ci.appveyor.com/project/electron-bot/electron-ljo26/branch/master)
[![AppVeyor Build Status](https://windows-ci.electronjs.org/api/projects/status/nilyf07hcef14dvj/branch/master?svg=true)](https://windows-ci.electronjs.org/project/AppVeyor/electron/branch/master)
[![devDependency Status](https://david-dm.org/electron/electron/dev-status.svg)](https://david-dm.org/electron/electron?type=dev)
[![Join the Electron Community on Slack](https://atom-slack.herokuapp.com/badge.svg)](https://atom-slack.herokuapp.com/)
:memo: Available Translations: 🇨🇳 🇹🇼 🇧🇷 🇪🇸 🇰🇷 🇯🇵 🇷🇺 🇫🇷 🇹🇭 🇳🇱 🇹🇷 🇮🇩 🇺🇦 🇨🇿 🇮🇹 🇵🇱.
:memo: Available Translations: 🇨🇳 🇹🇼 🇧🇷 🇪🇸 🇰🇷 🇯🇵 🇷🇺 🇫🇷 🇹🇭 🇳🇱 🇹🇷 🇮🇩 🇺🇦 🇨🇿 🇮🇹.
View these docs in other languages at [electron/i18n](https://github.com/electron/i18n/tree/master/content/).
The Electron framework lets you write cross-platform desktop applications
@@ -91,10 +92,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,

1
VERSION Normal file
View File

@@ -0,0 +1 @@
4.0.0-beta.2

View File

@@ -1,51 +1,10 @@
# The config expects the following environment variables to be set:
# - "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
# Don't forget to set up "NPM_CONFIG_ARCH" and "TARGET_ARCH" accordningly
# if you pass a custom value for 'target_cpu'.
# - "ELECTRON_RELEASE" Set it to '1' upload binaries on success.
# - "NPM_CONFIG_ARCH" E.g. 'x86'. Is used to build native Node.js modules.
# Must match 'target_cpu' passed to "GN_EXTRA_ARGS" and "TARGET_ARCH" value.
# - "TARGET_ARCH" Choose from {'ia32', 'x64', 'arm', 'arm64', 'mips64el'}.
# Is used in some publishing scripts, but does NOT affect the Electron binary.
# Must match 'target_cpu' passed to "GN_EXTRA_ARGS" and "NPM_CONFIG_ARCH" value.
# - "UPLOAD_TO_S3" Set it to '1' upload a release to the S3 bucket.
# Otherwise the release will be uploaded to the Github Releases.
# (The value is only checked if "ELECTRON_RELEASE" is defined.)
#
# The publishing scripts expect access tokens to be defined as env vars,
# but those are not covered here.
#
# AppVeyor docs on variables:
# https://www.appveyor.com/docs/environment-variables/
# 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: libcc-20
image: vs2017-15.9-10.0.18362
image: libcc-20-vs2017-15.7.4
environment:
GIT_CACHE_PATH: C:\Users\electron\libcc_cache
DISABLE_CRASH_REPORTER_TESTS: true
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]) {
@@ -54,15 +13,13 @@ build_script:
- echo "Building $env:GN_CONFIG build"
- git config --global core.longpaths true
- cd ..
- mkdir src
- md src
- 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] "
$env:GCLIENT_EXTRA_ARGS="--custom-var=checkout_boto=True --custom-var=checkout_requests=True"
}
- >-
gclient config
@@ -70,16 +27,10 @@ build_script:
--unmanaged
%GCLIENT_EXTRA_ARGS%
"https://github.com/electron/electron"
- gclient sync --with_branch_heads --with_tags --reset
- gclient sync --with_branch_heads --with_tags
- cd src
- 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
- gn gen out/Default "--args=import(\"//electron/build/args/%GN_CONFIG%.gn\") %GN_EXTRA_ARGS%"
- ninja -C out/Default electron:electron_app
- if "%GN_CONFIG%"=="testing" ( python C:\Users\electron\depot_tools\post_build_ninja_summary.py -C out\Default )
- 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
@@ -89,29 +40,22 @@ build_script:
- appveyor PushArtifact out/Default/dist.zip
- 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/electron.lib
- ps: >-
if ($env:GN_CONFIG -eq 'release') {
# Needed for msdia140.dll on 64-bit windows
$env:Path += ";$pwd\third_party\llvm-build\Release+Asserts\bin"
ninja -C out/Default electron:electron_symbols
ninja -C out/Default third_party/breakpad:dump_syms
}
- if "%GN_CONFIG%"=="release" ( python electron\script\dump-symbols.py -d %cd%\out\Default\electron.breakpad.syms -v)
- ps: >-
if ($env:GN_CONFIG -eq 'release') {
python electron\script\zip-symbols.py
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:
# Workaround for https://github.com/appveyor/ci/issues/2420
- set "PATH=%PATH%;C:\Program Files\Git\mingw64\libexec\git-core"
- ps: >-
if ((-Not (Test-Path Env:\TEST_WOA)) -And (-Not (Test-Path Env:\ELECTRON_RELEASE)) -And ($env:GN_CONFIG -in "testing", "release")) {
if ((-Not (Test-Path Env:\ELECTRON_RELEASE)) -And ($env:GN_CONFIG -in "testing", "release")) {
$env:RUN_TESTS="true"
}
- 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 )
- ps: >-
if ($env:RUN_TESTS -eq 'true') {
New-Item .\out\Default\gen\node_headers\Release -Type directory
@@ -120,23 +64,17 @@ test_script:
echo "Skipping tests for $env:GN_CONFIG build"
}
- cd electron
- if "%RUN_TESTS%"=="true" ( echo Running test suite & node script/yarn test -- --ci --enable-logging)
- if "%RUN_TESTS%"=="true" ( echo Running test suite & npm run test -- --ci )
- 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"
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
}

View File

@@ -2,25 +2,25 @@
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "shell/app/atom_content_client.h"
#include "atom/app/atom_content_client.h"
#include <string>
#include <utility>
#include <vector>
#include "atom/common/atom_version.h"
#include "atom/common/chrome_version.h"
#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/pepper_plugin_info.h"
#include "content/public/common/user_agent.h"
#include "electron/buildflags/buildflags.h"
#include "ppapi/buildflags/buildflags.h"
#include "shell/browser/atom_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)
@@ -32,16 +32,11 @@
#endif // defined(WIDEVINE_CDM_AVAILABLE)
#if BUILDFLAG(ENABLE_PDF_VIEWER)
#include "atom/common/atom_constants.h"
#include "pdf/pdf.h"
#include "shell/common/atom_constants.h"
#endif // BUILDFLAG(ENABLE_PDF_VIEWER)
#if BUILDFLAG(ENABLE_PLUGINS)
#include "content/public/common/pepper_plugin_info.h"
#include "ppapi/shared_impl/ppapi_permissions.h"
#endif // BUILDFLAG(ENABLE_PLUGINS)
namespace electron {
namespace atom {
namespace {
@@ -147,7 +142,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;
@@ -168,21 +162,15 @@ void ComputeBuiltInPlugins(std::vector<content::PepperPluginInfo>* plugins) {
plugins->push_back(pdf_info);
#endif // BUILDFLAG(ENABLE_PDF_VIEWER)
}
#endif // BUILDFLAG(ENABLE_PLUGINS)
void AppendDelimitedSwitchToVector(const base::StringPiece cmd_switch,
std::vector<std::string>* append_me) {
void ConvertStringWithSeparatorToVector(std::vector<std::string>* vec,
const char* separator,
const char* cmd_switch) {
auto* command_line = base::CommandLine::ForCurrentProcess();
auto switch_value = command_line->GetSwitchValueASCII(cmd_switch);
if (!switch_value.empty()) {
constexpr base::StringPiece delimiter(",", 1);
auto tokens =
base::SplitString(switch_value, delimiter, base::TRIM_WHITESPACE,
base::SPLIT_WANT_NONEMPTY);
append_me->reserve(append_me->size() + tokens.size());
std::move(std::begin(tokens), std::end(tokens),
std::back_inserter(*append_me));
}
auto string_with_separator = command_line->GetSwitchValueASCII(cmd_switch);
if (!string_with_separator.empty())
*vec = base::SplitString(string_with_separator, separator,
base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
}
} // namespace
@@ -191,42 +179,33 @@ AtomContentClient::AtomContentClient() {}
AtomContentClient::~AtomContentClient() {}
base::string16 AtomContentClient::GetLocalizedString(int message_id) {
std::string AtomContentClient::GetProduct() const {
return "Chrome/" CHROME_VERSION_STRING;
}
std::string AtomContentClient::GetUserAgent() const {
return content::BuildUserAgentFromProduct("Chrome/" CHROME_VERSION_STRING
" " ATOM_PRODUCT_NAME
"/" ATOM_VERSION_STRING);
}
base::string16 AtomContentClient::GetLocalizedString(int message_id) const {
return l10n_util::GetStringUTF16(message_id);
}
base::StringPiece AtomContentClient::GetDataResource(
int resource_id,
ui::ScaleFactor scale_factor) {
return ui::ResourceBundle::GetSharedInstance().GetRawDataResourceForScale(
resource_id, scale_factor);
}
gfx::Image& AtomContentClient::GetNativeImageNamed(int resource_id) {
return ui::ResourceBundle::GetSharedInstance().GetNativeImageNamed(
resource_id);
}
base::RefCountedMemory* AtomContentClient::GetDataResourceBytes(
int resource_id) {
return ui::ResourceBundle::GetSharedInstance().LoadDataResourceBytes(
resource_id);
}
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.push_back(url::kFileScheme);
schemes->standard_schemes.push_back("chrome-extension");
std::vector<std::string> splited;
ConvertStringWithSeparatorToVector(&splited, ",",
switches::kRegisterServiceWorkerSchemes);
for (const std::string& scheme : splited)
schemes->service_worker_schemes.push_back(scheme);
schemes->service_worker_schemes.push_back(url::kFileScheme);
ConvertStringWithSeparatorToVector(&splited, ",", switches::kSecureSchemes);
for (const std::string& scheme : splited)
schemes->secure_schemes.push_back(scheme);
}
void AtomContentClient::AddPepperPlugins(
@@ -235,9 +214,7 @@ void AtomContentClient::AddPepperPlugins(
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 AtomContentClient::AddContentDecryptionModules(
@@ -273,4 +250,4 @@ void AtomContentClient::AddContentDecryptionModules(
}
}
} // namespace electron
} // namespace atom

View File

@@ -2,29 +2,27 @@
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef SHELL_APP_ATOM_CONTENT_CLIENT_H_
#define SHELL_APP_ATOM_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"
#include "brightray/common/content_client.h"
namespace electron {
namespace atom {
class AtomContentClient : public content::ContentClient {
class AtomContentClient : public brightray::ContentClient {
public:
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;
std::string GetProduct() const override;
std::string GetUserAgent() const override;
base::string16 GetLocalizedString(int message_id) const override;
void AddAdditionalSchemes(Schemes* schemes) override;
void AddPepperPlugins(
std::vector<content::PepperPluginInfo>* plugins) override;
@@ -36,6 +34,6 @@ class AtomContentClient : public content::ContentClient {
DISALLOW_COPY_AND_ASSIGN(AtomContentClient);
};
} // namespace electron
} // namespace atom
#endif // SHELL_APP_ATOM_CONTENT_CLIENT_H_
#endif // ATOM_APP_ATOM_CONTENT_CLIENT_H_

View File

@@ -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_ATOM_LIBRARY_MAIN_H_
#define SHELL_APP_ATOM_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"
@@ -20,4 +20,4 @@ __attribute__((visibility("default"))) int AtomInitializeICUandStartNode(
}
#endif // OS_MACOSX
#endif // SHELL_APP_ATOM_LIBRARY_MAIN_H_
#endif // ATOM_APP_ATOM_LIBRARY_MAIN_H_

View File

@@ -2,24 +2,24 @@
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "shell/app/atom_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 "base/at_exit.h"
#include "base/i18n/icu_util.h"
#include "base/mac/bundle_locations.h"
#include "base/mac/scoped_nsautorelease_pool.h"
#include "brightray/common/mac/main_application_bundle.h"
#include "content/public/app/content_main.h"
#include "shell/app/atom_main_delegate.h"
#include "shell/app/node_main.h"
#include "shell/common/atom_command_line.h"
#include "shell/common/mac/main_application_bundle.h"
int AtomMain(int argc, char* argv[]) {
electron::AtomMainDelegate delegate;
atom::AtomMainDelegate delegate;
content::ContentMainParams params(&delegate);
params.argc = argc;
params.argv = const_cast<const char**>(argv);
electron::AtomCommandLine::Init(argc, argv);
atom::AtomCommandLine::Init(argc, argv);
return content::ContentMain(params);
}
@@ -28,11 +28,11 @@ int AtomInitializeICUandStartNode(int argc, char* argv[]) {
base::AtExitManager atexit_manager;
base::mac::ScopedNSAutoreleasePool pool;
base::mac::SetOverrideFrameworkBundlePath(
electron::MainApplicationBundlePath()
brightray::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

View File

@@ -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[]) {

186
atom/app/atom_main.cc Normal file
View File

@@ -0,0 +1,186 @@
// 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/app/atom_main.h"
#include <cstdlib>
#include <vector>
#if defined(OS_WIN)
#include <windows.h> // windows.h must be included first
#include <atlbase.h> // ensures that ATL statics like `_AtlWinModule` are initialized (it's an issue in static debug build)
#include <shellapi.h>
#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 "content/public/app/sandbox_helper_win.h"
#include "sandbox/win/src/sandbox_types.h"
#elif defined(OS_LINUX) // defined(OS_WIN)
#include "atom/app/atom_main_delegate.h" // NOLINT
#include "content/public/app/content_main.h"
#else // defined(OS_LINUX)
#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 "base/at_exit.h"
#include "base/i18n/icu_util.h"
#include "electron/buildflags/buildflags.h"
namespace {
#if BUILDFLAG(ENABLE_RUN_AS_NODE)
const char kRunAsNode[] = "ELECTRON_RUN_AS_NODE";
#endif
bool IsEnvSet(const char* name) {
#if defined(OS_WIN)
size_t required_size;
getenv_s(&required_size, nullptr, 0, name);
return required_size != 0;
#else
char* indicator = getenv(name);
return indicator && indicator[0] != '\0';
#endif
}
} // namespace
#if defined(OS_WIN)
int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE, wchar_t* cmd, int) {
struct Arguments {
int argc = 0;
wchar_t** argv = ::CommandLineToArgvW(::GetCommandLineW(), &argc);
~Arguments() { LocalFree(argv); }
} arguments;
if (!arguments.argv)
return -1;
#ifdef _DEBUG
// Don't display assert dialog boxes in CI test runs
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);
_CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_DEBUG | _CRTDBG_MODE_FILE);
_CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);
_set_error_mode(_OUT_TO_STDERR);
}
#endif
#if BUILDFLAG(ENABLE_RUN_AS_NODE)
bool run_as_node = IsEnvSet(kRunAsNode);
#else
bool run_as_node = false;
#endif
// Make sure the output is printed to console.
if (run_as_node || !IsEnvSet("ELECTRON_NO_ATTACH_CONSOLE"))
base::RouteStdioToConsole(false);
#ifndef DEBUG
// Chromium has its own TLS subsystem which supports automatic destruction
// of thread-local data, and also depends on memory allocation routines
// provided by the CRT. The problem is that the auto-destruction mechanism
// uses a hidden feature of the OS loader which calls a callback on thread
// exit, but only after all loaded DLLs have been detached. Since the CRT is
// also a DLL, it happens that by the time Chromium's `OnThreadExit` function
// is called, the heap functions, though still in memory, no longer perform
// their duties, and when Chromium calls `free` on its buffer, it triggers
// an access violation error.
// We work around this problem by invoking Chromium's `OnThreadExit` in time
// from within the CRT's atexit facility, ensuring the heap functions are
// still active. The second invocation from the OS loader will be a no-op.
extern void NTAPI OnThreadExit(PVOID module, DWORD reason, PVOID reserved);
atexit([]() { OnThreadExit(nullptr, DLL_THREAD_DETACH, nullptr); });
#endif
#if BUILDFLAG(ENABLE_RUN_AS_NODE)
if (run_as_node) {
std::vector<char*> argv(arguments.argc);
std::transform(
arguments.argv, arguments.argv + arguments.argc, argv.begin(),
[](auto& a) { return _strdup(base::WideToUTF8(a).c_str()); });
base::AtExitManager atexit_manager;
base::i18n::InitializeICU();
auto ret = atom::NodeMain(argv.size(), argv.data());
std::for_each(argv.begin(), argv.end(), free);
return ret;
}
#endif
if (IsEnvSet("ELECTRON_INTERNAL_CRASH_SERVICE")) {
return crash_service::Main(cmd);
}
if (!atom::CheckCommandLineArguments(arguments.argc, arguments.argv))
return -1;
sandbox::SandboxInterfaceInfo sandbox_info = {0};
content::InitializeSandboxInfo(&sandbox_info);
atom::AtomMainDelegate delegate;
content::ContentMainParams params(&delegate);
params.instance = instance;
params.sandbox_info = &sandbox_info;
atom::AtomCommandLine::Init(arguments.argc, arguments.argv);
return content::ContentMain(params);
}
#elif defined(OS_LINUX) // defined(OS_WIN)
int main(int argc, char* argv[]) {
#if BUILDFLAG(ENABLE_RUN_AS_NODE)
if (IsEnvSet(kRunAsNode)) {
base::i18n::InitializeICU();
base::AtExitManager atexit_manager;
return atom::NodeMain(argc, argv);
}
#endif
atom::AtomMainDelegate delegate;
content::ContentMainParams params(&delegate);
params.argc = argc;
params.argv = const_cast<const char**>(argv);
atom::AtomCommandLine::Init(argc, argv);
return content::ContentMain(params);
}
#else // defined(OS_LINUX)
int main(int argc, char* argv[]) {
#if BUILDFLAG(ENABLE_RUN_AS_NODE)
if (IsEnvSet(kRunAsNode)) {
return AtomInitializeICUandStartNode(argc, argv);
}
#endif
return AtomMain(argc, argv);
}
#endif // defined(OS_MACOSX)

View File

@@ -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_ATOM_MAIN_H_
#define SHELL_APP_ATOM_MAIN_H_
#ifndef ATOM_APP_ATOM_MAIN_H_
#define ATOM_APP_ATOM_MAIN_H_
#include "content/public/app/content_main.h"
#endif // SHELL_APP_ATOM_MAIN_H_
#endif // ATOM_APP_ATOM_MAIN_H_

View File

@@ -0,0 +1,220 @@
// 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/app/atom_main_delegate.h"
#include <iostream>
#include <memory>
#include <string>
#include "atom/app/atom_content_client.h"
#include "atom/browser/atom_browser_client.h"
#include "atom/browser/relauncher.h"
#include "atom/common/google_api_key.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/logging.h"
#include "chrome/common/chrome_paths.h"
#include "content/public/common/content_switches.h"
#include "ipc/ipc_buildflags.h"
#include "services/service_manager/sandbox/switches.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.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 "atom/app/atom_main_delegate_mac.h"
#endif
namespace atom {
namespace {
const char* kRelauncherProcess = "relauncher";
bool IsBrowserProcess(base::CommandLine* cmd) {
std::string process_type = cmd->GetSwitchValueASCII(::switches::kProcessType);
return process_type.empty();
}
#if defined(OS_WIN)
void InvalidParameterHandler(const wchar_t*,
const wchar_t*,
const wchar_t*,
unsigned int,
uintptr_t) {
// noop.
}
#endif
} // namespace
AtomMainDelegate::AtomMainDelegate() {}
AtomMainDelegate::~AtomMainDelegate() {}
bool AtomMainDelegate::BasicStartupComplete(int* exit_code) {
auto* command_line = base::CommandLine::ForCurrentProcess();
logging::LoggingSettings settings;
#if defined(OS_WIN)
// On Windows the terminal returns immediately, so we add a new line to
// prevent output in the same line as the prompt.
if (IsBrowserProcess(command_line))
std::wcout << std::endl;
#if defined(DEBUG)
// Print logging to debug.log on Windows
settings.logging_dest = logging::LOG_TO_ALL;
settings.log_file = L"debug.log";
settings.lock_log = logging::LOCK_LOG_FILE;
settings.delete_old = logging::DELETE_OLD_LOG_FILE;
#else
settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG;
#endif // defined(DEBUG)
#else // defined(OS_WIN)
settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG;
#endif // !defined(OS_WIN)
// Only enable logging when --enable-logging is specified.
auto env = base::Environment::Create();
if (!command_line->HasSwitch(::switches::kEnableLogging) &&
!env->HasVar("ELECTRON_ENABLE_LOGGING")) {
settings.logging_dest = logging::LOG_NONE;
logging::SetMinLogLevel(logging::LOG_NUM_SEVERITIES);
}
logging::InitLogging(settings);
// Logging with pid and timestamp.
logging::SetLogItems(true, false, true, false);
// Enable convient stack printing.
#if defined(DEBUG) && defined(OS_LINUX)
bool enable_stack_dumping = true;
#else
bool enable_stack_dumping = env->HasVar("ELECTRON_ENABLE_STACK_DUMPING");
#endif
#if defined(ARCH_CPU_ARM_FAMILY) && defined(ARCH_CPU_32_BITS)
// For 32bit ARM enabling stack printing would end up crashing.
// https://github.com/electron/electron/pull/11230#issuecomment-363232482
enable_stack_dumping = false;
#endif
if (enable_stack_dumping)
base::debug::EnableInProcessStackDumping();
chrome::RegisterPathProvider();
#if defined(OS_MACOSX)
SetUpBundleOverrides();
#endif
#if defined(OS_WIN)
// Ignore invalid parameter errors.
_set_invalid_parameter_handler(InvalidParameterHandler);
// Disable the ActiveVerifier, which is used by Chrome to track possible
// bugs, but no use in Electron.
base::win::DisableHandleVerifier();
#endif
return brightray::MainDelegate::BasicStartupComplete(exit_code);
}
void AtomMainDelegate::PreSandboxStartup() {
brightray::MainDelegate::PreSandboxStartup();
auto* command_line = base::CommandLine::ForCurrentProcess();
// Only append arguments for browser process.
if (!IsBrowserProcess(command_line))
return;
if (!command_line->HasSwitch(switches::kEnableMixedSandbox)) {
if (command_line->HasSwitch(switches::kEnableSandbox)) {
// Disable setuid sandbox since it is not longer required on
// linux(namespace sandbox is available on most distros).
command_line->AppendSwitch(
service_manager::switches::kDisableSetuidSandbox);
} else {
// Disable renderer sandbox for most of node's functions.
command_line->AppendSwitch(service_manager::switches::kNoSandbox);
}
}
// 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");
#endif
}
void AtomMainDelegate::PreContentInitialization() {
#if defined(OS_MACOSX)
RegisterAtomCrApp();
#endif
}
content::ContentBrowserClient* AtomMainDelegate::CreateContentBrowserClient() {
browser_client_.reset(new AtomBrowserClient);
return browser_client_.get();
}
content::ContentRendererClient*
AtomMainDelegate::CreateContentRendererClient() {
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kEnableSandbox) ||
!base::CommandLine::ForCurrentProcess()->HasSwitch(
service_manager::switches::kNoSandbox)) {
renderer_client_.reset(new AtomSandboxedRendererClient);
} else {
renderer_client_.reset(new AtomRendererClient);
}
return renderer_client_.get();
}
content::ContentUtilityClient* AtomMainDelegate::CreateContentUtilityClient() {
utility_client_.reset(new AtomContentUtilityClient);
return utility_client_.get();
}
int AtomMainDelegate::RunProcess(
const std::string& process_type,
const content::MainFunctionParams& main_function_params) {
if (process_type == kRelauncherProcess)
return relauncher::RelauncherMain(main_function_params);
else
return -1;
}
#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
std::unique_ptr<brightray::ContentClient>
AtomMainDelegate::CreateContentClient() {
return std::make_unique<AtomContentClient>();
}
} // namespace atom

View File

@@ -2,24 +2,18 @@
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef SHELL_APP_ATOM_MAIN_DELEGATE_H_
#define SHELL_APP_ATOM_MAIN_DELEGATE_H_
#ifndef ATOM_APP_ATOM_MAIN_DELEGATE_H_
#define ATOM_APP_ATOM_MAIN_DELEGATE_H_
#include <memory>
#include <string>
#include "content/public/app/content_main_delegate.h"
#include "content/public/common/content_client.h"
#include "brightray/common/content_client.h"
#include "brightray/common/main_delegate.h"
namespace tracing {
class TracingSamplerProfiler;
}
namespace atom {
namespace electron {
void LoadResourceBundle(const std::string& locale);
class AtomMainDelegate : public content::ContentMainDelegate {
class AtomMainDelegate : public brightray::MainDelegate {
public:
AtomMainDelegate();
~AtomMainDelegate() override;
@@ -28,38 +22,37 @@ class AtomMainDelegate : public content::ContentMainDelegate {
// content::ContentMainDelegate:
bool BasicStartupComplete(int* exit_code) override;
void PreSandboxStartup() override;
void PreCreateMainMessageLoop() override;
void PostEarlyInitialization(bool is_running_tests) override;
void PreContentInitialization() 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;
#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;
// brightray::MainDelegate:
std::unique_ptr<brightray::ContentClient> CreateContentClient() override;
#if defined(OS_MACOSX)
void OverrideChildProcessPath() override;
void OverrideFrameworkBundlePath() override;
#endif
private:
#if defined(OS_MACOSX)
void OverrideChildProcessPath();
void OverrideFrameworkBundlePath();
void SetUpBundleOverrides();
#endif
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(AtomMainDelegate);
};
} // namespace electron
} // namespace atom
#endif // SHELL_APP_ATOM_MAIN_DELEGATE_H_
#endif // ATOM_APP_ATOM_MAIN_DELEGATE_H_

View File

@@ -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_ATOM_MAIN_DELEGATE_MAC_H_
#define SHELL_APP_ATOM_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_ATOM_MAIN_DELEGATE_MAC_H_
#endif // ATOM_APP_ATOM_MAIN_DELEGATE_MAC_H_

View File

@@ -2,10 +2,9 @@
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "shell/app/atom_main_delegate.h"
#include <string>
#include "atom/app/atom_main_delegate.h"
#include "atom/browser/mac/atom_application.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/mac/bundle_locations.h"
@@ -13,57 +12,42 @@
#include "base/mac/scoped_nsautorelease_pool.h"
#include "base/path_service.h"
#include "base/strings/sys_string_conversions.h"
#include "content/common/mac_helpers.h"
#include "brightray/common/application_info.h"
#include "brightray/common/mac/main_application_bundle.h"
#include "content/public/common/content_paths.h"
#include "shell/browser/mac/atom_application.h"
#include "shell/common/application_info.h"
#include "shell/common/mac/main_application_bundle.h"
namespace electron {
namespace atom {
namespace {
base::FilePath GetFrameworksPath() {
return MainApplicationBundlePath().Append("Contents").Append("Frameworks");
return brightray::MainApplicationBundlePath()
.Append("Contents")
.Append("Frameworks");
}
base::FilePath GetHelperAppPath(const base::FilePath& frameworks_path,
const std::string& name) {
// Figure out what helper we are running
base::FilePath path;
base::PathService::Get(base::FILE_EXE, &path);
std::string helper_name = "Helper";
if (base::EndsWith(path.value(), content::kMacHelperSuffix_renderer,
base::CompareCase::SENSITIVE)) {
helper_name += content::kMacHelperSuffix_renderer;
} else if (base::EndsWith(path.value(), content::kMacHelperSuffix_gpu,
base::CompareCase::SENSITIVE)) {
helper_name += content::kMacHelperSuffix_gpu;
} else if (base::EndsWith(path.value(), content::kMacHelperSuffix_plugin,
base::CompareCase::SENSITIVE)) {
helper_name += content::kMacHelperSuffix_plugin;
}
return frameworks_path.Append(name + " " + helper_name + ".app")
return frameworks_path.Append(name + " Helper.app")
.Append("Contents")
.Append("MacOS")
.Append(name + " " + helper_name);
.Append(name + " Helper");
}
} // namespace
void AtomMainDelegate::OverrideFrameworkBundlePath() {
base::mac::SetOverrideFrameworkBundlePath(
GetFrameworksPath().Append(ELECTRON_PRODUCT_NAME " Framework.framework"));
GetFrameworksPath().Append(ATOM_PRODUCT_NAME " Framework.framework"));
}
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());
helper_path =
GetHelperAppPath(frameworks_path, brightray::GetApplicationName());
if (!base::PathExists(helper_path))
LOG(FATAL) << "Unable to find helper app";
base::PathService::Override(content::CHILD_PROCESS_EXE, helper_path);
@@ -71,7 +55,7 @@ void AtomMainDelegate::OverrideChildProcessPath() {
void AtomMainDelegate::SetUpBundleOverrides() {
base::mac::ScopedNSAutoreleasePool pool;
NSBundle* bundle = MainApplicationBundle();
NSBundle* bundle = brightray::MainApplicationBundle();
std::string base_bundle_id =
base::SysNSStringToUTF8([bundle bundleIdentifier]);
NSString* team_id = [bundle objectForInfoDictionaryKey:@"ElectronTeamID"];
@@ -85,4 +69,4 @@ void RegisterAtomCrApp() {
[AtomApplication sharedApplication];
}
} // namespace electron
} // namespace atom

View File

@@ -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

View File

@@ -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_

View File

@@ -2,45 +2,30 @@
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "shell/app/node_main.h"
#include "atom/app/node_main.h"
#include <memory>
#include <string>
#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/atom_bindings.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 "base/command_line.h"
#include "base/feature_list.h"
#include "base/task/thread_pool/thread_pool_instance.h"
#include "base/task_scheduler/task_scheduler.h"
#include "base/threading/thread_task_runner_handle.h"
#include "electron/electron_version.h"
#include "gin/array_buffer.h"
#include "gin/public/isolate_holder.h"
#include "gin/v8_initializer.h"
#include "native_mate/dictionary.h"
#include "shell/app/uv_task_runner.h"
#include "shell/browser/javascript_environment.h"
#include "shell/browser/node_debugger.h"
#include "shell/common/api/electron_bindings.h"
#include "shell/common/crash_reporter/crash_reporter.h"
#include "shell/common/native_mate_converters/string16_converter.h"
#include "shell/common/node_bindings.h"
#include "shell/common/node_includes.h"
#if defined(_WIN64)
#include "shell/common/crash_reporter/crash_reporter_win.h"
#endif
#include "atom/common/node_includes.h"
namespace electron {
#if !defined(OS_LINUX)
void AddExtraParameter(const std::string& key, const std::string& value) {
crash_reporter::CrashReporter::GetInstance()->AddExtraParameter(key, value);
}
void RemoveExtraParameter(const std::string& key) {
crash_reporter::CrashReporter::GetInstance()->RemoveExtraParameter(key);
}
#endif
namespace atom {
int NodeMain(int argc, char* argv[]) {
base::CommandLine::Init(argc, argv);
@@ -58,9 +43,15 @@ int NodeMain(int argc, char* argv[]) {
feature_list->InitializeFromCommandLine("", "");
base::FeatureList::SetInstance(std::move(feature_list));
#if defined(_WIN64)
crash_reporter::CrashReporterWin::SetUnhandledExceptionFilter();
#endif
gin::V8Initializer::LoadV8Snapshot(
gin::V8Initializer::V8SnapshotFileType::kWithAdditionalContext);
gin::V8Initializer::LoadV8Natives();
// V8 requires a task scheduler apparently
base::TaskScheduler::CreateAndStartWithDefaultParams("Electron");
// Initialize gin::IsolateHolder.
JavascriptEnvironment gin_env(loop);
// Explicitly register electron's builtin modules.
NodeBindings::RegisterBuiltinModules();
@@ -69,53 +60,25 @@ int NodeMain(int argc, char* argv[]) {
const char** exec_argv;
node::Init(&argc, const_cast<const char**>(argv), &exec_argc, &exec_argv);
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);
node::IsolateData* isolate_data =
node::CreateIsolateData(gin_env.isolate(), loop, gin_env.platform());
CHECK_NE(nullptr, isolate_data);
node::Environment* env =
node::CreateEnvironment(isolate_data, gin_env.context(), argc, argv,
exec_argc, exec_argv, false);
CHECK_NE(nullptr, env);
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();
node::BootstrapEnvironment(env);
mate::Dictionary process(gin_env.isolate(), env->process_object());
#if defined(OS_WIN)
process.SetMethod("log", &ElectronBindings::Log);
process.SetMethod("log", &AtomBindings::Log);
#endif
process.SetMethod("crash", &ElectronBindings::Crash);
process.SetMethod("crash", &AtomBindings::Crash);
// Setup process.crashReporter.start in child node processes
auto reporter = mate::Dictionary::CreateEmpty(gin_env.isolate());
reporter.SetMethod("start", &crash_reporter::CrashReporter::StartInstance);
#if !defined(OS_LINUX)
reporter.SetMethod("addExtraParameter", &AddExtraParameter);
reporter.SetMethod("removeExtraParameter", &RemoveExtraParameter);
#endif
process.Set("crashReporter", reporter);
mate::Dictionary versions;
if (process.Get("versions", &versions)) {
versions.SetReadOnly(ELECTRON_PROJECT_NAME, ELECTRON_VERSION_STRING);
}
node::LoadEnvironment(env);
bool more;
@@ -133,30 +96,25 @@ int NodeMain(int argc, char* argv[]) {
}
} while (more == true);
node_debugger.Stop();
exit_code = node::EmitExit(env);
env->set_can_call_into_js(false);
node::RunAtExit(env);
gin_env.platform()->DrainTasks(env->isolate());
gin_env.platform()->CancelPendingDelayedTasks(env->isolate());
gin_env.platform()->UnregisterIsolate(env->isolate());
v8::Isolate* isolate = env->isolate();
node::FreeEnvironment(env);
node::FreeIsolateData(isolate_data);
gin_env.platform()->DrainTasks(isolate);
gin_env.platform()->CancelPendingDelayedTasks(isolate);
gin_env.platform()->UnregisterIsolate(isolate);
}
// 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
// gin::IsolateHolder waits for tasks running in TaskScheduler in its
// destructor and thus must be destroyed before TaskScheduler starts skipping
// CONTINUE_ON_SHUTDOWN tasks.
base::ThreadPoolInstance::Get()->Shutdown();
base::TaskScheduler::GetInstance()->Shutdown();
v8::V8::Dispose();
return exit_code;
}
} // namespace electron
} // namespace atom

View File

@@ -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_

View File

@@ -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>

View File

@@ -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) {}
@@ -43,7 +43,7 @@ bool UvTaskRunner::PostNonNestableDelayedTask(const base::Location& from_here,
// static
void UvTaskRunner::OnTimeout(uv_timer_t* timer) {
UvTaskRunner* self = static_cast<UvTaskRunner*>(timer->data);
if (!base::Contains(self->tasks_, timer))
if (!ContainsKey(self->tasks_, timer))
return;
std::move(self->tasks_[timer]).Run();
@@ -57,4 +57,4 @@ void UvTaskRunner::OnClose(uv_handle_t* handle) {
delete reinterpret_cast<uv_timer_t*>(handle);
}
} // namespace electron
} // namespace atom

View File

@@ -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_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>
@@ -12,7 +12,7 @@
#include "base/single_thread_task_runner.h"
#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_

View File

@@ -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_ATOM_API_APP_H_
#define SHELL_BROWSER_API_ATOM_API_APP_H_
#ifndef ATOM_BROWSER_API_ATOM_API_APP_H_
#define ATOM_BROWSER_API_ATOM_API_APP_H_
#include <memory>
#include <string>
@@ -11,6 +11,13 @@
#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/task/cancelable_task_tracker.h"
#include "chrome/browser/icon_manager.h"
#include "chrome/browser/process_singleton.h"
@@ -19,16 +26,8 @@
#include "content/public/browser/render_process_host.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/base/completion_callback.h"
#include "net/ssl/client_cert_identity.h"
#include "shell/browser/api/event_emitter.h"
#include "shell/browser/api/process_metric.h"
#include "shell/browser/atom_browser_client.h"
#include "shell/browser/browser.h"
#include "shell/browser/browser_observer.h"
#include "shell/common/native_mate_converters/callback.h"
#include "shell/common/promise_util.h"
#if defined(USE_NSS_CERTS)
#include "chrome/browser/certificate_manager_model.h"
@@ -42,12 +41,23 @@ namespace mate {
class Arguments;
} // namespace mate
namespace electron {
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 AtomBrowserClient::Delegate,
@@ -57,7 +67,7 @@ class App : public AtomBrowserClient::Delegate,
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 mate::Handle<App> Create(v8::Isolate* isolate);
@@ -67,7 +77,7 @@ class App : public AtomBrowserClient::Delegate,
#if defined(USE_NSS_CERTS)
void OnCertificateManagerModelCreated(
std::unique_ptr<base::DictionaryValue> options,
net::CompletionOnceCallback callback,
const net::CompletionCallback& callback,
std::unique_ptr<CertificateManagerModel> model);
#endif
@@ -90,6 +100,8 @@ class App : public AtomBrowserClient::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;
#if defined(OS_MACOSX)
@@ -116,11 +128,12 @@ class App : public AtomBrowserClient::Delegate,
int cert_error,
const net::SSLInfo& ssl_info,
const GURL& request_url,
bool is_main_frame_request,
content::ResourceType resource_type,
bool strict_enforcement,
const base::RepeatingCallback<
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,
@@ -128,7 +141,7 @@ class App : public AtomBrowserClient::Delegate,
bool CanCreateWindow(content::RenderFrameHost* opener,
const GURL& opener_url,
const GURL& opener_top_level_frame_url,
const url::Origin& source_origin,
const GURL& source_origin,
content::mojom::WindowContainerType container_type,
const GURL& target_url,
const content::Referrer& referrer,
@@ -142,7 +155,6 @@ class App : public AtomBrowserClient::Delegate,
bool* no_javascript_access) override;
// content::GpuDataManagerObserver:
void OnGpuInfoUpdate() override;
void OnGpuProcessCrashed(base::TerminationStatus status) override;
// content::BrowserChildProcessObserver:
@@ -162,9 +174,6 @@ class App : public AtomBrowserClient::Delegate,
void ChildProcessLaunched(int process_type, base::ProcessHandle handle);
void ChildProcessDisconnected(base::ProcessId pid);
void SetAppLogsPath(base::Optional<base::FilePath> custom_path,
mate::Arguments* args);
// Get/Set the pre-defined path in PathService.
base::FilePath GetPath(mate::Arguments* args, const std::string& name);
void SetPath(mate::Arguments* args,
@@ -173,7 +182,6 @@ class App : public AtomBrowserClient::Delegate,
void SetDesktopName(const std::string& desktop_name);
std::string GetLocale();
std::string GetLocaleCountryCode();
void OnSecondInstance(const base::CommandLine::StringVector& cmd,
const base::FilePath& cwd);
bool HasSingleInstanceLock() const;
@@ -183,34 +191,27 @@ class App : public AtomBrowserClient::Delegate,
void DisableHardwareAcceleration(mate::Arguments* args);
void DisableDomainBlockingFor3DAPIs(mate::Arguments* args);
bool IsAccessibilitySupportEnabled();
void SetAccessibilitySupportEnabled(bool enabled, mate::Arguments* args);
void SetAccessibilitySupportEnabled(bool enabled);
Browser::LoginItemSettings GetLoginItemSettings(mate::Arguments* args);
#if defined(USE_NSS_CERTS)
void ImportCertificate(const base::DictionaryValue& options,
net::CompletionRepeatingCallback callback);
const net::CompletionCallback& callback);
#endif
v8::Local<v8::Promise> GetFileIcon(const base::FilePath& path,
mate::Arguments* args);
void GetFileIcon(const base::FilePath& path, mate::Arguments* args);
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(mate::Arguments* args);
void SetUserAgentFallback(const std::string& user_agent);
std::string GetUserAgentFallback();
void SetBrowserClientCanUseCustomSiteInstance(bool should_disable);
bool CanBrowserClientUseCustomSiteInstance();
void EnableMixedSandbox(mate::Arguments* args);
#if defined(OS_MACOSX)
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(
base::Callback<void()> StartAccessingSecurityScopedResource(
mate::Arguments* args);
#endif
@@ -234,8 +235,7 @@ class App : public AtomBrowserClient::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_;
DISALLOW_COPY_AND_ASSIGN(App);
@@ -243,6 +243,6 @@ class App : public AtomBrowserClient::Delegate,
} // namespace api
} // namespace electron
} // namespace atom
#endif // SHELL_BROWSER_API_ATOM_API_APP_H_
#endif // ATOM_BROWSER_API_ATOM_API_APP_H_

View File

@@ -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/atom_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(
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

View File

@@ -2,17 +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/atom_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 "native_mate/dictionary.h"
#include "native_mate/object_template_builder.h"
#include "shell/browser/browser.h"
#include "shell/browser/native_window.h"
#include "shell/browser/window_list.h"
#include "shell/common/api/event_emitter_caller.h"
#include "shell/common/native_mate_converters/callback.h"
#include "shell/common/node_includes.h"
namespace mate {
@@ -31,7 +31,7 @@ struct Converter<base::Time> {
} // namespace mate
namespace electron {
namespace atom {
namespace api {
@@ -64,17 +64,11 @@ void AutoUpdater::OnError(const std::string& message,
auto errorObject =
error->ToObject(isolate()->GetCurrentContext()).ToLocalChecked();
auto context = isolate()->GetCurrentContext();
// add two new params for better error handling
errorObject
->Set(context, mate::StringToV8(isolate(), "code"),
v8::Integer::New(isolate(), code))
.Check();
errorObject
->Set(context, mate::StringToV8(isolate(), "domain"),
mate::StringToV8(isolate(), domain))
.Check();
errorObject->Set(mate::StringToV8(isolate(), "code"),
v8::Integer::New(isolate(), code));
errorObject->Set(mate::StringToV8(isolate(), "domain"),
mate::StringToV8(isolate(), domain));
mate::EmitEvent(isolate(), GetWrapper(), "error", errorObject, message);
}
@@ -97,8 +91,7 @@ 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() {
@@ -141,11 +134,11 @@ 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,
@@ -154,11 +147,9 @@ void Initialize(v8::Local<v8::Object> exports,
v8::Isolate* isolate = context->GetIsolate();
mate::Dictionary dict(isolate, exports);
dict.Set("autoUpdater", AutoUpdater::Create(isolate));
dict.Set("AutoUpdater", AutoUpdater::GetConstructor(isolate)
->GetFunction(context)
.ToLocalChecked());
dict.Set("AutoUpdater", AutoUpdater::GetConstructor(isolate)->GetFunction());
}
} // namespace
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_auto_updater, Initialize)
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_auto_updater, Initialize)

View File

@@ -2,18 +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_ATOM_API_AUTO_UPDATER_H_
#define SHELL_BROWSER_API_ATOM_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 "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"
#include "shell/browser/api/event_emitter.h"
#include "shell/browser/auto_updater.h"
#include "shell/browser/window_list_observer.h"
namespace electron {
namespace atom {
namespace api {
@@ -56,6 +56,6 @@ class AutoUpdater : public mate::EventEmitter<AutoUpdater>,
} // namespace api
} // namespace electron
} // namespace atom
#endif // SHELL_BROWSER_API_ATOM_API_AUTO_UPDATER_H_
#endif // ATOM_BROWSER_API_ATOM_API_AUTO_UPDATER_H_

View File

@@ -2,27 +2,27 @@
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "shell/browser/api/atom_api_browser_view.h"
#include "atom/browser/api/atom_api_browser_view.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 "shell/browser/api/atom_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/native_mate_converters/gfx_converter.h"
#include "shell/common/native_mate_converters/value_converter.h"
#include "shell/common/node_includes.h"
#include "shell/common/options_switches.h"
#include "ui/gfx/geometry/rect.h"
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) {
atom::AutoResizeFlags* auto_resize_flags) {
mate::Dictionary params;
if (!ConvertFromV8(isolate, val, &params)) {
return false;
@@ -31,29 +31,21 @@ 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;
}
bool horizontal = false;
if (params.Get("horizontal", &horizontal) && horizontal) {
flags |= electron::kAutoResizeHorizontal;
}
bool vertical = false;
if (params.Get("vertical", &vertical) && vertical) {
flags |= electron::kAutoResizeVertical;
flags |= atom::kAutoResizeHeight;
}
*auto_resize_flags = static_cast<electron::AutoResizeFlags>(flags);
*auto_resize_flags = static_cast<atom::AutoResizeFlags>(flags);
return true;
}
};
} // namespace mate
namespace electron {
namespace atom {
namespace api {
@@ -68,13 +60,12 @@ void BrowserView::Init(v8::Isolate* isolate,
const mate::Dictionary& options) {
mate::Dictionary web_preferences = mate::Dictionary::CreateEmpty(isolate);
options.Get(options::kWebPreferences, &web_preferences);
web_preferences.Set("type", "browserView");
web_preferences.Set("isBrowserView", true);
mate::Handle<class WebContents> web_contents =
WebContents::Create(isolate, web_preferences);
web_contents_.Reset(isolate, web_contents.ToV8());
api_web_contents_ = web_contents.get();
Observe(web_contents->web_contents());
view_.reset(
NativeBrowserView::Create(api_web_contents_->managed_web_contents()));
@@ -83,16 +74,7 @@ void BrowserView::Init(v8::Isolate* isolate,
}
BrowserView::~BrowserView() {
if (api_web_contents_) { // destroy() is called
// Destroy WebContents asynchronously unless app is shutting down,
// because destroy() might be called inside WebContents's event handler.
api_web_contents_->DestroyWebContents(!Browser::Get()->is_shutting_down());
}
}
void BrowserView::WebContentsDestroyed() {
api_web_contents_ = nullptr;
web_contents_.Reset();
api_web_contents_->DestroyWebContents(true /* async */);
}
// static
@@ -102,8 +84,15 @@ mate::WrappableBase* BrowserView::New(mate::Arguments* args) {
return nullptr;
}
mate::Dictionary options = mate::Dictionary::CreateEmpty(args->isolate());
args->GetNext(&options);
if (args->Length() > 1) {
args->ThrowError("Too many arguments");
return nullptr;
}
mate::Dictionary options;
if (!(args->Length() == 1 && args->GetNext(&options))) {
options = mate::Dictionary::CreateEmpty(args->isolate());
}
return new BrowserView(args->isolate(), args->GetThis(), options);
}
@@ -120,10 +109,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));
}
@@ -144,7 +129,6 @@ void BrowserView::BuildPrototype(v8::Isolate* isolate,
.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);
@@ -152,22 +136,21 @@ 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));
mate::Dictionary browser_view(isolate, BrowserView::GetConstructor(isolate)
->GetFunction(context)
.ToLocalChecked());
mate::Dictionary browser_view(
isolate, BrowserView::GetConstructor(isolate)->GetFunction());
browser_view.SetMethod("fromId",
&mate::TrackableObject<BrowserView>::FromWeakMapID);
browser_view.SetMethod("getAllViews",
@@ -178,4 +161,4 @@ void Initialize(v8::Local<v8::Object> exports,
} // namespace
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_browser_view, Initialize)
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_browser_view, Initialize)

View File

@@ -2,16 +2,15 @@
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef SHELL_BROWSER_API_ATOM_API_BROWSER_VIEW_H_
#define SHELL_BROWSER_API_ATOM_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 "content/public/browser/web_contents_observer.h"
#include "atom/browser/api/trackable_object.h"
#include "atom/browser/native_browser_view.h"
#include "native_mate/handle.h"
#include "shell/browser/api/trackable_object.h"
#include "shell/browser/native_browser_view.h"
namespace gfx {
class Rect;
@@ -22,7 +21,7 @@ class Arguments;
class Dictionary;
} // namespace mate
namespace electron {
namespace atom {
class NativeBrowserView;
@@ -30,8 +29,7 @@ namespace api {
class WebContents;
class BrowserView : public mate::TrackableObject<BrowserView>,
public content::WebContentsObserver {
class BrowserView : public mate::TrackableObject<BrowserView> {
public:
static mate::WrappableBase* New(mate::Arguments* args);
@@ -49,9 +47,6 @@ class BrowserView : public mate::TrackableObject<BrowserView>,
const mate::Dictionary& options);
~BrowserView() override;
// content::WebContentsObserver:
void WebContentsDestroyed() override;
private:
void Init(v8::Isolate* isolate,
v8::Local<v8::Object> wrapper,
@@ -59,7 +54,6 @@ class BrowserView : public mate::TrackableObject<BrowserView>,
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();
@@ -74,6 +68,6 @@ class BrowserView : public mate::TrackableObject<BrowserView>,
} // namespace api
} // namespace electron
} // namespace atom
#endif // SHELL_BROWSER_API_ATOM_API_BROWSER_VIEW_H_
#endif // ATOM_BROWSER_API_ATOM_API_BROWSER_VIEW_H_

View File

@@ -2,31 +2,30 @@
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "shell/browser/api/atom_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/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/browser/renderer_host/render_widget_host_impl.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h"
#include "gin/converter.h"
#include "native_mate/dictionary.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/api/constructor.h"
#include "shell/common/color_util.h"
#include "shell/common/native_mate_converters/callback.h"
#include "shell/common/native_mate_converters/value_converter.h"
#include "shell/common/node_includes.h"
#include "shell/common/options_switches.h"
#include "ui/gl/gpu_switching_manager.h"
namespace electron {
#include "atom/common/node_includes.h"
namespace atom {
namespace api {
@@ -45,21 +44,10 @@ BrowserWindow::BrowserWindow(v8::Isolate* isolate,
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
@@ -78,7 +66,7 @@ BrowserWindow::BrowserWindow(v8::Isolate* isolate,
}
web_contents_.Reset(isolate, web_contents.ToV8());
api_web_contents_ = web_contents->GetWeakPtr();
api_web_contents_ = web_contents.get();
api_web_contents_->AddObserver(this);
Observe(api_web_contents_->web_contents());
@@ -86,6 +74,10 @@ BrowserWindow::BrowserWindow(v8::Isolate* isolate,
mate::Dictionary(isolate, web_contents->GetWrapper())
.Set("browserWindowOptions", options);
// Tell the content module to initialize renderer widget with transparent
// mode.
ui::GpuSwitchingManager::SetTransparent(window()->transparent());
// Associate with BrowserWindow.
web_contents->SetOwnerWindow(window());
@@ -96,7 +88,8 @@ BrowserWindow::BrowserWindow(v8::Isolate* isolate,
InitWith(isolate, wrapper);
#if defined(OS_MACOSX)
OverrideNSWindowContentView(web_contents->managed_web_contents());
if (!window()->has_frame())
OverrideNSWindowContentView(web_contents->managed_web_contents());
#endif
// Init window after everything has been setup.
@@ -104,9 +97,7 @@ BrowserWindow::BrowserWindow(v8::Isolate* isolate,
}
BrowserWindow::~BrowserWindow() {
// FIXME This is a hack rather than a proper fix preventing shutdown crashes.
if (api_web_contents_)
api_web_contents_->RemoveObserver(this);
api_web_contents_->RemoveObserver(this);
// Note that the OnWindowClosed will not be called after the destructor runs,
// since the window object is managed by the TopLevelWindow class.
if (web_contents())
@@ -142,7 +133,7 @@ void BrowserWindow::RenderViewCreated(
render_view_host->GetProcess()->GetID(),
render_view_host->GetRoutingID());
if (impl)
impl->owner_delegate()->SetBackgroundOpaque(false);
impl->SetBackgroundOpaque(false);
}
void BrowserWindow::DidFirstVisuallyNonEmptyPaint() {
@@ -182,15 +173,19 @@ 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.
// https://github.com/electron/electron/issues/16202.
//
// TODO(zcbenz): We should find out the root cause and improve the closing
// procedure of BrowserWindow.
if (!web_contents())
return;
DCHECK(web_contents());
// Close all child windows before closing current window.
v8::Locker locker(isolate());
@@ -217,11 +212,6 @@ void BrowserWindow::OnRendererResponsive() {
Emit("responsive");
}
void BrowserWindow::OnDraggableRegionsUpdated(
const std::vector<mojom::DraggableRegionPtr>& regions) {
UpdateDraggableRegions(regions);
}
void BrowserWindow::RequestPreferredWidth(int* width) {
*width = web_contents()->GetPreferredSize().width();
}
@@ -244,7 +234,7 @@ void BrowserWindow::OnCloseButtonClicked(bool* prevent_default) {
return;
if (web_contents()->NeedToFireBeforeUnload())
web_contents()->DispatchBeforeUnload(false /* auto_cancel */);
web_contents()->DispatchBeforeUnload();
else
web_contents()->Close();
}
@@ -282,7 +272,7 @@ void BrowserWindow::OnWindowFocus() {
void BrowserWindow::OnWindowResize() {
#if defined(OS_MACOSX)
if (!draggable_regions_.empty())
UpdateDraggableRegions(draggable_regions_);
UpdateDraggableRegions(nullptr, draggable_regions_);
#endif
TopLevelWindow::OnWindowResize();
}
@@ -314,50 +304,18 @@ void BrowserWindow::SetBackgroundColor(const std::string& color_name) {
auto* view = web_contents()->GetRenderWidgetHostView();
if (view)
view->SetBackgroundColor(ParseHexColor(color_name));
// Also update the web preferences object otherwise the view will be reset on
// the next load URL call
if (api_web_contents_) {
auto* web_preferences =
WebContentsPreferences::From(api_web_contents_->web_contents());
if (web_preferences) {
web_preferences->preference()->SetStringKey(options::kBackgroundColor,
color_name);
}
}
}
void BrowserWindow::SetBrowserView(v8::Local<v8::Value> value) {
TopLevelWindow::ResetBrowserViews();
TopLevelWindow::AddBrowserView(value);
TopLevelWindow::SetBrowserView(value);
#if defined(OS_MACOSX)
UpdateDraggableRegions(draggable_regions_);
#endif
}
void BrowserWindow::AddBrowserView(v8::Local<v8::Value> value) {
TopLevelWindow::AddBrowserView(value);
#if defined(OS_MACOSX)
UpdateDraggableRegions(draggable_regions_);
#endif
}
void BrowserWindow::RemoveBrowserView(v8::Local<v8::Value> value) {
TopLevelWindow::RemoveBrowserView(value);
#if defined(OS_MACOSX)
UpdateDraggableRegions(draggable_regions_);
#endif
}
void BrowserWindow::ResetBrowserViews() {
TopLevelWindow::ResetBrowserViews();
#if defined(OS_MACOSX)
UpdateDraggableRegions(draggable_regions_);
UpdateDraggableRegions(nullptr, draggable_regions_);
#endif
}
void BrowserWindow::SetVibrancy(v8::Isolate* isolate,
v8::Local<v8::Value> value) {
std::string type = gin::V8ToString(isolate, value);
std::string type = mate::V8ToString(value);
auto* render_view_host = web_contents()->GetRenderViewHost();
if (render_view_host) {
@@ -365,8 +323,7 @@ void BrowserWindow::SetVibrancy(v8::Isolate* isolate,
render_view_host->GetProcess()->GetID(),
render_view_host->GetRoutingID());
if (impl)
impl->owner_delegate()->SetBackgroundOpaque(
type.empty() ? !window_->transparent() : false);
impl->SetBackgroundOpaque(type.empty() ? !window_->transparent() : false);
}
TopLevelWindow::SetVibrancy(isolate, value);
@@ -393,13 +350,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;
}
@@ -408,8 +365,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));
@@ -428,22 +385,10 @@ void BrowserWindow::Cleanup() {
if (host)
host->GetWidget()->RemoveInputEventObserver(this);
// Destroy WebContents asynchronously unless app is shutting down,
// because destroy() might be called inside WebContents's event handler.
api_web_contents_->DestroyWebContents(!Browser::Get()->is_shutting_down());
api_web_contents_->DestroyWebContents(true /* async */);
Observe(nullptr);
}
void BrowserWindow::OnWindowShow() {
web_contents()->WasShown();
TopLevelWindow::OnWindowShow();
}
void BrowserWindow::OnWindowHide() {
web_contents()->WasOccluded();
TopLevelWindow::OnWindowHide();
}
// static
mate::WrappableBase* BrowserWindow::New(mate::Arguments* args) {
if (!Browser::Get()->is_ready()) {
@@ -487,12 +432,12 @@ 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,
@@ -500,11 +445,10 @@ void Initialize(v8::Local<v8::Object> exports,
void* priv) {
v8::Isolate* isolate = context->GetIsolate();
mate::Dictionary dict(isolate, exports);
dict.Set("BrowserWindow",
mate::CreateConstructor<BrowserWindow>(
isolate, base::BindRepeating(&BrowserWindow::New)));
dict.Set("BrowserWindow", mate::CreateConstructor<BrowserWindow>(
isolate, base::Bind(&BrowserWindow::New)));
}
} // namespace
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_window, Initialize)
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_window, Initialize)

View File

@@ -2,18 +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_ATOM_API_BROWSER_WINDOW_H_
#define SHELL_BROWSER_API_ATOM_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/atom_api_top_level_window.h"
#include "shell/browser/api/atom_api_web_contents.h"
namespace electron {
namespace atom {
namespace api {
@@ -51,12 +51,12 @@ class BrowserWindow : public TopLevelWindow,
void DidFirstVisuallyNonEmptyPaint() override;
void BeforeUnloadDialogCancelled() override;
void OnRendererUnresponsive(content::RenderProcessHost*) override;
bool OnMessageReceived(const IPC::Message& message,
content::RenderFrameHost* rfh) override;
// ExtendedWebContentsObserver:
void OnCloseContents() override;
void OnRendererResponsive() override;
void OnDraggableRegionsUpdated(
const std::vector<mojom::DraggableRegionPtr>& regions) override;
// NativeWindowObserver:
void RequestPreferredWidth(int* width) override;
@@ -72,12 +72,7 @@ class BrowserWindow : public TopLevelWindow,
void Blur() override;
void SetBackgroundColor(const std::string& color_name) override;
void SetBrowserView(v8::Local<v8::Value> value) override;
void AddBrowserView(v8::Local<v8::Value> value) override;
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();
@@ -87,18 +82,18 @@ class BrowserWindow : public TopLevelWindow,
private:
#if defined(OS_MACOSX)
void OverrideNSWindowContentView(InspectableWebContents* iwc);
void OverrideNSWindowContentView(brightray::InspectableWebContents* iwc);
#endif
// 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);
@@ -114,11 +109,11 @@ 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_;
base::WeakPtr<api::WebContents> api_web_contents_;
api::WebContents* api_web_contents_;
base::WeakPtrFactory<BrowserWindow> weak_factory_;
@@ -127,6 +122,6 @@ class BrowserWindow : public TopLevelWindow,
} // namespace api
} // namespace electron
} // namespace atom
#endif // SHELL_BROWSER_API_ATOM_API_BROWSER_WINDOW_H_
#endif // ATOM_BROWSER_API_ATOM_API_BROWSER_WINDOW_H_

View File

@@ -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/atom_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/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"
#include "brightray/browser/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()));
@@ -57,32 +55,28 @@ std::vector<gfx::Rect> CalculateNonDraggableRegions(
} // namespace
void BrowserWindow::OverrideNSWindowContentView(InspectableWebContents* iwc) {
void BrowserWindow::OverrideNSWindowContentView(
brightray::InspectableWebContents* iwc) {
// Make NativeWindow use a NSView as content view.
static_cast<NativeWindowMac*>(window())->OverrideNSWindowContentView();
// Add webview to contentView.
NSView* webView = iwc->GetView()->GetNativeView().GetNativeNSView();
NSView* contentView =
[window()->GetNativeWindow().GetNativeNSWindow() contentView];
NSView* webView = iwc->GetView()->GetNativeView();
NSView* contentView = [window()->GetNativeWindow() contentView];
[webView setFrame:[contentView bounds]];
// ensure that buttons view is floated to top of view hierarchy
NSArray* subviews = [contentView subviews];
NSView* last = subviews.lastObject;
[contentView addSubview:webView positioned:NSWindowBelow relativeTo:last];
[contentView addSubview:webView];
[contentView viewDidMoveToWindow];
}
void BrowserWindow::UpdateDraggableRegions(
const std::vector<mojom::DraggableRegionPtr>& regions) {
content::RenderFrameHost* rfh,
const std::vector<DraggableRegion>& regions) {
if (window_->has_frame())
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.
NSView* webView = web_contents()->GetNativeView().GetNativeNSView();
NSView* webView = web_contents()->GetNativeView();
NSInteger webViewWidth = NSWidth([webView bounds]);
NSInteger webViewHeight = NSHeight([webView bounds]);
@@ -101,11 +95,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_ != &regions) {
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));
@@ -114,10 +104,8 @@ void BrowserWindow::UpdateDraggableRegions(
DraggableRegionsToSkRegion(regions), webViewWidth, webViewHeight);
}
auto browser_views = window_->browser_views();
for (NativeBrowserView* view : browser_views) {
view->UpdateDraggableRegions(drag_exclude_rects);
}
if (window_->browser_view())
window_->browser_view()->UpdateDraggableRegions(drag_exclude_rects);
// Create and add a ControlRegionView for each region that needs to be
// excluded from the dragging.
@@ -139,4 +127,4 @@ void BrowserWindow::UpdateDraggableRegions(
} // namespace api
} // namespace electron
} // namespace atom

View File

@@ -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/atom_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

View File

@@ -0,0 +1,79 @@
// 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 "base/bind.h"
#include "base/files/file_util.h"
#include "content/public/browser/tracing_controller.h"
#include "native_mate/dictionary.h"
#include "atom/common/node_includes.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) {
Dictionary options;
if (!ConvertFromV8(isolate, val, &options))
return false;
std::string category_filter, trace_options;
if (!options.Get("categoryFilter", &category_filter) ||
!options.Get("traceOptions", &trace_options))
return false;
*out = base::trace_event::TraceConfig(category_filter, trace_options);
return true;
}
};
} // 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;
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));
}
void StopRecording(const base::FilePath& path,
const CompletionCallback& callback) {
TracingController::GetInstance()->StopTracing(
GetTraceDataEndpoint(path, callback));
}
void Initialize(v8::Local<v8::Object> exports,
v8::Local<v8::Value> unused,
v8::Local<v8::Context> context,
void* priv) {
auto controller = base::Unretained(TracingController::GetInstance());
mate::Dictionary dict(context->GetIsolate(), exports);
dict.SetMethod("getCategories",
base::Bind(&TracingController::GetCategories, controller));
dict.SetMethod("startRecording",
base::Bind(&TracingController::StartTracing, controller));
dict.SetMethod("stopRecording", &StopRecording);
dict.SetMethod(
"getTraceBufferUsage",
base::Bind(&TracingController::GetTraceBufferUsage, controller));
}
} // namespace
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_content_tracing, Initialize)

View File

@@ -0,0 +1,331 @@
// 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/time/time.h"
#include "base/values.h"
#include "content/public/browser/browser_context.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();
}
// Run |callback| on UI thread.
void RunCallbackInUI(const base::Closure& callback) {
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, callback);
}
// Remove cookies from |list| not matching |filter|, and pass it to |callback|.
void FilterCookies(std::unique_ptr<base::DictionaryValue> filter,
const Cookies::GetCallback& callback,
const net::CookieList& list) {
net::CookieList result;
for (const auto& cookie : list) {
if (MatchesCookie(filter.get(), cookie))
result.push_back(cookie);
}
RunCallbackInUI(base::Bind(callback, Cookies::SUCCESS, result));
}
// Receives cookies matching |filter| in IO thread.
void GetCookiesOnIO(scoped_refptr<net::URLRequestContextGetter> getter,
std::unique_ptr<base::DictionaryValue> filter,
const Cookies::GetCallback& callback) {
std::string url;
filter->GetString("url", &url);
auto filtered_callback =
base::Bind(FilterCookies, base::Passed(&filter), callback);
// Empty url will match all url cookies.
if (url.empty())
GetCookieStore(getter)->GetAllCookiesAsync(filtered_callback);
else
GetCookieStore(getter)->GetAllCookiesForURLAsync(GURL(url),
filtered_callback);
}
// Removes cookie with |url| and |name| in IO thread.
void RemoveCookieOnIOThread(scoped_refptr<net::URLRequestContextGetter> getter,
const GURL& url,
const std::string& name,
const base::Closure& callback) {
GetCookieStore(getter)->DeleteCookieAsync(
url, name, base::BindOnce(RunCallbackInUI, callback));
}
// Callback of SetCookie.
void OnSetCookie(const Cookies::SetCallback& callback, bool success) {
RunCallbackInUI(
base::Bind(callback, success ? Cookies::SUCCESS : Cookies::FAILED));
}
// Flushes cookie store in IO thread.
void FlushCookieStoreOnIOThread(
scoped_refptr<net::URLRequestContextGetter> getter,
const base::Closure& callback) {
GetCookieStore(getter)->FlushStore(base::BindOnce(RunCallbackInUI, callback));
}
// Sets cookie with |details| in IO thread.
void SetCookieOnIO(scoped_refptr<net::URLRequestContextGetter> getter,
std::unique_ptr<base::DictionaryValue> details,
const Cookies::SetCallback& callback) {
std::string url, 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);
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);
}
std::unique_ptr<net::CanonicalCookie> canonical_cookie(
net::CanonicalCookie::CreateSanitizedCookie(
GURL(url), name, value, domain, path, creation_time, expiration_time,
last_access_time, secure, http_only,
net::CookieSameSite::DEFAULT_MODE, net::COOKIE_PRIORITY_DEFAULT));
auto completion_callback = base::BindOnce(OnSetCookie, callback);
if (!canonical_cookie || !canonical_cookie->IsCanonical()) {
std::move(completion_callback).Run(false);
return;
}
if (url.empty()) {
std::move(completion_callback).Run(false);
return;
}
if (name.empty()) {
std::move(completion_callback).Run(false);
return;
}
GetCookieStore(getter)->SetCanonicalCookieAsync(
std::move(canonical_cookie), secure, http_only,
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() {}
void Cookies::Get(const base::DictionaryValue& filter,
const GetCallback& callback) {
auto copy = base::DictionaryValue::From(
base::Value::ToUniquePtrValue(filter.Clone()));
auto* getter = browser_context_->GetRequestContext();
content::BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::BindOnce(GetCookiesOnIO, base::RetainedRef(getter), std::move(copy),
callback));
}
void Cookies::Remove(const GURL& url,
const std::string& name,
const base::Closure& callback) {
auto* getter = browser_context_->GetRequestContext();
content::BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::BindOnce(RemoveCookieOnIOThread, base::RetainedRef(getter), url,
name, callback));
}
void Cookies::Set(const base::DictionaryValue& details,
const SetCallback& callback) {
auto copy = base::DictionaryValue::From(
base::Value::ToUniquePtrValue(details.Clone()));
auto* getter = browser_context_->GetRequestContext();
content::BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::BindOnce(SetCookieOnIO, base::RetainedRef(getter), std::move(copy),
callback));
}
void Cookies::FlushStore(const base::Closure& callback) {
auto* getter = browser_context_->GetRequestContext();
content::BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::BindOnce(FlushCookieStoreOnIOThread, base::RetainedRef(getter),
callback));
}
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

View File

@@ -2,32 +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_ATOM_API_COOKIES_H_
#define SHELL_BROWSER_API_ATOM_API_COOKIES_H_
#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 "base/callback_list.h"
#include "gin/handle.h"
#include "native_mate/handle.h"
#include "net/cookies/canonical_cookie.h"
#include "shell/browser/api/trackable_object.h"
#include "shell/browser/net/cookie_details.h"
#include "shell/common/promise_util.h"
namespace base {
class DictionaryValue;
}
namespace mate {
class Dictionary;
}
namespace net {
class URLRequestContextGetter;
}
namespace electron {
namespace atom {
class AtomBrowserContext;
@@ -35,8 +30,16 @@ namespace api {
class Cookies : public mate::TrackableObject<Cookies> {
public:
static gin::Handle<Cookies> Create(v8::Isolate* isolate,
AtomBrowserContext* browser_context);
enum Error {
SUCCESS,
FAILED,
};
using GetCallback = base::Callback<void(Error, const net::CookieList&)>;
using SetCallback = base::Callback<void(Error)>;
static mate::Handle<Cookies> Create(v8::Isolate* isolate,
AtomBrowserContext* browser_context);
// mate::TrackableObject:
static void BuildPrototype(v8::Isolate* isolate,
@@ -46,10 +49,12 @@ class Cookies : public mate::TrackableObject<Cookies> {
Cookies(v8::Isolate* isolate, AtomBrowserContext* browser_context);
~Cookies() override;
v8::Local<v8::Promise> Get(const mate::Dictionary& 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();
void Get(const base::DictionaryValue& filter, const GetCallback& callback);
void Remove(const GURL& url,
const std::string& name,
const base::Closure& callback);
void Set(const base::DictionaryValue& details, const SetCallback& callback);
void FlushStore(const base::Closure& callback);
// CookieChangeNotifier subscription:
void OnCookieChanged(const CookieDetails*);
@@ -64,6 +69,6 @@ class Cookies : public mate::TrackableObject<Cookies> {
} // namespace api
} // namespace electron
} // namespace atom
#endif // SHELL_BROWSER_API_ATOM_API_COOKIES_H_
#endif // ATOM_BROWSER_API_ATOM_API_COOKIES_H_

View File

@@ -2,24 +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/atom_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 "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 "native_mate/dictionary.h"
#include "shell/common/native_mate_converters/callback.h"
#include "shell/common/native_mate_converters/value_converter.h"
#include "shell/common/node_includes.h"
#include "atom/common/node_includes.h"
using content::DevToolsAgentHost;
namespace electron {
namespace atom {
namespace api {
@@ -44,8 +45,7 @@ void Debugger::DispatchProtocolMessage(DevToolsAgentHost* agent_host,
v8::Locker locker(isolate());
v8::HandleScope handle_scope(isolate());
std::unique_ptr<base::Value> parsed_message =
base::JSONReader::ReadDeprecated(message);
std::unique_ptr<base::Value> parsed_message = base::JSONReader::Read(message);
if (!parsed_message || !parsed_message->is_dict())
return;
base::DictionaryValue* dict =
@@ -61,26 +61,23 @@ void Debugger::DispatchProtocolMessage(DevToolsAgentHost* agent_host,
params.Swap(params_value);
Emit("message", method, params);
} else {
auto it = pending_requests_.find(id);
if (it == pending_requests_.end())
auto send_command_callback = pending_requests_[id];
pending_requests_.erase(id);
if (send_command_callback.is_null())
return;
electron::util::Promise promise = std::move(it->second);
pending_requests_.erase(it);
base::DictionaryValue* error = nullptr;
if (dict->GetDictionary("error", &error)) {
std::string message;
error->GetString("message", &message);
promise.RejectWithErrorMessage(message);
} else {
base::DictionaryValue* result_body = nullptr;
base::DictionaryValue result;
if (dict->GetDictionary("result", &result_body)) {
result.Swap(result_body);
}
promise.Resolve(result);
base::DictionaryValue* error_body = nullptr;
base::DictionaryValue error;
bool has_error;
if ((has_error = dict->GetDictionary("error", &error_body))) {
error.Swap(error_body);
}
base::DictionaryValue* result_body = nullptr;
base::DictionaryValue result;
if (dict->GetDictionary("result", &result_body))
result.Swap(result_body);
send_command_callback.Run(has_error ? error.Clone() : base::Value(),
result);
}
}
@@ -128,27 +125,23 @@ void Debugger::Detach() {
AgentHostClosed(agent_host_.get());
}
v8::Local<v8::Promise> Debugger::SendCommand(mate::Arguments* args) {
electron::util::Promise promise(isolate());
v8::Local<v8::Promise> handle = promise.GetHandle();
if (!agent_host_) {
promise.RejectWithErrorMessage("No target available");
return handle;
}
void Debugger::SendCommand(mate::Arguments* args) {
if (!agent_host_)
return;
std::string method;
if (!args->GetNext(&method)) {
promise.RejectWithErrorMessage("Invalid method");
return handle;
args->ThrowError();
return;
}
base::DictionaryValue command_params;
args->GetNext(&command_params);
SendCommandCallback callback;
args->GetNext(&callback);
base::DictionaryValue request;
int request_id = ++previous_request_id_;
pending_requests_.emplace(request_id, std::move(promise));
pending_requests_[request_id] = callback;
request.SetInteger("id", request_id);
request.SetString("method", method);
if (!command_params.empty())
@@ -158,13 +151,16 @@ v8::Local<v8::Promise> Debugger::SendCommand(mate::Arguments* args) {
std::string json_args;
base::JSONWriter::Write(request, &json_args);
agent_host_->DispatchProtocolMessage(this, json_args);
return handle;
}
void Debugger::ClearPendingRequests() {
for (auto& it : pending_requests_)
it.second.RejectWithErrorMessage("target closed while handling command");
if (pending_requests_.empty())
return;
base::Value error(base::Value::Type::DICTIONARY);
base::Value error_msg("target closed while handling command");
error.SetKey("message", std::move(error_msg));
for (const auto& it : pending_requests_)
it.second.Run(error, base::Value());
}
// static
@@ -186,11 +182,11 @@ void Debugger::BuildPrototype(v8::Isolate* isolate,
} // namespace api
} // namespace electron
} // namespace atom
namespace {
using electron::api::Debugger;
using atom::api::Debugger;
void Initialize(v8::Local<v8::Object> exports,
v8::Local<v8::Value> unused,
@@ -198,11 +194,9 @@ void Initialize(v8::Local<v8::Object> exports,
void* priv) {
v8::Isolate* isolate = context->GetIsolate();
mate::Dictionary(isolate, exports)
.Set("Debugger", Debugger::GetConstructor(isolate)
->GetFunction(context)
.ToLocalChecked());
.Set("Debugger", Debugger::GetConstructor(isolate)->GetFunction());
}
} // namespace
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_debugger, Initialize)
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_debugger, Initialize);

View File

@@ -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_ATOM_API_DEBUGGER_H_
#define SHELL_BROWSER_API_ATOM_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 "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 "native_mate/handle.h"
#include "shell/browser/api/trackable_object.h"
#include "shell/common/promise_util.h"
namespace content {
class DevToolsAgentHost;
@@ -25,7 +24,7 @@ namespace mate {
class Arguments;
}
namespace electron {
namespace atom {
namespace api {
@@ -33,6 +32,9 @@ class Debugger : public mate::TrackableObject<Debugger>,
public content::DevToolsAgentHostClient,
public content::WebContentsObserver {
public:
using SendCommandCallback =
base::Callback<void(const base::Value&, const base::Value&)>;
static mate::Handle<Debugger> Create(v8::Isolate* isolate,
content::WebContents* web_contents);
@@ -54,12 +56,12 @@ class Debugger : public mate::TrackableObject<Debugger>,
content::RenderFrameHost* new_rfh) override;
private:
using PendingRequestMap = std::map<int, electron::util::Promise>;
using PendingRequestMap = std::map<int, SendCommandCallback>;
void Attach(mate::Arguments* args);
bool IsAttached();
void Detach();
v8::Local<v8::Promise> SendCommand(mate::Arguments* args);
void SendCommand(mate::Arguments* args);
void ClearPendingRequests();
content::WebContents* web_contents_; // Weak Reference.
@@ -73,6 +75,6 @@ class Debugger : public mate::TrackableObject<Debugger>,
} // namespace api
} // namespace electron
} // namespace atom
#endif // SHELL_BROWSER_API_ATOM_API_DEBUGGER_H_
#endif // ATOM_BROWSER_API_ATOM_API_DEBUGGER_H_

View File

@@ -2,22 +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/atom_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 "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 "native_mate/dictionary.h"
#include "shell/common/api/atom_api_native_image.h"
#include "shell/common/native_mate_converters/gfx_converter.h"
#include "shell/common/node_includes.h"
#include "third_party/webrtc/modules/desktop_capture/desktop_capture_options.h"
#include "third_party/webrtc/modules/desktop_capture/desktop_capturer.h"
@@ -27,34 +25,30 @@
#include "ui/display/win/display_info.h"
#endif // defined(OS_WIN)
#include "atom/common/node_includes.h"
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) {
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(
isolate, gfx::Image(GetWindowIcon(source.media_list_source.id))));
}
return ConvertToV8(isolate, dict);
}
};
} // namespace mate
namespace electron {
namespace atom {
namespace api {
@@ -66,9 +60,7 @@ DesktopCapturer::~DesktopCapturer() {}
void DesktopCapturer::StartHandling(bool capture_window,
bool capture_screen,
const gfx::Size& thumbnail_size,
bool fetch_window_icons) {
fetch_window_icons_ = fetch_window_icons;
const gfx::Size& thumbnail_size) {
#if defined(OS_WIN)
if (content::desktop_capture::CreateDesktopCaptureOptions()
.allow_directx_capturer()) {
@@ -87,6 +79,10 @@ void DesktopCapturer::StartHandling(bool capture_window,
capture_screen_ = capture_screen;
{
// Remove this once
// https://bugs.chromium.org/p/chromium/issues/detail?id=795340 is fixed.
base::ScopedAllowBaseSyncPrimitivesForTesting
scoped_allow_base_sync_primitives;
// Initialize the source list.
// Apply the new thumbnail size and restart capture.
if (capture_window) {
@@ -132,26 +128,24 @@ bool DesktopCapturer::ShouldScheduleNextRefresh(DesktopMediaList* list) {
}
void DesktopCapturer::UpdateSourcesList(DesktopMediaList* list) {
std::vector<DesktopCapturer::Source> window_sources;
if (capture_window_ &&
list->GetMediaListType() == content::DesktopMediaID::TYPE_WINDOW) {
capture_window_ = false;
const auto& media_list_sources = list->GetSources();
std::vector<DesktopCapturer::Source> window_sources;
window_sources.reserve(media_list_sources.size());
for (const auto& media_list_source : media_list_sources) {
window_sources.emplace_back(DesktopCapturer::Source{
media_list_source, std::string(), fetch_window_icons_});
window_sources.emplace_back(
DesktopCapturer::Source{media_list_source, std::string()});
}
std::move(window_sources.begin(), window_sources.end(),
std::back_inserter(captured_sources_));
}
std::vector<DesktopCapturer::Source> screen_sources;
if (capture_screen_ &&
list->GetMediaListType() == content::DesktopMediaID::TYPE_SCREEN) {
capture_screen_ = false;
const auto& media_list_sources = list->GetSources();
std::vector<DesktopCapturer::Source> screen_sources;
screen_sources.reserve(media_list_sources.size());
for (const auto& media_list_source : media_list_sources) {
screen_sources.emplace_back(
DesktopCapturer::Source{media_list_source, std::string()});
@@ -165,12 +159,8 @@ void DesktopCapturer::UpdateSourcesList(DesktopMediaList* list) {
std::vector<std::string> device_names;
// Crucially, this list of device names will be in the same order as
// |media_list_sources|.
if (!webrtc::DxgiDuplicatorController::Instance()->GetDeviceNames(
&device_names)) {
Emit("error", "Failed to get sources.");
return;
}
webrtc::DxgiDuplicatorController::Instance()->GetDeviceNames(
&device_names);
int device_name_index = 0;
for (auto& source : screen_sources) {
const auto& device_name = device_names[device_name_index++];
@@ -180,13 +170,13 @@ void DesktopCapturer::UpdateSourcesList(DesktopMediaList* list) {
const int64_t device_id =
display::win::DisplayInfo::DeviceIdFromDeviceName(
wide_device_name.c_str());
source.display_id = base::NumberToString(device_id);
source.display_id = base::Int64ToString(device_id);
}
}
#elif defined(OS_MACOSX)
// On Mac, the IDs across the APIs match.
for (auto& source : screen_sources) {
source.display_id = base::NumberToString(source.media_list_source.id.id);
source.display_id = base::Int64ToString(source.media_list_source.id.id);
}
#endif // defined(OS_WIN)
// TODO(ajmacd): Add Linux support. The IDs across APIs differ but Chrome
@@ -197,7 +187,7 @@ void DesktopCapturer::UpdateSourcesList(DesktopMediaList* list) {
}
if (!capture_window_ && !capture_screen_)
Emit("finished", captured_sources_, fetch_window_icons_);
Emit("finished", captured_sources_);
}
// static
@@ -216,7 +206,7 @@ void DesktopCapturer::BuildPrototype(
} // namespace api
} // namespace electron
} // namespace atom
namespace {
@@ -226,10 +216,9 @@ void Initialize(v8::Local<v8::Object> exports,
void* priv) {
v8::Isolate* isolate = context->GetIsolate();
mate::Dictionary dict(isolate, exports);
dict.SetMethod("createDesktopCapturer",
&electron::api::DesktopCapturer::Create);
dict.Set("desktopCapturer", atom::api::DesktopCapturer::Create(isolate));
}
} // namespace
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_desktop_capturer, Initialize)
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_desktop_capturer, Initialize);

View File

@@ -2,32 +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_ATOM_API_DESKTOP_CAPTURER_H_
#define SHELL_BROWSER_API_ATOM_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/event_emitter.h"
#include "chrome/browser/media/webrtc/desktop_media_list_observer.h"
#include "chrome/browser/media/webrtc/native_desktop_media_list.h"
#include "native_mate/handle.h"
#include "shell/browser/api/trackable_object.h"
namespace electron {
namespace atom {
namespace api {
class DesktopCapturer : public mate::TrackableObject<DesktopCapturer>,
class DesktopCapturer : public mate::EventEmitter<DesktopCapturer>,
public DesktopMediaListObserver {
public:
struct Source {
DesktopMediaList::Source media_list_source;
// Will be an empty string if not available.
std::string display_id;
// Whether or not this source should provide an icon.
bool fetch_icon = false;
};
static mate::Handle<DesktopCapturer> Create(v8::Isolate* isolate);
@@ -37,8 +34,7 @@ class DesktopCapturer : public mate::TrackableObject<DesktopCapturer>,
void StartHandling(bool capture_window,
bool capture_screen,
const gfx::Size& thumbnail_size,
bool fetch_window_icons);
const gfx::Size& thumbnail_size);
protected:
explicit DesktopCapturer(v8::Isolate* isolate);
@@ -63,7 +59,6 @@ class DesktopCapturer : public mate::TrackableObject<DesktopCapturer>,
std::vector<DesktopCapturer::Source> captured_sources_;
bool capture_window_ = false;
bool capture_screen_ = false;
bool fetch_window_icons_ = false;
#if defined(OS_WIN)
bool using_directx_capturer_ = false;
#endif // defined(OS_WIN)
@@ -73,6 +68,6 @@ class DesktopCapturer : public mate::TrackableObject<DesktopCapturer>,
} // namespace api
} // namespace electron
} // namespace atom
#endif // SHELL_BROWSER_API_ATOM_API_DESKTOP_CAPTURER_H_
#endif // ATOM_BROWSER_API_ATOM_API_DESKTOP_CAPTURER_H_

View File

@@ -0,0 +1,142 @@
// 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_path_converter.h"
#include "atom/common/native_mate_converters/image_converter.h"
#include "atom/common/native_mate_converters/net_converter.h"
#include "native_mate/dictionary.h"
#include "atom/common/node_includes.h"
namespace mate {
template <>
struct Converter<file_dialog::Filter> {
static bool FromV8(v8::Isolate* isolate,
v8::Local<v8::Value> val,
file_dialog::Filter* out) {
mate::Dictionary dict;
if (!ConvertFromV8(isolate, val, &dict))
return false;
if (!dict.Get("name", &(out->first)))
return false;
if (!dict.Get("extensions", &(out->second)))
return false;
return true;
}
};
template <>
struct Converter<file_dialog::DialogSettings> {
static bool FromV8(v8::Isolate* isolate,
v8::Local<v8::Value> val,
file_dialog::DialogSettings* out) {
mate::Dictionary dict;
if (!ConvertFromV8(isolate, val, &dict))
return false;
dict.Get("window", &(out->parent_window));
dict.Get("title", &(out->title));
dict.Get("message", &(out->message));
dict.Get("buttonLabel", &(out->button_label));
dict.Get("nameFieldLabel", &(out->name_field_label));
dict.Get("defaultPath", &(out->default_path));
dict.Get("filters", &(out->filters));
dict.Get("properties", &(out->properties));
dict.Get("showsTagField", &(out->shows_tag_field));
#if defined(MAS_BUILD)
dict.Get("securityScopedBookmarks", &(out->security_scoped_bookmarks));
#endif
return true;
}
};
} // namespace mate
namespace {
void 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::Local<v8::Value> peek = args->PeekNext();
atom::MessageBoxCallback callback;
if (mate::Converter<atom::MessageBoxCallback>::FromV8(args->isolate(), peek,
&callback)) {
atom::ShowMessageBox(window, static_cast<atom::MessageBoxType>(type),
buttons, default_id, cancel_id, options, title,
message, detail, checkbox_label, checkbox_checked,
icon, callback);
} else {
int chosen = atom::ShowMessageBox(
window, static_cast<atom::MessageBoxType>(type), buttons, default_id,
cancel_id, options, title, message, detail, icon);
args->Return(chosen);
}
}
void ShowOpenDialog(const file_dialog::DialogSettings& settings,
mate::Arguments* args) {
v8::Local<v8::Value> peek = args->PeekNext();
file_dialog::OpenDialogCallback callback;
if (mate::Converter<file_dialog::OpenDialogCallback>::FromV8(
args->isolate(), peek, &callback)) {
file_dialog::ShowOpenDialog(settings, callback);
} else {
std::vector<base::FilePath> paths;
if (file_dialog::ShowOpenDialog(settings, &paths))
args->Return(paths);
}
}
void ShowSaveDialog(const file_dialog::DialogSettings& settings,
mate::Arguments* args) {
v8::Local<v8::Value> peek = args->PeekNext();
file_dialog::SaveDialogCallback callback;
if (mate::Converter<file_dialog::SaveDialogCallback>::FromV8(
args->isolate(), peek, &callback)) {
file_dialog::ShowSaveDialog(settings, callback);
} else {
base::FilePath path;
if (file_dialog::ShowSaveDialog(settings, &path))
args->Return(path);
}
}
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("showMessageBox", &ShowMessageBox);
dict.SetMethod("showErrorBox", &atom::ShowErrorBox);
dict.SetMethod("showOpenDialog", &ShowOpenDialog);
dict.SetMethod("showSaveDialog", &ShowSaveDialog);
#if defined(OS_MACOSX) || defined(OS_WIN)
dict.SetMethod("showCertificateTrustDialog",
&certificate_trust::ShowCertificateTrust);
#endif
}
} // namespace
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_dialog, Initialize)

View File

@@ -2,20 +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/atom_api_download_item.h"
#include "atom/browser/api/atom_api_download_item.h"
#include <map>
#include "atom/browser/atom_browser_main_parts.h"
#include "atom/common/native_mate_converters/callback.h"
#include "atom/common/native_mate_converters/file_path_converter.h"
#include "atom/common/native_mate_converters/gurl_converter.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/atom_browser_main_parts.h"
#include "shell/common/native_mate_converters/callback.h"
#include "shell/common/native_mate_converters/file_dialog_converter.h"
#include "shell/common/native_mate_converters/file_path_converter.h"
#include "shell/common/native_mate_converters/gurl_converter.h"
#include "shell/common/node_includes.h"
#include "atom/common/node_includes.h"
namespace mate {
@@ -47,7 +47,7 @@ struct Converter<download::DownloadItem::DownloadState> {
} // namespace mate
namespace electron {
namespace atom {
namespace api {
@@ -102,7 +102,7 @@ bool DownloadItem::IsPaused() const {
}
void DownloadItem::Resume() {
download_item_->Resume(true /* user_gesture */);
download_item_->Resume();
}
bool DownloadItem::CanResume() const {
@@ -165,15 +165,6 @@ base::FilePath DownloadItem::GetSavePath() const {
return save_path_;
}
file_dialog::DialogSettings DownloadItem::GetSaveDialogOptions() const {
return dialog_options_;
}
void DownloadItem::SetSaveDialogOptions(
const file_dialog::DialogSettings& options) {
dialog_options_ = options;
}
std::string DownloadItem::GetLastModifiedTime() const {
return download_item_->GetLastModifiedTime();
}
@@ -209,10 +200,6 @@ void DownloadItem::BuildPrototype(v8::Isolate* isolate,
.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)
.SetMethod("getETag", &DownloadItem::GetETag)
.SetMethod("getStartTime", &DownloadItem::GetStartTime);
@@ -235,7 +222,7 @@ mate::Handle<DownloadItem> DownloadItem::Create(v8::Isolate* isolate,
} // namespace api
} // namespace electron
} // namespace atom
namespace {
@@ -245,11 +232,10 @@ void Initialize(v8::Local<v8::Object> exports,
void* priv) {
v8::Isolate* isolate = context->GetIsolate();
mate::Dictionary(isolate, exports)
.Set("DownloadItem", electron::api::DownloadItem::GetConstructor(isolate)
->GetFunction(context)
.ToLocalChecked());
.Set("DownloadItem",
atom::api::DownloadItem::GetConstructor(isolate)->GetFunction());
}
} // namespace
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_download_item, Initialize)
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_download_item, Initialize);

View File

@@ -2,20 +2,19 @@
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef SHELL_BROWSER_API_ATOM_API_DOWNLOAD_ITEM_H_
#define SHELL_BROWSER_API_ATOM_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 "base/files/file_path.h"
#include "components/download/public/common/download_item.h"
#include "native_mate/handle.h"
#include "shell/browser/api/trackable_object.h"
#include "shell/browser/ui/file_dialog.h"
#include "url/gurl.h"
namespace electron {
namespace atom {
namespace api {
@@ -45,8 +44,6 @@ class DownloadItem : public mate::TrackableObject<DownloadItem>,
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;
@@ -61,7 +58,6 @@ class DownloadItem : public mate::TrackableObject<DownloadItem>,
private:
base::FilePath save_path_;
file_dialog::DialogSettings dialog_options_;
download::DownloadItem* download_item_;
DISALLOW_COPY_AND_ASSIGN(DownloadItem);
@@ -69,6 +65,6 @@ class DownloadItem : public mate::TrackableObject<DownloadItem>,
} // namespace api
} // namespace electron
} // namespace atom
#endif // SHELL_BROWSER_API_ATOM_API_DOWNLOAD_ITEM_H_
#endif // ATOM_BROWSER_API_ATOM_API_DOWNLOAD_ITEM_H_

View File

@@ -2,49 +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/atom_api_global_shortcut.h"
#include "atom/browser/api/atom_api_global_shortcut.h"
#include <string>
#include <vector>
#include "atom/common/native_mate_converters/accelerator_converter.h"
#include "atom/common/native_mate_converters/callback.h"
#include "base/stl_util.h"
#include "base/strings/utf_string_conversions.h"
#include "native_mate/dictionary.h"
#include "shell/browser/api/atom_api_system_preferences.h"
#include "shell/common/native_mate_converters/accelerator_converter.h"
#include "shell/common/native_mate_converters/callback.h"
#include "shell/common/node_includes.h"
#if defined(OS_MACOSX)
#include "base/mac/mac_util.h"
#endif
#include "atom/common/node_includes.h"
using extensions::GlobalShortcutListener;
namespace {
#if defined(OS_MACOSX)
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};
if (std::find(std::begin(mediaKeys), std::end(mediaKeys),
accelerator.key_code()) != std::end(mediaKeys)) {
bool trusted =
electron::api::SystemPreferences::IsTrustedAccessibilityClient(false);
if (!trusted)
return true;
}
}
return false;
}
#endif
} // namespace
namespace electron {
namespace atom {
namespace api {
@@ -60,37 +31,15 @@ void GlobalShortcut::OnKeyPressed(const ui::Accelerator& accelerator) {
if (accelerator_callback_map_.find(accelerator) ==
accelerator_callback_map_.end()) {
// This should never occur, because if it does, GlobalGlobalShortcutListener
// notifies us with wrong accelerator.
// notifes us with wrong accelerator.
NOTREACHED();
return;
}
accelerator_callback_map_[accelerator].Run();
}
bool GlobalShortcut::RegisterAll(
const std::vector<ui::Accelerator>& accelerators,
const base::Closure& callback) {
std::vector<ui::Accelerator> registered;
for (auto& accelerator : accelerators) {
if (!Register(accelerator, callback)) {
// unregister all shortcuts if any failed
UnregisterSome(registered);
return false;
}
registered.push_back(accelerator);
}
return true;
}
bool GlobalShortcut::Register(const ui::Accelerator& accelerator,
const base::Closure& callback) {
#if defined(OS_MACOSX)
if (RegisteringMediaKeyForUntrustedClient(accelerator))
return false;
#endif
if (!GlobalShortcutListener::GetInstance()->RegisterAccelerator(accelerator,
this)) {
return false;
@@ -101,7 +50,7 @@ bool GlobalShortcut::Register(const ui::Accelerator& accelerator,
}
void GlobalShortcut::Unregister(const ui::Accelerator& accelerator) {
if (!base::Contains(accelerator_callback_map_, accelerator))
if (!ContainsKey(accelerator_callback_map_, accelerator))
return;
accelerator_callback_map_.erase(accelerator);
@@ -109,15 +58,8 @@ void GlobalShortcut::Unregister(const ui::Accelerator& accelerator) {
this);
}
void GlobalShortcut::UnregisterSome(
const std::vector<ui::Accelerator>& accelerators) {
for (auto& accelerator : accelerators) {
Unregister(accelerator);
}
}
bool GlobalShortcut::IsRegistered(const ui::Accelerator& accelerator) {
return base::Contains(accelerator_callback_map_, accelerator);
return ContainsKey(accelerator_callback_map_, accelerator);
}
void GlobalShortcut::UnregisterAll() {
@@ -135,7 +77,6 @@ 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)
.SetMethod("unregister", &GlobalShortcut::Unregister)
@@ -144,7 +85,7 @@ void GlobalShortcut::BuildPrototype(v8::Isolate* isolate,
} // namespace api
} // namespace electron
} // namespace atom
namespace {
@@ -154,9 +95,9 @@ void Initialize(v8::Local<v8::Object> exports,
void* priv) {
v8::Isolate* isolate = context->GetIsolate();
mate::Dictionary dict(isolate, exports);
dict.Set("globalShortcut", electron::api::GlobalShortcut::Create(isolate));
dict.Set("globalShortcut", atom::api::GlobalShortcut::Create(isolate));
}
} // namespace
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_global_shortcut, Initialize)
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_global_shortcut, Initialize)

View File

@@ -2,20 +2,19 @@
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef SHELL_BROWSER_API_ATOM_API_GLOBAL_SHORTCUT_H_
#define SHELL_BROWSER_API_ATOM_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 "native_mate/handle.h"
#include "shell/browser/api/trackable_object.h"
#include "ui/base/accelerators/accelerator.h"
namespace electron {
namespace atom {
namespace api {
@@ -34,13 +33,10 @@ class GlobalShortcut : public extensions::GlobalShortcutListener::Observer,
private:
typedef std::map<ui::Accelerator, base::Closure> AcceleratorCallbackMap;
bool RegisterAll(const std::vector<ui::Accelerator>& accelerators,
const base::Closure& callback);
bool Register(const ui::Accelerator& accelerator,
const base::Closure& callback);
bool IsRegistered(const ui::Accelerator& accelerator);
void Unregister(const ui::Accelerator& accelerator);
void UnregisterSome(const std::vector<ui::Accelerator>& accelerators);
void UnregisterAll();
// GlobalShortcutListener::Observer implementation.
@@ -53,6 +49,6 @@ class GlobalShortcut : public extensions::GlobalShortcutListener::Observer,
} // namespace api
} // namespace electron
} // namespace atom
#endif // SHELL_BROWSER_API_ATOM_API_GLOBAL_SHORTCUT_H_
#endif // ATOM_BROWSER_API_ATOM_API_GLOBAL_SHORTCUT_H_

View File

@@ -2,15 +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/atom_api_in_app_purchase.h"
#include "atom/browser/api/atom_api_in_app_purchase.h"
#include <string>
#include <utility>
#include <vector>
#include "atom/common/native_mate_converters/callback.h"
#include "native_mate/dictionary.h"
#include "shell/common/native_mate_converters/callback.h"
#include "shell/common/node_includes.h"
#include "atom/common/node_includes.h"
namespace mate {
@@ -61,7 +62,7 @@ struct Converter<in_app_purchase::Product> {
dict.Set("formattedPrice", val.formattedPrice);
// Downloadable Content Information
dict.Set("isDownloadable", val.isDownloadable);
dict.Set("isDownloadable", val.downloadable);
return dict.GetHandle();
}
@@ -69,7 +70,7 @@ struct Converter<in_app_purchase::Product> {
} // namespace mate
namespace electron {
namespace atom {
namespace api {
@@ -91,7 +92,7 @@ void InAppPurchase::BuildPrototype(v8::Isolate* isolate,
&in_app_purchase::FinishAllTransactions)
.SetMethod("finishTransactionByDate",
&in_app_purchase::FinishTransactionByDate)
.SetMethod("getProducts", &InAppPurchase::GetProducts);
.SetMethod("getProducts", &in_app_purchase::GetProducts);
}
InAppPurchase::InAppPurchase(v8::Isolate* isolate) {
@@ -100,37 +101,13 @@ InAppPurchase::InAppPurchase(v8::Isolate* isolate) {
InAppPurchase::~InAppPurchase() {}
v8::Local<v8::Promise> InAppPurchase::PurchaseProduct(
const std::string& product_id,
mate::Arguments* args) {
v8::Isolate* isolate = args->isolate();
electron::util::Promise promise(isolate);
v8::Local<v8::Promise> handle = promise.GetHandle();
void InAppPurchase::PurchaseProduct(const std::string& product_id,
mate::Arguments* args) {
int quantity = 1;
in_app_purchase::InAppPurchaseCallback callback;
args->GetNext(&quantity);
in_app_purchase::PurchaseProduct(
product_id, quantity,
base::BindOnce(electron::util::Promise::ResolvePromise<bool>,
std::move(promise)));
return handle;
}
v8::Local<v8::Promise> InAppPurchase::GetProducts(
const std::vector<std::string>& productIDs,
mate::Arguments* args) {
v8::Isolate* isolate = args->isolate();
electron::util::Promise promise(isolate);
v8::Local<v8::Promise> handle = promise.GetHandle();
in_app_purchase::GetProducts(
productIDs, base::BindOnce(electron::util::Promise::ResolvePromise<
std::vector<in_app_purchase::Product>>,
std::move(promise)));
return handle;
args->GetNext(&callback);
in_app_purchase::PurchaseProduct(product_id, quantity, callback);
}
void InAppPurchase::OnTransactionsUpdated(
@@ -141,11 +118,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,
@@ -155,12 +132,11 @@ void Initialize(v8::Local<v8::Object> exports,
v8::Isolate* isolate = context->GetIsolate();
mate::Dictionary dict(isolate, exports);
dict.Set("inAppPurchase", InAppPurchase::Create(isolate));
dict.Set("InAppPurchase", InAppPurchase::GetConstructor(isolate)
->GetFunction(context)
.ToLocalChecked());
dict.Set("InAppPurchase",
InAppPurchase::GetConstructor(isolate)->GetFunction());
#endif
}
} // namespace
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_in_app_purchase, Initialize)
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_in_app_purchase, Initialize)

View File

@@ -2,20 +2,19 @@
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef SHELL_BROWSER_API_ATOM_API_IN_APP_PURCHASE_H_
#define SHELL_BROWSER_API_ATOM_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 "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 "native_mate/handle.h"
#include "shell/browser/api/event_emitter.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/promise_util.h"
namespace electron {
namespace atom {
namespace api {
@@ -31,11 +30,7 @@ class InAppPurchase : public mate::EventEmitter<InAppPurchase>,
explicit InAppPurchase(v8::Isolate* isolate);
~InAppPurchase() override;
v8::Local<v8::Promise> PurchaseProduct(const std::string& product_id,
mate::Arguments* args);
v8::Local<v8::Promise> GetProducts(const std::vector<std::string>& productIDs,
mate::Arguments* args);
void PurchaseProduct(const std::string& product_id, mate::Arguments* args);
// TransactionObserver:
void OnTransactionsUpdated(
@@ -47,6 +42,6 @@ class InAppPurchase : public mate::EventEmitter<InAppPurchase>,
} // namespace api
} // namespace electron
} // namespace atom
#endif // SHELL_BROWSER_API_ATOM_API_IN_APP_PURCHASE_H_
#endif // ATOM_BROWSER_API_ATOM_API_IN_APP_PURCHASE_H_

View File

@@ -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/atom_api_menu.h"
#include <utility>
#include "atom/browser/api/atom_api_menu.h"
#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 "native_mate/constructor.h"
#include "native_mate/dictionary.h"
#include "native_mate/object_template_builder.h"
#include "shell/browser/native_window.h"
#include "shell/common/native_mate_converters/accelerator_converter.h"
#include "shell/common/native_mate_converters/image_converter.h"
#include "shell/common/native_mate_converters/once_callback.h"
#include "shell/common/native_mate_converters/string16_converter.h"
#include "shell/common/node_includes.h"
namespace electron {
#include "atom/common/node_includes.h"
namespace atom {
namespace api {
@@ -41,10 +40,7 @@ void Menu::AfterInit(v8::Isolate* isolate) {
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_);
}
@@ -67,12 +63,6 @@ bool Menu::IsCommandIdVisible(int command_id) const {
return is_visible_.Run(GetWrapper(), command_id);
}
bool Menu::ShouldCommandIdWorkWhenHidden(int command_id) const {
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,
@@ -84,12 +74,6 @@ bool Menu::GetAcceleratorForCommandIdWithParams(
return mate::ConvertFromV8(isolate(), val, accelerator);
}
bool Menu::ShouldRegisterAcceleratorForCommandId(int command_id) const {
v8::Locker locker(isolate());
v8::HandleScope handle_scope(isolate());
return should_register_accelerator_.Run(GetWrapper(), command_id);
}
void Menu::ExecuteCommand(int command_id, int flags) {
v8::Locker locker(isolate());
v8::HandleScope handle_scope(isolate());
@@ -98,7 +82,7 @@ void Menu::ExecuteCommand(int command_id, int flags) {
command_id);
}
void Menu::OnMenuWillShow(ui::SimpleMenuModel* source) {
void Menu::MenuWillShow(ui::SimpleMenuModel* source) {
v8::Locker locker(isolate());
v8::HandleScope handle_scope(isolate());
menu_will_show_.Run(GetWrapper());
@@ -143,10 +127,6 @@ void Menu::SetSublabel(int index, const base::string16& sublabel) {
model_->SetSublabel(index, sublabel);
}
void Menu::SetToolTip(int index, const base::string16& toolTip) {
model_->SetToolTip(index, toolTip);
}
void Menu::SetRole(int index, const base::string16& role) {
model_->SetRole(index, role);
}
@@ -175,16 +155,6 @@ base::string16 Menu::GetSublabelAt(int index) const {
return model_->GetSublabelAt(index);
}
base::string16 Menu::GetToolTipAt(int index) const {
return model_->GetToolTipAt(index);
}
base::string16 Menu::GetAcceleratorTextAt(int index) const {
ui::Accelerator accelerator;
model_->GetAcceleratorAtWithParams(index, true, &accelerator);
return accelerator.GetShortcutText();
}
bool Menu::IsItemCheckedAt(int index) const {
return model_->IsItemCheckedAt(index);
}
@@ -197,10 +167,6 @@ bool Menu::IsVisibleAt(int index) const {
return model_->IsVisibleAt(index);
}
bool Menu::WorksWhenHiddenAt(int index) const {
return model_->WorksWhenHiddenAt(index);
}
void Menu::OnMenuWillClose() {
Emit("menu-will-close");
}
@@ -209,16 +175,6 @@ void Menu::OnMenuWillShow() {
Emit("menu-will-show");
}
base::OnceClosure Menu::BindSelfToClosure(base::OnceClosure callback) {
// return ((callback, ref) => { callback() }).bind(null, callback, this)
v8::Global<v8::Value> ref(isolate(), GetWrapper());
return base::BindOnce(
[](base::OnceClosure callback, v8::Global<v8::Value> ref) {
std::move(callback).Run();
},
std::move(callback), std::move(ref));
}
// static
void Menu::BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype) {
@@ -232,7 +188,6 @@ void Menu::BuildPrototype(v8::Isolate* isolate,
.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)
@@ -240,11 +195,8 @@ void Menu::BuildPrototype(v8::Isolate* isolate,
.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);
@@ -252,23 +204,21 @@ void Menu::BuildPrototype(v8::Isolate* isolate,
} // 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::BindRepeating(&Menu::New));
Menu::SetConstructor(isolate, base::Bind(&Menu::New));
mate::Dictionary dict(isolate, exports);
dict.Set(
"Menu",
Menu::GetConstructor(isolate)->GetFunction(context).ToLocalChecked());
dict.Set("Menu", Menu::GetConstructor(isolate)->GetFunction());
#if defined(OS_MACOSX)
dict.SetMethod("setApplicationMenu", &Menu::SetApplicationMenu);
dict.SetMethod("sendActionToFirstResponder",
@@ -278,4 +228,4 @@ void Initialize(v8::Local<v8::Object> exports,
} // namespace
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_menu, Initialize)
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_menu, Initialize)

View File

@@ -2,18 +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_ATOM_API_MENU_H_
#define SHELL_BROWSER_API_ATOM_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 "shell/browser/api/atom_api_top_level_window.h"
#include "shell/browser/api/trackable_object.h"
#include "shell/browser/ui/atom_menu_model.h"
namespace electron {
namespace atom {
namespace api {
@@ -47,20 +47,18 @@ class Menu : public mate::TrackableObject<Menu>,
bool IsCommandIdChecked(int command_id) const override;
bool IsCommandIdEnabled(int command_id) const override;
bool IsCommandIdVisible(int command_id) const override;
bool ShouldCommandIdWorkWhenHidden(int command_id) const override;
bool GetAcceleratorForCommandIdWithParams(
int command_id,
bool use_default_accelerator,
ui::Accelerator* accelerator) const override;
bool ShouldRegisterAcceleratorForCommandId(int command_id) const override;
void ExecuteCommand(int command_id, int event_flags) override;
void OnMenuWillShow(ui::SimpleMenuModel* source) override;
void MenuWillShow(ui::SimpleMenuModel* source) override;
virtual void PopupAt(TopLevelWindow* window,
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<AtomMenuModel> model_;
@@ -70,11 +68,6 @@ class Menu : public mate::TrackableObject<Menu>,
void OnMenuWillClose() override;
void OnMenuWillShow() override;
protected:
// Returns a new callback which keeps references of the JS wrapper until the
// passed |callback| is called.
base::OnceClosure BindSelfToClosure(base::OnceClosure callback);
private:
void InsertItemAt(int index, int command_id, const base::string16& label);
void InsertSeparatorAt(int index);
@@ -91,7 +84,6 @@ class Menu : public mate::TrackableObject<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);
@@ -99,48 +91,42 @@ class Menu : public mate::TrackableObject<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::RepeatingCallback<bool(v8::Local<v8::Value>, int)> is_checked_;
base::RepeatingCallback<bool(v8::Local<v8::Value>, int)> is_enabled_;
base::RepeatingCallback<bool(v8::Local<v8::Value>, int)> is_visible_;
base::RepeatingCallback<bool(v8::Local<v8::Value>, int)> works_when_hidden_;
base::RepeatingCallback<v8::Local<v8::Value>(v8::Local<v8::Value>, int, bool)>
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<v8::Local<v8::Value>(v8::Local<v8::Value>, int, bool)>
get_accelerator_;
base::RepeatingCallback<bool(v8::Local<v8::Value>, int)>
should_register_accelerator_;
base::RepeatingCallback<void(v8::Local<v8::Value>, v8::Local<v8::Value>, int)>
base::Callback<void(v8::Local<v8::Value>, v8::Local<v8::Value>, int)>
execute_command_;
base::RepeatingCallback<void(v8::Local<v8::Value>)> menu_will_show_;
base::Callback<void(v8::Local<v8::Value>)> menu_will_show_;
DISALLOW_COPY_AND_ASSIGN(Menu);
};
} // namespace api
} // namespace electron
} // namespace atom
namespace mate {
template <>
struct Converter<electron::AtomMenuModel*> {
struct Converter<atom::AtomMenuModel*> {
static bool FromV8(v8::Isolate* isolate,
v8::Local<v8::Value> val,
electron::AtomMenuModel** 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;
@@ -149,4 +135,4 @@ struct Converter<electron::AtomMenuModel*> {
} // namespace mate
#endif // SHELL_BROWSER_API_ATOM_API_MENU_H_
#endif // ATOM_BROWSER_API_ATOM_API_MENU_H_

View File

@@ -2,19 +2,19 @@
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef SHELL_BROWSER_API_ATOM_API_MENU_MAC_H_
#define SHELL_BROWSER_API_ATOM_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/atom_api_menu.h"
#include "atom/browser/api/atom_api_menu.h"
#include <map>
#include <string>
#import "shell/browser/ui/cocoa/atom_menu_controller.h"
#import "atom/browser/ui/cocoa/atom_menu_controller.h"
using base::scoped_nsobject;
namespace electron {
namespace atom {
namespace api {
@@ -27,19 +27,19 @@ class MenuMac : public Menu {
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;
private:
friend class Menu;
void OnClosed(int32_t window_id, base::OnceClosure callback);
void OnClosed(int32_t window_id, base::Closure callback);
scoped_nsobject<AtomMenuController> menu_controller_;
@@ -53,6 +53,6 @@ class MenuMac : public Menu {
} // namespace api
} // namespace electron
} // namespace atom
#endif // SHELL_BROWSER_API_ATOM_API_MENU_MAC_H_
#endif // ATOM_BROWSER_API_ATOM_API_MENU_MAC_H_

View File

@@ -2,21 +2,17 @@
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#import "shell/browser/api/atom_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 "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"
#include "atom/common/node_includes.h"
using content::BrowserThread;
@@ -26,7 +22,7 @@ static scoped_nsobject<NSMenu> applicationMenu_;
} // namespace
namespace electron {
namespace atom {
namespace api {
@@ -39,20 +35,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::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI}, std::move(popup));
auto popup = base::Bind(&MenuMac::PopupOnUI, weak_factory_.GetWeakPtr(),
native_window->GetWeakPtr(), window->weak_map_id(), x,
y, positioning_item, callback);
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, popup);
}
void MenuMac::PopupOnUI(const base::WeakPtr<NativeWindow>& native_window,
@@ -60,17 +51,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();
NSWindow* nswindow = native_window->GetNativeWindow();
base::OnceClosure close_callback =
base::BindOnce(&MenuMac::OnClosed, weak_factory_.GetWeakPtr(), window_id,
std::move(callback));
popup_controllers_[window_id] = base::scoped_nsobject<AtomMenuController>(
[[AtomMenuController 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];
@@ -105,9 +95,9 @@ 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;
base::MessageLoop::ScopedNestableTaskAllower allow;
// One of the events that could be pumped is |window.close()|.
// User-initiated event-tracking loops protect against this by
@@ -117,7 +107,7 @@ 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];
}
@@ -136,17 +126,17 @@ void MenuMac::ClosePopupAt(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<AtomMenuController> menu_controller(
[[AtomMenuController 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,4 +167,4 @@ mate::WrappableBase* Menu::New(mate::Arguments* args) {
} // namespace api
} // namespace electron
} // namespace atom

View File

@@ -2,18 +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/atom_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 {
@@ -26,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;
@@ -43,26 +42,17 @@ 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(), NULL, gfx::Rect(location, gfx::Size()),
views::MenuAnchorPosition::kTopLeft, ui::MENU_SOURCE_MOUSE);
views::MENU_ANCHOR_TOPLEFT, ui::MENU_SOURCE_MOUSE);
}
void MenuViews::ClosePopupAt(int32_t window_id) {
@@ -79,9 +69,9 @@ 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
@@ -91,4 +81,4 @@ mate::WrappableBase* Menu::New(mate::Arguments* args) {
} // namespace api
} // namespace electron
} // namespace atom

View File

@@ -2,18 +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_ATOM_API_MENU_VIEWS_H_
#define SHELL_BROWSER_API_ATOM_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/atom_api_menu.h"
#include "ui/display/screen.h"
#include "ui/views/controls/menu/menu_runner.h"
namespace electron {
namespace atom {
namespace api {
@@ -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_ATOM_API_MENU_VIEWS_H_
#endif // ATOM_BROWSER_API_ATOM_API_MENU_VIEWS_H_

View File

@@ -0,0 +1,61 @@
// 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();
}
} // 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());
}
} // namespace
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_net, Initialize)

View File

@@ -2,12 +2,12 @@
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef SHELL_BROWSER_API_ATOM_API_NET_H_
#define SHELL_BROWSER_API_ATOM_API_NET_H_
#ifndef ATOM_BROWSER_API_ATOM_API_NET_H_
#define ATOM_BROWSER_API_ATOM_API_NET_H_
#include "shell/browser/api/event_emitter.h"
#include "atom/browser/api/event_emitter.h"
namespace electron {
namespace atom {
namespace api {
@@ -18,7 +18,7 @@ class Net : public mate::EventEmitter<Net> {
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 mate::EventEmitter<Net> {
} // namespace api
} // namespace electron
} // namespace atom
#endif // SHELL_BROWSER_API_ATOM_API_NET_H_
#endif // ATOM_BROWSER_API_ATOM_API_NET_H_

View File

@@ -0,0 +1,138 @@
// 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/atom_browser_main_parts.h"
#include "atom/common/native_mate_converters/callback.h"
#include "atom/common/native_mate_converters/file_path_converter.h"
#include "base/command_line.h"
#include "components/net_log/chrome_net_log.h"
#include "content/public/browser/storage_partition.h"
#include "native_mate/dictionary.h"
#include "native_mate/handle.h"
#include "net/url_request/url_request_context_getter.h"
#include "atom/common/node_includes.h"
namespace atom {
namespace api {
NetLog::NetLog(v8::Isolate* isolate, AtomBrowserContext* browser_context)
: browser_context_(browser_context) {
Init(isolate);
net_log_writer_ =
atom::AtomBrowserMainParts::Get()->net_log()->net_export_file_writer();
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();
}
void NetLog::StopLogging(mate::Arguments* args) {
net_log::NetExportFileWriter::FilePathCallback callback;
if (!args->GetNext(&callback)) {
args->ThrowError("Invalid callback function");
return;
}
if (IsCurrentlyLogging()) {
stop_callback_queue_.emplace_back(callback);
net_log_writer_->StopNetLog(nullptr);
} else {
callback.Run(base::FilePath());
}
}
void NetLog::OnNewState(const base::DictionaryValue& state) {
net_log_state_ = state.CreateDeepCopy();
if (stop_callback_queue_.empty())
return;
if (GetLoggingState() == "NOT_LOGGING") {
for (auto& callback : stop_callback_queue_) {
if (!callback.is_null())
net_log_writer_->GetFilePathToCompletedLog(callback);
}
stop_callback_queue_.clear();
}
}
// static
mate::Handle<NetLog> NetLog::Create(v8::Isolate* isolate,
AtomBrowserContext* browser_context) {
return mate::CreateHandle(isolate, new NetLog(isolate, browser_context));
}
// static
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

View 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 "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;
void 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<net_log::NetExportFileWriter::FilePathCallback>
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_

View File

@@ -2,28 +2,30 @@
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "shell/browser/api/atom_api_notification.h"
#include "atom/browser/api/atom_api_notification.h"
#include "atom/browser/api/atom_api_menu.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 "base/guid.h"
#include "base/strings/utf_string_conversions.h"
#include "brightray/browser/browser_client.h"
#include "native_mate/constructor.h"
#include "native_mate/dictionary.h"
#include "native_mate/object_template_builder.h"
#include "shell/browser/api/atom_api_menu.h"
#include "shell/browser/atom_browser_client.h"
#include "shell/browser/browser.h"
#include "shell/common/native_mate_converters/gfx_converter.h"
#include "shell/common/native_mate_converters/image_converter.h"
#include "shell/common/native_mate_converters/string16_converter.h"
#include "shell/common/node_includes.h"
#include "url/gurl.h"
// Must be the last in the includes list.
// See https://github.com/electron/electron/issues/10363
#include "atom/common/node_includes.h"
namespace mate {
template <>
struct Converter<electron::NotificationAction> {
struct Converter<brightray::NotificationAction> {
static bool FromV8(v8::Isolate* isolate,
v8::Local<v8::Value> val,
electron::NotificationAction* out) {
brightray::NotificationAction* out) {
mate::Dictionary dict;
if (!ConvertFromV8(isolate, val, &dict))
return false;
@@ -36,7 +38,7 @@ struct Converter<electron::NotificationAction> {
}
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
electron::NotificationAction val) {
brightray::NotificationAction val) {
mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate);
dict.Set("text", val.text);
dict.Set("type", val.type);
@@ -45,7 +47,7 @@ struct Converter<electron::NotificationAction> {
};
} // namespace mate
namespace electron {
namespace atom {
namespace api {
@@ -54,8 +56,7 @@ Notification::Notification(v8::Isolate* isolate,
mate::Arguments* args) {
InitWith(isolate, wrapper);
presenter_ = static_cast<AtomBrowserClient*>(AtomBrowserClient::Get())
->GetNotificationPresenter();
presenter_ = brightray::BrowserClient::Get()->GetNotificationPresenter();
mate::Dictionary opts;
if (args->GetNext(&opts)) {
@@ -118,7 +119,7 @@ base::string16 Notification::GetSound() const {
return sound_;
}
std::vector<electron::NotificationAction> Notification::GetActions() const {
std::vector<brightray::NotificationAction> Notification::GetActions() const {
return actions_;
}
@@ -156,7 +157,7 @@ void Notification::SetSound(const base::string16& new_sound) {
}
void Notification::SetActions(
const std::vector<electron::NotificationAction>& actions) {
const std::vector<brightray::NotificationAction>& actions) {
actions_ = actions;
}
@@ -189,7 +190,6 @@ void Notification::NotificationClosed() {
void Notification::Close() {
if (notification_) {
notification_->Dismiss();
notification_->set_delegate(nullptr);
notification_.reset();
}
}
@@ -200,7 +200,7 @@ void Notification::Show() {
if (presenter_) {
notification_ = presenter_->CreateNotification(this, base::GenerateGUID());
if (notification_) {
electron::NotificationOptions options;
brightray::NotificationOptions options;
options.title = title_;
options.subtitle = subtitle_;
options.msg = body_;
@@ -218,8 +218,7 @@ void Notification::Show() {
}
bool Notification::IsSupported() {
return !!static_cast<AtomBrowserClient*>(AtomBrowserClient::Get())
->GetNotificationPresenter();
return !!brightray::BrowserClient::Get()->GetNotificationPresenter();
}
// static
@@ -248,28 +247,26 @@ void Notification::BuildPrototype(v8::Isolate* isolate,
} // 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();
Notification::SetConstructor(isolate,
base::BindRepeating(&Notification::New));
Notification::SetConstructor(isolate, base::Bind(&Notification::New));
mate::Dictionary dict(isolate, exports);
dict.Set("Notification", Notification::GetConstructor(isolate)
->GetFunction(context)
.ToLocalChecked());
dict.Set("Notification",
Notification::GetConstructor(isolate)->GetFunction());
dict.SetMethod("isSupported", &Notification::IsSupported);
}
} // namespace
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_common_notification, Initialize)
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_common_notification, Initialize)

View File

@@ -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_ATOM_API_NOTIFICATION_H_
#define SHELL_BROWSER_API_ATOM_API_NOTIFICATION_H_
#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 "base/strings/utf_string_conversions.h"
#include "brightray/browser/notification.h"
#include "brightray/browser/notification_delegate.h"
#include "brightray/browser/notification_presenter.h"
#include "native_mate/handle.h"
#include "shell/browser/api/trackable_object.h"
#include "shell/browser/notifications/notification.h"
#include "shell/browser/notifications/notification_delegate.h"
#include "shell/browser/notifications/notification_presenter.h"
#include "ui/gfx/image/image.h"
namespace electron {
namespace atom {
namespace api {
class Notification : public mate::TrackableObject<Notification>,
public NotificationDelegate {
public brightray::NotificationDelegate {
public:
static mate::WrappableBase* New(mate::Arguments* args);
static bool IsSupported();
@@ -55,7 +55,7 @@ class Notification : public mate::TrackableObject<Notification>,
bool GetHasReply() const;
base::string16 GetReplyPlaceholder() const;
base::string16 GetSound() const;
std::vector<electron::NotificationAction> GetActions() const;
std::vector<brightray::NotificationAction> GetActions() const;
base::string16 GetCloseButtonText() const;
// Prop Setters
@@ -66,7 +66,7 @@ class Notification : public mate::TrackableObject<Notification>,
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<electron::NotificationAction>& actions);
void SetActions(const std::vector<brightray::NotificationAction>& actions);
void SetCloseButtonText(const base::string16& text);
private:
@@ -80,18 +80,18 @@ class Notification : public mate::TrackableObject<Notification>,
bool has_reply_ = false;
base::string16 reply_placeholder_;
base::string16 sound_;
std::vector<electron::NotificationAction> actions_;
std::vector<brightray::NotificationAction> actions_;
base::string16 close_button_text_;
electron::NotificationPresenter* presenter_;
brightray::NotificationPresenter* presenter_;
base::WeakPtr<electron::Notification> notification_;
base::WeakPtr<brightray::Notification> notification_;
DISALLOW_COPY_AND_ASSIGN(Notification);
};
} // namespace api
} // namespace electron
} // namespace atom
#endif // SHELL_BROWSER_API_ATOM_API_NOTIFICATION_H_
#endif // ATOM_BROWSER_API_ATOM_API_NOTIFICATION_H_

View File

@@ -2,14 +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/atom_api_power_monitor.h"
#include "atom/browser/api/atom_api_power_monitor.h"
#include "atom/browser/browser.h"
#include "atom/common/native_mate_converters/callback.h"
#include "base/power_monitor/power_monitor.h"
#include "base/power_monitor/power_monitor_device_source.h"
#include "native_mate/dictionary.h"
#include "shell/browser/browser.h"
#include "shell/common/native_mate_converters/callback.h"
#include "shell/common/node_includes.h"
#include "atom/common/node_includes.h"
namespace mate {
template <>
@@ -31,19 +32,19 @@ struct Converter<ui::IdleState> {
};
} // namespace mate
namespace electron {
namespace atom {
namespace api {
PowerMonitor::PowerMonitor(v8::Isolate* isolate) {
#if defined(OS_LINUX)
SetShutdownHandler(base::BindRepeating(&PowerMonitor::ShouldShutdown,
base::Unretained(this)));
SetShutdownHandler(
base::Bind(&PowerMonitor::ShouldShutdown, base::Unretained(this)));
#elif defined(OS_MACOSX)
Browser::Get()->SetShutdownHandler(base::BindRepeating(
&PowerMonitor::ShouldShutdown, base::Unretained(this)));
Browser::Get()->SetShutdownHandler(
base::Bind(&PowerMonitor::ShouldShutdown, base::Unretained(this)));
#endif
base::PowerMonitor::AddObserver(this);
base::PowerMonitor::Get()->AddObserver(this);
Init(isolate);
#if defined(OS_MACOSX) || defined(OS_WIN)
InitPlatformSpecificMonitors();
@@ -51,7 +52,7 @@ PowerMonitor::PowerMonitor(v8::Isolate* isolate) {
}
PowerMonitor::~PowerMonitor() {
base::PowerMonitor::RemoveObserver(this);
base::PowerMonitor::Get()->RemoveObserver(this);
}
bool PowerMonitor::ShouldShutdown() {
@@ -83,28 +84,27 @@ void PowerMonitor::OnResume() {
Emit("resume");
}
ui::IdleState PowerMonitor::GetSystemIdleState(v8::Isolate* isolate,
int idle_threshold) {
void PowerMonitor::QuerySystemIdleState(v8::Isolate* isolate,
int idle_threshold,
const ui::IdleCallback& callback) {
if (idle_threshold > 0) {
return ui::CalculateIdleState(idle_threshold);
ui::CalculateIdleState(idle_threshold, callback);
} 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();
void PowerMonitor::QuerySystemIdleTime(const ui::IdleTimeCallback& callback) {
ui::CalculateIdleTime(callback);
}
// static
v8::Local<v8::Value> PowerMonitor::Create(v8::Isolate* isolate) {
if (!Browser::Get()->is_ready()) {
isolate->ThrowException(v8::Exception::Error(
mate::StringToV8(isolate,
"The 'powerMonitor' module can't be used before the "
"app 'ready' event")));
isolate->ThrowException(v8::Exception::Error(mate::StringToV8(
isolate,
"Cannot require \"powerMonitor\" module before app is ready")));
return v8::Null(isolate);
}
@@ -122,17 +122,17 @@ void PowerMonitor::BuildPrototype(v8::Isolate* isolate,
.SetMethod("blockShutdown", &PowerMonitor::BlockShutdown)
.SetMethod("unblockShutdown", &PowerMonitor::UnblockShutdown)
#endif
.SetMethod("getSystemIdleState", &PowerMonitor::GetSystemIdleState)
.SetMethod("getSystemIdleTime", &PowerMonitor::GetSystemIdleTime);
.SetMethod("querySystemIdleState", &PowerMonitor::QuerySystemIdleState)
.SetMethod("querySystemIdleTime", &PowerMonitor::QuerySystemIdleTime);
}
} // namespace api
} // namespace electron
} // namespace atom
namespace {
using electron::api::PowerMonitor;
using atom::api::PowerMonitor;
void Initialize(v8::Local<v8::Object> exports,
v8::Local<v8::Value> unused,
@@ -140,13 +140,11 @@ void Initialize(v8::Local<v8::Object> exports,
void* priv) {
v8::Isolate* isolate = context->GetIsolate();
mate::Dictionary dict(isolate, exports);
dict.Set("createPowerMonitor",
base::BindRepeating(&PowerMonitor::Create, isolate));
dict.Set("PowerMonitor", PowerMonitor::GetConstructor(isolate)
->GetFunction(context)
.ToLocalChecked());
dict.Set("powerMonitor", PowerMonitor::Create(isolate));
dict.Set("PowerMonitor",
PowerMonitor::GetConstructor(isolate)->GetFunction());
}
} // namespace
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_power_monitor, Initialize)
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_power_monitor, Initialize)

View File

@@ -2,16 +2,16 @@
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef SHELL_BROWSER_API_ATOM_API_POWER_MONITOR_H_
#define SHELL_BROWSER_API_ATOM_API_POWER_MONITOR_H_
#ifndef ATOM_BROWSER_API_ATOM_API_POWER_MONITOR_H_
#define ATOM_BROWSER_API_ATOM_API_POWER_MONITOR_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 "shell/browser/api/trackable_object.h"
#include "shell/browser/lib/power_observer.h"
#include "ui/base/idle/idle.h"
namespace electron {
namespace atom {
namespace api {
@@ -46,8 +46,10 @@ class PowerMonitor : public mate::TrackableObject<PowerMonitor>,
void OnResume() override;
private:
ui::IdleState GetSystemIdleState(v8::Isolate* isolate, int idle_threshold);
int GetSystemIdleTime();
void QuerySystemIdleState(v8::Isolate* isolate,
int idle_threshold,
const ui::IdleCallback& callback);
void QuerySystemIdleTime(const ui::IdleTimeCallback& callback);
#if defined(OS_WIN)
// Static callback invoked when a message comes in to our messaging window.
@@ -76,6 +78,6 @@ class PowerMonitor : public mate::TrackableObject<PowerMonitor>,
} // namespace api
} // namespace electron
} // namespace atom
#endif // SHELL_BROWSER_API_ATOM_API_POWER_MONITOR_H_
#endif // ATOM_BROWSER_API_ATOM_API_POWER_MONITOR_H_

View File

@@ -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/atom_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
@@ -41,7 +39,7 @@
[super dealloc];
}
- (void)addEmitter:(electron::api::PowerMonitor*)monitor_ {
- (void)addEmitter:(atom::api::PowerMonitor*)monitor_ {
self->emitters.push_back(monitor_);
}
@@ -59,7 +57,7 @@
@end
namespace electron {
namespace atom {
namespace api {
@@ -73,4 +71,4 @@ void PowerMonitor::InitPlatformSpecificMonitors() {
} // namespace api
} // namespace electron
} // namespace atom

View File

@@ -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/browser/api/atom_api_power_monitor.h"
#include "atom/browser/api/atom_api_power_monitor.h"
#include <windows.h>
#include <wtsapi32.h>
@@ -11,7 +11,7 @@
#include "ui/base/win/shell.h"
#include "ui/gfx/win/hwnd_util.h"
namespace electron {
namespace atom {
namespace {
@@ -69,4 +69,4 @@ LRESULT CALLBACK PowerMonitor::WndProc(HWND hwnd,
} // namespace api
} // namespace electron
} // namespace atom

View File

@@ -0,0 +1,135 @@
// 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_power_save_blocker.h"
#include <string>
#include "base/task_scheduler/post_task.h"
#include "base/threading/thread_task_runner_handle.h"
#include "native_mate/dictionary.h"
#include "atom/common/node_includes.h"
namespace mate {
template <>
struct Converter<device::mojom::WakeLockType> {
static bool FromV8(v8::Isolate* isolate,
v8::Local<v8::Value> val,
device::mojom::WakeLockType* out) {
std::string type;
if (!ConvertFromV8(isolate, val, &type))
return false;
if (type == "prevent-app-suspension")
*out = device::mojom::WakeLockType::kPreventAppSuspension;
else if (type == "prevent-display-sleep")
*out = device::mojom::WakeLockType::kPreventDisplaySleep;
else
return false;
return true;
}
};
} // namespace mate
namespace atom {
namespace api {
PowerSaveBlocker::PowerSaveBlocker(v8::Isolate* isolate)
: current_blocker_type_(
device::mojom::WakeLockType::kPreventAppSuspension) {
Init(isolate);
}
PowerSaveBlocker::~PowerSaveBlocker() {}
void PowerSaveBlocker::UpdatePowerSaveBlocker() {
if (power_save_blocker_types_.empty()) {
power_save_blocker_.reset();
return;
}
// |WakeLockType::kPreventAppSuspension| keeps system active, but allows
// screen to be turned off.
// |WakeLockType::kPreventDisplaySleep| keeps system and screen active, has a
// higher precedence level than |WakeLockType::kPreventAppSuspension|.
//
// Only the highest-precedence blocker type takes effect.
device::mojom::WakeLockType new_blocker_type =
device::mojom::WakeLockType::kPreventAppSuspension;
for (const auto& element : power_save_blocker_types_) {
if (element.second == device::mojom::WakeLockType::kPreventDisplaySleep) {
new_blocker_type = device::mojom::WakeLockType::kPreventDisplaySleep;
break;
}
}
if (!power_save_blocker_ || new_blocker_type != current_blocker_type_) {
auto new_blocker = std::make_unique<device::PowerSaveBlocker>(
new_blocker_type, device::mojom::WakeLockReason::kOther,
ATOM_PRODUCT_NAME, base::ThreadTaskRunnerHandle::Get(),
// This task runner may be used by some device service
// implementation bits to interface with dbus client code, which in
// turn imposes some subtle thread affinity on the clients. We
// therefore require a single-thread runner.
base::CreateSingleThreadTaskRunnerWithTraits(
{base::MayBlock(), base::TaskPriority::BACKGROUND}));
power_save_blocker_.swap(new_blocker);
current_blocker_type_ = new_blocker_type;
}
}
int PowerSaveBlocker::Start(device::mojom::WakeLockType type) {
static int count = 0;
power_save_blocker_types_[count] = type;
UpdatePowerSaveBlocker();
return count++;
}
bool PowerSaveBlocker::Stop(int id) {
bool success = power_save_blocker_types_.erase(id) > 0;
UpdatePowerSaveBlocker();
return success;
}
bool PowerSaveBlocker::IsStarted(int id) {
return power_save_blocker_types_.find(id) != power_save_blocker_types_.end();
}
// static
mate::Handle<PowerSaveBlocker> PowerSaveBlocker::Create(v8::Isolate* isolate) {
return mate::CreateHandle(isolate, new PowerSaveBlocker(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);
}
} // namespace api
} // 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 dict(isolate, exports);
dict.Set("powerSaveBlocker", atom::api::PowerSaveBlocker::Create(isolate));
}
} // namespace
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_power_save_blocker, Initialize);

View File

@@ -0,0 +1,56 @@
// 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_POWER_SAVE_BLOCKER_H_
#define ATOM_BROWSER_API_ATOM_API_POWER_SAVE_BLOCKER_H_
#include <map>
#include <memory>
#include "atom/browser/api/trackable_object.h"
#include "native_mate/handle.h"
#include "services/device/wake_lock/power_save_blocker/power_save_blocker.h"
namespace mate {
class Dictionary;
}
namespace atom {
namespace api {
class PowerSaveBlocker : public mate::TrackableObject<PowerSaveBlocker> {
public:
static mate::Handle<PowerSaveBlocker> Create(v8::Isolate* isolate);
static void BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype);
protected:
explicit PowerSaveBlocker(v8::Isolate* isolate);
~PowerSaveBlocker() override;
private:
void UpdatePowerSaveBlocker();
int Start(device::mojom::WakeLockType type);
bool Stop(int id);
bool IsStarted(int id);
std::unique_ptr<device::PowerSaveBlocker> power_save_blocker_;
// Current blocker type used by |power_save_blocker_|
device::mojom::WakeLockType current_blocker_type_;
// Map from id to the corresponding blocker type for each request.
using WakeLockTypeMap = std::map<int, device::mojom::WakeLockType>;
WakeLockTypeMap power_save_blocker_types_;
DISALLOW_COPY_AND_ASSIGN(PowerSaveBlocker);
};
} // namespace api
} // namespace atom
#endif // ATOM_BROWSER_API_ATOM_API_POWER_SAVE_BLOCKER_H_

View File

@@ -0,0 +1,248 @@
// 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 atom {
namespace api {
namespace {
// List of registered custom standard schemes.
std::vector<std::string> g_standard_schemes;
} // namespace
std::vector<std::string> GetStandardSchemes() {
return g_standard_schemes;
}
void RegisterStandardSchemes(const std::vector<std::string>& schemes,
mate::Arguments* args) {
g_standard_schemes = schemes;
mate::Dictionary opts;
bool secure = false;
args->GetNext(&opts) && opts.Get("secure", &secure);
// Dynamically register the schemes.
auto* policy = content::ChildProcessSecurityPolicy::GetInstance();
for (const std::string& scheme : schemes) {
url::AddStandardScheme(scheme.c_str(), url::SCHEME_WITH_HOST);
if (secure) {
url::AddSecureScheme(scheme.c_str());
}
policy->RegisterWebSafeScheme(scheme);
}
// Add the schemes to command line switches, so child processes can also
// register them.
base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
atom::switches::kStandardSchemes, base::JoinString(schemes, ","));
if (secure) {
base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
atom::switches::kSecureSchemes, base::JoinString(schemes, ","));
}
}
Protocol::Protocol(v8::Isolate* isolate, AtomBrowserContext* browser_context)
: browser_context_(browser_context), weak_factory_(this) {
Init(isolate);
}
Protocol::~Protocol() {}
void Protocol::RegisterServiceWorkerSchemes(
const std::vector<std::string>& schemes) {
atom::AtomBrowserClient::SetCustomServiceWorkerSchemes(schemes);
}
void Protocol::UnregisterProtocol(const std::string& scheme,
mate::Arguments* args) {
CompletionCallback callback;
args->GetNext(&callback);
auto* getter = static_cast<URLRequestContextGetter*>(
browser_context_->GetRequestContext());
content::BrowserThread::PostTaskAndReplyWithResult(
content::BrowserThread::IO, FROM_HERE,
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;
}
void Protocol::IsProtocolHandled(const std::string& scheme,
const BooleanCallback& callback) {
auto* getter = static_cast<URLRequestContextGetter*>(
browser_context_->GetRequestContext());
content::BrowserThread::PostTaskAndReplyWithResult(
content::BrowserThread::IO, FROM_HERE,
base::Bind(&Protocol::IsProtocolHandledInIO, base::RetainedRef(getter),
scheme),
callback);
}
// static
bool Protocol::IsProtocolHandledInIO(
scoped_refptr<URLRequestContextGetter> request_context_getter,
const std::string& scheme) {
return request_context_getter->job_factory()->IsHandledProtocol(scheme);
}
void Protocol::UninterceptProtocol(const std::string& scheme,
mate::Arguments* args) {
CompletionCallback callback;
args->GetNext(&callback);
auto* getter = static_cast<URLRequestContextGetter*>(
browser_context_->GetRequestContext());
content::BrowserThread::PostTaskAndReplyWithResult(
content::BrowserThread::IO, FROM_HERE,
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("registerServiceWorkerSchemes",
&Protocol::RegisterServiceWorkerSchemes)
.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 RegisterStandardSchemes(const std::vector<std::string>& schemes,
mate::Arguments* args) {
if (atom::Browser::Get()->is_ready()) {
args->ThrowError(
"protocol.registerStandardSchemes should be called before "
"app is ready");
return;
}
atom::api::RegisterStandardSchemes(schemes, 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("registerStandardSchemes", &RegisterStandardSchemes);
dict.SetMethod("getStandardSchemes", &atom::api::GetStandardSchemes);
}
} // namespace
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_protocol, Initialize)

View File

@@ -0,0 +1,201 @@
// 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 "base/callback.h"
#include "base/memory/weak_ptr.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 RegisterStandardSchemes(const std::vector<std::string>& schemes,
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>)>;
using BooleanCallback = base::Callback<void(bool)>;
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 schemes that can handle service worker.
void RegisterServiceWorkerSchemes(const std::vector<std::string>& schemes);
// 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());
content::BrowserThread::PostTaskAndReplyWithResult(
content::BrowserThread::IO, FROM_HERE,
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.
void IsProtocolHandled(const std::string& scheme,
const BooleanCallback& callback);
static bool IsProtocolHandledInIO(
scoped_refptr<URLRequestContextGetter> request_context_getter,
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());
content::BrowserThread::PostTaskAndReplyWithResult(
content::BrowserThread::IO, FROM_HERE,
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_

View File

@@ -0,0 +1,91 @@
// 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 "content/public/browser/render_process_host.h"
#include "native_mate/dictionary.h"
#include "native_mate/object_template_builder.h"
#include "atom/common/node_includes.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::CreateFrom(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_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_render_process_preferences,
Initialize)

View 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_

View File

@@ -2,18 +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/atom_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 "base/bind.h"
#include "native_mate/dictionary.h"
#include "native_mate/object_template_builder.h"
#include "shell/browser/api/atom_api_browser_window.h"
#include "shell/browser/browser.h"
#include "shell/common/native_mate_converters/gfx_converter.h"
#include "shell/common/node_includes.h"
#include "ui/display/display.h"
#include "ui/display/screen.h"
#include "ui/gfx/geometry/point.h"
@@ -22,7 +21,9 @@
#include "ui/display/win/screen_win.h"
#endif
namespace electron {
#include "atom/common/node_includes.h"
namespace atom {
namespace api {
@@ -51,19 +52,6 @@ std::vector<std::string> MetricsToArray(uint32_t metrics) {
return array;
}
void DelayEmit(Screen* screen,
base::StringPiece name,
const display::Display& display) {
screen->Emit(name, display);
}
void DelayEmitWithMetrics(Screen* screen,
base::StringPiece name,
const display::Display& display,
const std::vector<std::string>& metrics) {
screen->Emit(name, display, metrics);
}
} // namespace
Screen::Screen(v8::Isolate* isolate, display::Screen* screen)
@@ -98,13 +86,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);
@@ -113,31 +101,23 @@ static gfx::Rect DIPToScreenRect(electron::NativeWindow* window,
#endif
void Screen::OnDisplayAdded(const display::Display& new_display) {
base::ThreadTaskRunnerHandle::Get()->PostNonNestableTask(
FROM_HERE, base::Bind(&DelayEmit, base::Unretained(this), "display-added",
new_display));
Emit("display-added", new_display);
}
void Screen::OnDisplayRemoved(const display::Display& old_display) {
base::ThreadTaskRunnerHandle::Get()->PostNonNestableTask(
FROM_HERE, base::Bind(&DelayEmit, base::Unretained(this),
"display-removed", old_display));
Emit("display-removed", old_display);
}
void Screen::OnDisplayMetricsChanged(const display::Display& display,
uint32_t changed_metrics) {
base::ThreadTaskRunnerHandle::Get()->PostNonNestableTask(
FROM_HERE, base::Bind(&DelayEmitWithMetrics, base::Unretained(this),
"display-metrics-changed", display,
MetricsToArray(changed_metrics)));
Emit("display-metrics-changed", display, MetricsToArray(changed_metrics));
}
// static
v8::Local<v8::Value> Screen::Create(v8::Isolate* isolate) {
if (!Browser::Get()->is_ready()) {
isolate->ThrowException(v8::Exception::Error(mate::StringToV8(
isolate,
"The 'screen' module can't be used before the app 'ready' event")));
isolate, "Cannot require \"screen\" module before app is ready")));
return v8::Null(isolate);
}
@@ -171,11 +151,11 @@ 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,
@@ -183,12 +163,10 @@ void Initialize(v8::Local<v8::Object> exports,
void* priv) {
v8::Isolate* isolate = context->GetIsolate();
mate::Dictionary dict(isolate, exports);
dict.Set("createScreen", base::BindRepeating(&Screen::Create, isolate));
dict.Set(
"Screen",
Screen::GetConstructor(isolate)->GetFunction(context).ToLocalChecked());
dict.Set("screen", Screen::Create(isolate));
dict.Set("Screen", Screen::GetConstructor(isolate)->GetFunction());
}
} // namespace
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_common_screen, Initialize)
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_common_screen, Initialize)

View File

@@ -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_ATOM_API_SCREEN_H_
#define SHELL_BROWSER_API_ATOM_API_SCREEN_H_
#ifndef ATOM_BROWSER_API_ATOM_API_SCREEN_H_
#define ATOM_BROWSER_API_ATOM_API_SCREEN_H_
#include <vector>
#include "atom/browser/api/event_emitter.h"
#include "native_mate/handle.h"
#include "shell/browser/api/event_emitter.h"
#include "ui/display/display_observer.h"
#include "ui/display/screen.h"
@@ -18,7 +18,7 @@ class Rect;
class Screen;
} // namespace gfx
namespace electron {
namespace atom {
namespace api {
@@ -54,6 +54,6 @@ class Screen : public mate::EventEmitter<Screen>,
} // namespace api
} // namespace electron
} // namespace atom
#endif // SHELL_BROWSER_API_ATOM_API_SCREEN_H_
#endif // ATOM_BROWSER_API_ATOM_API_SCREEN_H_

View File

@@ -2,21 +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/atom_api_session.h"
#include "atom/browser/api/atom_api_session.h"
#include <algorithm>
#include <map>
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include "base/command_line.h"
#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/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 "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 "brightray/browser/media/media_device_id_salt.h"
#include "chrome/browser/browser_process.h"
#include "chrome/common/pref_names.h"
#include "components/download/public/common/download_danger_type.h"
@@ -24,50 +39,27 @@
#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/network_service_instance.h"
#include "content/public/browser/storage_partition.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/self_owned_receiver.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/disk_cache/disk_cache.h"
#include "net/dns/host_cache.h"
#include "net/http/http_auth_handler_factory.h"
#include "net/http/http_auth_preferences.h"
#include "net/http/http_cache.h"
#include "services/network/network_service.h"
#include "services/network/public/cpp/features.h"
#include "shell/browser/api/atom_api_cookies.h"
#include "shell/browser/api/atom_api_data_pipe_holder.h"
#include "shell/browser/api/atom_api_download_item.h"
#include "shell/browser/api/atom_api_net_log.h"
#include "shell/browser/api/atom_api_protocol_ns.h"
#include "shell/browser/api/atom_api_web_request_ns.h"
#include "shell/browser/atom_browser_context.h"
#include "shell/browser/atom_browser_main_parts.h"
#include "shell/browser/atom_permission_manager.h"
#include "shell/browser/browser.h"
#include "shell/browser/media/media_device_id_salt.h"
#include "shell/browser/net/cert_verifier_client.h"
#include "shell/browser/session_preferences.h"
#include "shell/common/native_mate_converters/callback.h"
#include "shell/common/native_mate_converters/content_converter.h"
#include "shell/common/native_mate_converters/file_path_converter.h"
#include "shell/common/native_mate_converters/gurl_converter.h"
#include "shell/common/native_mate_converters/net_converter.h"
#include "shell/common/native_mate_converters/value_converter.h"
#include "shell/common/node_includes.h"
#include "shell/common/options_switches.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"
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
#include "shell/browser/extensions/atom_extension_system.h"
#endif
#include "atom/common/node_includes.h"
using atom::api::Cookies;
using content::BrowserThread;
using content::StoragePartition;
@@ -79,6 +71,15 @@ struct ClearStorageDataOptions {
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) {
@@ -119,6 +120,27 @@ uint32_t GetQuotaMask(const std::vector<std::string>& quota_types) {
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 {
@@ -141,9 +163,42 @@ struct Converter<ClearStorageDataOptions> {
}
};
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 electron {
namespace atom {
namespace api {
@@ -154,6 +209,129 @@ const char kPersistPrefix[] = "persist:";
// Referenced session objects.
std::map<uint32_t, v8::Global<v8::Object>> g_sessions;
// Runs the callback in UI thread.
void RunCallbackInUI(const base::Callback<void()>& callback) {
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, callback);
}
template <typename... T>
void RunCallbackInUI(const base::Callback<void(T...)>& callback, T... result) {
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
base::BindOnce(callback, result...));
}
// Callback of HttpCache::GetBackend.
void OnGetBackend(disk_cache::Backend** backend_ptr,
Session::CacheAction action,
const net::CompletionCallback& callback,
int result) {
if (result != net::OK) {
RunCallbackInUI(callback, result);
} else if (backend_ptr && *backend_ptr) {
if (action == Session::CacheAction::CLEAR) {
(*backend_ptr)
->DoomAllEntries(base::Bind(&RunCallbackInUI<int>, callback));
} else if (action == Session::CacheAction::STATS) {
base::StringPairs stats;
(*backend_ptr)->GetStats(&stats);
for (const auto& stat : stats) {
if (stat.first == "Current size") {
int current_size;
base::StringToInt(stat.second, &current_size);
RunCallbackInUI(callback, current_size);
break;
}
}
}
} else {
RunCallbackInUI<int>(callback, net::ERR_FAILED);
}
}
void DoCacheActionInIO(
const scoped_refptr<net::URLRequestContextGetter>& context_getter,
Session::CacheAction action,
const net::CompletionCallback& callback) {
auto* request_context = context_getter->GetURLRequestContext();
auto* http_cache = request_context->http_transaction_factory()->GetCache();
if (!http_cache)
RunCallbackInUI<int>(callback, net::ERR_FAILED);
// Call GetBackend and make the backend's ptr accessable in OnGetBackend.
using BackendPtr = disk_cache::Backend*;
auto** backend_ptr = new BackendPtr(nullptr);
net::CompletionCallback on_get_backend =
base::Bind(&OnGetBackend, base::Owned(backend_ptr), action, callback);
int rv = http_cache->GetBackend(backend_ptr, on_get_backend);
if (rv != net::ERR_IO_PENDING)
on_get_backend.Run(net::OK);
}
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,
const base::Closure& callback) {
auto* request_context = context_getter->GetURLRequestContext();
auto* cache = request_context->host_resolver()->GetHostCache();
if (cache) {
cache->clear();
DCHECK_EQ(0u, cache->size());
if (!callback.is_null())
RunCallbackInUI(callback);
}
}
void ClearAuthCacheInIO(
const scoped_refptr<net::URLRequestContextGetter>& context_getter,
const ClearAuthCacheOptions& options,
const base::Closure& callback) {
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();
}
if (!callback.is_null())
RunCallbackInUI(callback);
}
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 OnClearStorageDataDone(const base::Closure& callback) {
if (!callback.is_null())
callback.Run();
}
void DownloadIdCallback(content::DownloadManager* download_manager,
const base::FilePath& path,
const std::vector<GURL>& url_chain,
@@ -166,8 +344,8 @@ void DownloadIdCallback(content::DownloadManager* download_manager,
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(),
GURL(), 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(),
@@ -180,9 +358,8 @@ void DestroyGlobalHandle(v8::Isolate* 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)) {
if (local_handle->IsObject()) {
v8::Local<v8::Object> object = local_handle->ToObject();
void* ptr = object->GetAlignedPointerFromInternalField(0);
if (!ptr)
return;
@@ -210,10 +387,8 @@ Session::Session(v8::Isolate* isolate, AtomBrowserContext* browser_context)
Session::~Session() {
content::BrowserContext::GetDownloadManager(browser_context())
->RemoveObserver(this);
// TODO(zcbenz): Now since URLRequestContextGetter is gone, is this still
// needed?
// Refs https://github.com/electron/electron/pull/12305.
DestroyGlobalHandle(isolate(), cookies_);
DestroyGlobalHandle(isolate(), web_request_);
DestroyGlobalHandle(isolate(), protocol_);
DestroyGlobalHandle(isolate(), net_log_);
g_sessions.erase(weak_map_id());
@@ -238,79 +413,39 @@ void Session::OnDownloadCreated(content::DownloadManager* manager,
}
}
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::BindOnce(util::Promise::ResolvePromise<std::string>,
std::move(promise)));
return handle;
void Session::ResolveProxy(
const GURL& url,
const ResolveProxyHelper::ResolveProxyCallback& callback) {
browser_context_->GetResolveProxyHelper()->ResolveProxy(url, callback);
}
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;
template <Session::CacheAction action>
void Session::DoCacheAction(const net::CompletionCallback& callback) {
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::BindOnce(&DoCacheActionInIO,
WrapRefCounted(browser_context_->GetRequestContext()),
action, callback));
}
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();
void Session::ClearStorageData(mate::Arguments* args) {
// clearStorageData([options, callback])
ClearStorageDataOptions options;
base::Closure callback;
args->GetNext(&options);
args->GetNext(&callback);
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());
brightray::MediaDeviceIDSalt::Reset(browser_context()->prefs());
}
storage_partition->ClearData(
options.storage_types, options.quota_types, options.origin, base::Time(),
base::Time::Max(),
base::BindOnce(util::Promise::ResolveEmptyPromise, std::move(promise)));
return handle;
options.storage_types, options.quota_types, options.origin,
content::StoragePartition::OriginMatcherFunction(), base::Time(),
base::Time::Max(), base::Bind(&OnClearStorageDataDone, callback));
}
void Session::FlushStorageData() {
@@ -319,17 +454,11 @@ void Session::FlushStorageData() {
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);
void Session::SetProxy(const mate::Dictionary& options,
const base::Closure& callback) {
if (!browser_context_->in_memory_pref_store()) {
promise.Resolve();
return handle;
callback.Run();
return;
}
std::string proxy_rules, bypass_list, pac_url;
@@ -342,22 +471,17 @@ v8::Local<v8::Promise> Session::SetProxy(mate::Arguments* args) {
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 */)),
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)),
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;
base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, callback);
}
void Session::SetDownloadPath(const base::FilePath& path) {
@@ -391,54 +515,40 @@ void Session::DisableNetworkEmulation() {
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) {
proc.Run(request, base::AdaptCallbackForRepeating(std::move(cb)));
}
void Session::SetCertVerifyProc(v8::Local<v8::Value> val,
mate::Arguments* args) {
CertVerifierClient::CertVerifyProc proc;
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;
}
mojo::PendingRemote<network::mojom::CertVerifierClient>
cert_verifier_client_remote;
if (proc) {
mojo::MakeSelfOwnedReceiver(
std::make_unique<CertVerifierClient>(proc),
cert_verifier_client_remote.InitWithNewPipeAndPassReceiver());
}
content::BrowserContext::GetDefaultStoragePartition(browser_context_.get())
->GetNetworkContext()
->SetCertVerifierClient(std::move(cert_verifier_client_remote));
// This causes the cert verifier cache to be cleared.
content::GetNetworkService()->OnCertDBChanged();
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
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;
}
auto handler = std::make_unique<AtomPermissionManager::RequestHandler>();
if (!mate::ConvertFromV8(args->isolate(), val, handler.get())) {
AtomPermissionManager::RequestHandler handler;
if (!(val->IsNull() || mate::ConvertFromV8(args->isolate(), val, &handler))) {
args->ThrowError("Must pass null or function");
return;
}
permission_manager->SetPermissionRequestHandler(base::BindRepeating(
[](AtomPermissionManager::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))));
auto* permission_manager = static_cast<AtomPermissionManager*>(
browser_context()->GetPermissionControllerDelegate());
permission_manager->SetPermissionRequestHandler(handler);
}
void Session::SetPermissionCheckHandler(v8::Local<v8::Value> val,
@@ -453,67 +563,69 @@ void Session::SetPermissionCheckHandler(v8::Local<v8::Value> val,
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();
void Session::ClearHostResolverCache(mate::Arguments* args) {
base::Closure callback;
args->GetNext(&callback);
content::BrowserContext::GetDefaultStoragePartition(browser_context_.get())
->GetNetworkContext()
->ClearHostCache(nullptr,
base::BindOnce(util::Promise::ResolveEmptyPromise,
std::move(promise)));
return handle;
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::BindOnce(&ClearHostResolverCacheInIO,
WrapRefCounted(browser_context_->GetRequestContext()),
callback));
}
v8::Local<v8::Promise> Session::ClearAuthCache() {
auto* isolate = v8::Isolate::GetCurrent();
util::Promise promise(isolate);
v8::Local<v8::Promise> handle = promise.GetHandle();
void Session::ClearAuthCache(mate::Arguments* args) {
ClearAuthCacheOptions options;
if (!args->GetNext(&options)) {
args->ThrowError("Must specify options object");
return;
}
base::Closure callback;
args->GetNext(&callback);
content::BrowserContext::GetDefaultStoragePartition(browser_context_.get())
->GetNetworkContext()
->ClearHttpAuthCache(base::Time(),
base::BindOnce(util::Promise::ResolveEmptyPromise,
std::move(promise)));
return handle;
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::BindOnce(&ClearAuthCacheInIO,
WrapRefCounted(browser_context_->GetRequestContext()),
options, callback));
}
void Session::AllowNTLMCredentialsForDomains(const std::string& domains) {
network::mojom::HttpAuthDynamicParamsPtr auth_dynamic_params =
network::mojom::HttpAuthDynamicParams::New();
auth_dynamic_params->server_allowlist = domains;
auth_dynamic_params->enable_negotiate_port =
base::CommandLine::ForCurrentProcess()->HasSwitch(
electron::switches::kEnableAuthNegotiatePort);
content::GetNetworkService()->ConfigureHttpAuthPrefs(
std::move(auth_dynamic_params));
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::BindOnce(&AllowNTLMCredentialsForDomainsInIO,
WrapRefCounted(browser_context_->GetRequestContext()),
domains));
}
void Session::SetUserAgent(const std::string& user_agent,
mate::Arguments* args) {
browser_context_->SetUserAgent(user_agent);
content::BrowserContext::GetDefaultStoragePartition(browser_context_.get())
->GetNetworkContext()
->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) {
gin::Handle<DataPipeHolder> holder = DataPipeHolder::From(isolate, uuid);
if (holder.IsEmpty()) {
util::Promise promise(isolate);
promise.RejectWithErrorMessage("Could not get blob data handle");
return promise.GetHandle();
}
void Session::GetBlobData(const std::string& uuid,
const AtomBlobReader::CompletionCallback& callback) {
if (callback.is_null())
return;
return holder->ReadAll(isolate);
AtomBlobReader* blob_reader = browser_context()->GetBlobReader();
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::BindOnce(&AtomBlobReader::StartReading,
base::Unretained(blob_reader), uuid, callback));
}
void Session::CreateInterruptedDownload(const mate::Dictionary& options) {
@@ -542,7 +654,7 @@ void Session::CreateInterruptedDownload(const mate::Dictionary& options) {
}
auto* download_manager =
content::BrowserContext::GetDownloadManager(browser_context());
download_manager->GetDelegate()->GetNextId(base::BindRepeating(
download_manager->GetDelegate()->GetNextId(base::Bind(
&DownloadIdCallback, download_manager, path, url_chain, mime_type, offset,
length, last_modified, etag, base::Time::FromDoubleT(start_time)));
}
@@ -560,14 +672,6 @@ std::vector<base::FilePath::StringType> Session::GetPreloads() const {
return prefs->preloads();
}
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
void Session::LoadChromeExtension(const base::FilePath extension_path) {
auto* extension_system = static_cast<extensions::AtomExtensionSystem*>(
extensions::ExtensionSystem::Get(browser_context()));
extension_system->LoadExtension(extension_path);
}
#endif
v8::Local<v8::Value> Session::Cookies(v8::Isolate* isolate) {
if (cookies_.IsEmpty()) {
auto handle = Cookies::Create(isolate, browser_context());
@@ -578,66 +682,28 @@ v8::Local<v8::Value> Session::Cookies(v8::Isolate* isolate) {
v8::Local<v8::Value> Session::Protocol(v8::Isolate* isolate) {
if (protocol_.IsEmpty()) {
v8::Local<v8::Value> handle;
handle = ProtocolNS::Create(isolate, browser_context()).ToV8();
protocol_.Reset(isolate, handle);
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()) {
v8::Local<v8::Value> handle;
handle = WebRequestNS::Create(isolate, browser_context()).ToV8();
web_request_.Reset(isolate, handle);
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 = electron::api::NetLog::Create(isolate, browser_context());
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 void StartPreconnectOnUI(
scoped_refptr<AtomBrowserContext> browser_context,
const GURL& url,
int num_sockets_to_preconnect) {
std::vector<predictors::PreconnectRequest> requests = {
{url.GetOrigin(), num_sockets_to_preconnect, net::NetworkIsolationKey()}};
browser_context->GetPreconnectManager()->Start(url, requests);
}
void Session::Preconnect(const mate::Dictionary& options,
mate::Arguments* args) {
GURL url;
if (!options.Get("url", &url) || !url.is_valid()) {
args->ThrowError("Must pass non-empty valid url to session.preconnect.");
return;
}
int num_sockets_to_preconnect = 1;
if (options.Get("numSockets", &num_sockets_to_preconnect)) {
const int kMinSocketsToPreconnect = 1;
const int kMaxSocketsToPreconnect = 6;
if (num_sockets_to_preconnect < kMinSocketsToPreconnect ||
num_sockets_to_preconnect > kMaxSocketsToPreconnect) {
args->ThrowError(
base::StringPrintf("numSocketsToPreconnect is outside range [%d,%d]",
kMinSocketsToPreconnect, kMaxSocketsToPreconnect));
return;
}
}
DCHECK_GT(num_sockets_to_preconnect, 0);
base::PostTaskWithTraits(
FROM_HERE, {content::BrowserThread::UI},
base::BindOnce(&StartPreconnectOnUI, base::RetainedRef(browser_context_),
url, num_sockets_to_preconnect));
}
// static
mate::Handle<Session> Session::CreateFrom(v8::Isolate* isolate,
AtomBrowserContext* browser_context) {
@@ -681,8 +747,8 @@ void Session::BuildPrototype(v8::Isolate* isolate,
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
.MakeDestroyable()
.SetMethod("resolveProxy", &Session::ResolveProxy)
.SetMethod("getCacheSize", &Session::GetCacheSize)
.SetMethod("clearCache", &Session::ClearCache)
.SetMethod("getCacheSize", &Session::DoCacheAction<CacheAction::STATS>)
.SetMethod("clearCache", &Session::DoCacheAction<CacheAction::CLEAR>)
.SetMethod("clearStorageData", &Session::ClearStorageData)
.SetMethod("flushStorageData", &Session::FlushStorageData)
.SetMethod("setProxy", &Session::SetProxy)
@@ -705,10 +771,6 @@ void Session::BuildPrototype(v8::Isolate* isolate,
&Session::CreateInterruptedDownload)
.SetMethod("setPreloads", &Session::SetPreloads)
.SetMethod("getPreloads", &Session::GetPreloads)
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
.SetMethod("loadChromeExtension", &Session::LoadChromeExtension)
#endif
.SetMethod("preconnect", &Session::Preconnect)
.SetProperty("cookies", &Session::Cookies)
.SetProperty("netLog", &Session::NetLog)
.SetProperty("protocol", &Session::Protocol)
@@ -717,18 +779,15 @@ void Session::BuildPrototype(v8::Isolate* isolate,
} // namespace api
} // namespace electron
} // namespace atom
namespace {
using electron::api::Cookies;
using electron::api::NetLog;
using electron::api::ProtocolNS;
using electron::api::Session;
using atom::api::Session;
v8::Local<v8::Value> FromPartition(const std::string& partition,
mate::Arguments* args) {
if (!electron::Browser::Get()->is_ready()) {
if (!atom::Browser::Get()->is_ready()) {
args->ThrowError("Session can only be received when app is ready");
return v8::Null(args->isolate());
}
@@ -743,21 +802,11 @@ void Initialize(v8::Local<v8::Object> exports,
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", ProtocolNS::GetConstructor(isolate)
->GetFunction(context)
.ToLocalChecked());
dict.Set("Session", Session::GetConstructor(isolate)->GetFunction());
dict.Set("Cookies", Cookies::GetConstructor(isolate)->GetFunction());
dict.SetMethod("fromPartition", &FromPartition);
}
} // namespace
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_session, Initialize)
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_session, Initialize)

View File

@@ -2,19 +2,19 @@
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef SHELL_BROWSER_API_ATOM_API_SESSION_H_
#define SHELL_BROWSER_API_ATOM_API_SESSION_H_
#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 "base/values.h"
#include "content/public/browser/download_manager.h"
#include "electron/buildflags/buildflags.h"
#include "native_mate/handle.h"
#include "shell/browser/api/trackable_object.h"
#include "shell/browser/net/resolve_proxy_helper.h"
#include "shell/common/promise_util.h"
#include "net/base/completion_callback.h"
class GURL;
@@ -31,7 +31,7 @@ namespace net {
class ProxyConfig;
}
namespace electron {
namespace atom {
class AtomBrowserContext;
@@ -40,6 +40,11 @@ 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);
@@ -57,12 +62,13 @@ class Session : public mate::TrackableObject<Session>,
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 ResolveProxy(const GURL& url,
const ResolveProxyHelper::ResolveProxyCallback& callback);
template <CacheAction action>
void DoCacheAction(const net::CompletionCallback& callback);
void ClearStorageData(mate::Arguments* args);
void FlushStorageData();
v8::Local<v8::Promise> SetProxy(mate::Arguments* args);
void SetProxy(const mate::Dictionary& options, const base::Closure& callback);
void SetDownloadPath(const base::FilePath& path);
void EnableNetworkEmulation(const mate::Dictionary& options);
void DisableNetworkEmulation();
@@ -71,13 +77,13 @@ class Session : public mate::TrackableObject<Session>,
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();
void ClearHostResolverCache(mate::Arguments* args);
void 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 GetBlobData(const std::string& uuid,
const AtomBlobReader::CompletionCallback& callback);
void CreateInterruptedDownload(const mate::Dictionary& options);
void SetPreloads(const std::vector<base::FilePath::StringType>& preloads);
std::vector<base::FilePath::StringType> GetPreloads() const;
@@ -85,11 +91,6 @@ class Session : public mate::TrackableObject<Session>,
v8::Local<v8::Value> Protocol(v8::Isolate* isolate);
v8::Local<v8::Value> WebRequest(v8::Isolate* isolate);
v8::Local<v8::Value> NetLog(v8::Isolate* isolate);
void Preconnect(const mate::Dictionary& options, mate::Arguments* args);
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
void LoadChromeExtension(const base::FilePath extension_path);
#endif
protected:
Session(v8::Isolate* isolate, AtomBrowserContext* browser_context);
@@ -100,13 +101,11 @@ class Session : public mate::TrackableObject<Session>,
download::DownloadItem* item) override;
private:
// Cached mate::Wrappable objects.
// Cached object.
v8::Global<v8::Value> cookies_;
v8::Global<v8::Value> protocol_;
v8::Global<v8::Value> net_log_;
// Cached object.
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_;
@@ -118,6 +117,6 @@ class Session : public mate::TrackableObject<Session>,
} // namespace api
} // namespace electron
} // namespace atom
#endif // SHELL_BROWSER_API_ATOM_API_SESSION_H_
#endif // ATOM_BROWSER_API_ATOM_API_SESSION_H_

View File

@@ -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/atom_api_system_preferences.h"
#include "atom/browser/api/atom_api_system_preferences.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 "shell/common/native_mate_converters/callback.h"
#include "shell/common/native_mate_converters/value_converter.h"
#include "shell/common/node_includes.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 {
@@ -31,7 +29,7 @@ SystemPreferences::~SystemPreferences() {
#if !defined(OS_MACOSX)
bool SystemPreferences::IsDarkMode() {
return ui::NativeTheme::GetInstanceForNativeUi()->ShouldUseDarkColors();
return false;
}
#endif
@@ -39,23 +37,6 @@ bool SystemPreferences::IsInvertedColorScheme() {
return color_utils::IsInvertedColorScheme();
}
bool SystemPreferences::IsHighContrastColorScheme() {
return ui::NativeTheme::GetInstanceForNativeUi()->UsesHighContrastColors();
}
v8::Local<v8::Value> SystemPreferences::GetAnimationSettings(
v8::Isolate* isolate) {
mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate);
dict.SetHidden("simple", true);
dict.Set("shouldRenderRichAnimation",
gfx::Animation::ShouldRenderRichAnimation());
dict.Set("scrollAnimationsEnabledBySystem",
gfx::Animation::ScrollAnimationsEnabledBySystem());
dict.Set("prefersReducedMotion", gfx::Animation::PrefersReducedMotion());
return dict.GetHandle();
}
// static
mate::Handle<SystemPreferences> SystemPreferences::Create(
v8::Isolate* isolate) {
@@ -68,13 +49,10 @@ void SystemPreferences::BuildPrototype(
v8::Local<v8::FunctionTemplate> prototype) {
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)
#endif
#if defined(OS_WIN)
.SetMethod("getAccentColor", &SystemPreferences::GetAccentColor)
.SetMethod("isAeroGlassEnabled", &SystemPreferences::IsAeroGlassEnabled)
.SetMethod("getColor", &SystemPreferences::GetColor)
#elif defined(OS_MACOSX)
.SetMethod("postNotification", &SystemPreferences::PostNotification)
.SetMethod("subscribeNotification",
@@ -99,42 +77,25 @@ void SystemPreferences::BuildPrototype(
.SetMethod("removeUserDefault", &SystemPreferences::RemoveUserDefault)
.SetMethod("isSwipeTrackingFromScrollEventsEnabled",
&SystemPreferences::IsSwipeTrackingFromScrollEventsEnabled)
.SetMethod("_getEffectiveAppearance",
.SetMethod("getEffectiveAppearance",
&SystemPreferences::GetEffectiveAppearance)
.SetMethod("_getAppLevelAppearance",
.SetMethod("getAppLevelAppearance",
&SystemPreferences::GetAppLevelAppearance)
.SetMethod("_setAppLevelAppearance",
.SetMethod("setAppLevelAppearance",
&SystemPreferences::SetAppLevelAppearance)
.SetProperty("appLevelAppearance",
&SystemPreferences::GetAppLevelAppearance,
&SystemPreferences::SetAppLevelAppearance)
.SetProperty("effectiveAppearance",
&SystemPreferences::GetEffectiveAppearance)
.SetMethod("getSystemColor", &SystemPreferences::GetSystemColor)
.SetMethod("canPromptTouchID", &SystemPreferences::CanPromptTouchID)
.SetMethod("promptTouchID", &SystemPreferences::PromptTouchID)
.SetMethod("isTrustedAccessibilityClient",
&SystemPreferences::IsTrustedAccessibilityClient)
.SetMethod("getMediaAccessStatus",
&SystemPreferences::GetMediaAccessStatus)
.SetMethod("askForMediaAccess", &SystemPreferences::AskForMediaAccess)
#endif
.SetMethod("isInvertedColorScheme",
&SystemPreferences::IsInvertedColorScheme)
.SetMethod("isHighContrastColorScheme",
&SystemPreferences::IsHighContrastColorScheme)
.SetMethod("isDarkMode", &SystemPreferences::IsDarkMode)
.SetMethod("getAnimationSettings",
&SystemPreferences::GetAnimationSettings);
.SetMethod("isDarkMode", &SystemPreferences::IsDarkMode);
}
} // 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,
@@ -143,11 +104,10 @@ void Initialize(v8::Local<v8::Object> exports,
v8::Isolate* isolate = context->GetIsolate();
mate::Dictionary dict(isolate, exports);
dict.Set("systemPreferences", SystemPreferences::Create(isolate));
dict.Set("SystemPreferences", SystemPreferences::GetConstructor(isolate)
->GetFunction(context)
.ToLocalChecked());
dict.Set("SystemPreferences",
SystemPreferences::GetConstructor(isolate)->GetFunction());
}
} // namespace
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_system_preferences, Initialize)
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_system_preferences, Initialize);

View File

@@ -2,21 +2,20 @@
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef SHELL_BROWSER_API_ATOM_API_SYSTEM_PREFERENCES_H_
#define SHELL_BROWSER_API_ATOM_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 "base/callback.h"
#include "base/values.h"
#include "native_mate/handle.h"
#include "shell/browser/api/event_emitter.h"
#include "shell/common/promise_util.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
@@ -24,7 +23,7 @@ namespace base {
class DictionaryValue;
}
namespace electron {
namespace atom {
namespace api {
@@ -49,13 +48,12 @@ class SystemPreferences : public mate::EventEmitter<SystemPreferences>
static void BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype);
#if defined(OS_WIN) || defined(OS_MACOSX)
std::string GetAccentColor();
std::string GetColor(const std::string& color, mate::Arguments* args);
#endif
#if defined(OS_WIN)
bool IsAeroGlassEnabled();
std::string GetAccentColor();
std::string GetColor(const std::string& color, mate::Arguments* args);
void InitializeWindow();
// gfx::SysColorChangeListener:
@@ -66,13 +64,10 @@ class SystemPreferences : public mate::EventEmitter<SystemPreferences>
#elif defined(OS_MACOSX)
using NotificationCallback =
base::RepeatingCallback<void(const std::string&,
const base::DictionaryValue&,
const std::string&)>;
base::Callback<void(const std::string&, const base::DictionaryValue&)>;
void PostNotification(const std::string& name,
const base::DictionaryValue& user_info,
mate::Arguments* args);
const base::DictionaryValue& user_info);
int SubscribeNotification(const std::string& name,
const NotificationCallback& callback);
void UnsubscribeNotification(int id);
@@ -95,21 +90,6 @@ class SystemPreferences : public mate::EventEmitter<SystemPreferences>
void RemoveUserDefault(const std::string& name);
bool IsSwipeTrackingFromScrollEventsEnabled();
std::string GetSystemColor(const std::string& color, mate::Arguments* args);
bool CanPromptTouchID();
v8::Local<v8::Promise> PromptTouchID(v8::Isolate* isolate,
const std::string& reason);
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);
// TODO(MarshallOfSound): Write tests for these methods once we
// are running tests on a Mojave machine
v8::Local<v8::Value> GetEffectiveAppearance(v8::Isolate* isolate);
@@ -118,14 +98,15 @@ class SystemPreferences : public mate::EventEmitter<SystemPreferences>
#endif
bool IsDarkMode();
bool IsInvertedColorScheme();
bool IsHighContrastColorScheme();
v8::Local<v8::Value> GetAnimationSettings(v8::Isolate* isolate);
protected:
explicit SystemPreferences(v8::Isolate* isolate);
~SystemPreferences() override;
#if defined(OS_MACOSX)
void DoPostNotification(const std::string& name,
const base::DictionaryValue& user_info,
NotificationCenterKind kind);
int DoSubscribeNotification(const std::string& name,
const NotificationCallback& callback,
NotificationCenterKind kind);
@@ -158,8 +139,6 @@ class SystemPreferences : public mate::EventEmitter<SystemPreferences>
bool invertered_color_scheme_;
bool high_contrast_color_scheme_;
std::unique_ptr<gfx::ScopedSysColorChangeListener> color_change_listener_;
#endif
DISALLOW_COPY_AND_ASSIGN(SystemPreferences);
@@ -167,6 +146,6 @@ class SystemPreferences : public mate::EventEmitter<SystemPreferences>
} // namespace api
} // namespace electron
} // namespace atom
#endif // SHELL_BROWSER_API_ATOM_API_SYSTEM_PREFERENCES_H_
#endif // ATOM_BROWSER_API_ATOM_API_SYSTEM_PREFERENCES_H_

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