Compare commits

..

48 Commits

Author SHA1 Message Date
John Kleinschmidt
f2fe287b34 Bump v1.6.13 2017-09-06 13:17:43 -04:00
John Kleinschmidt
47242064ba Fix syntax error 2017-09-06 12:54:26 -04:00
John Kleinschmidt
da73284515 Make sure future 1.6 releases are tagged correctly 2017-09-06 12:30:47 -04:00
John Kleinschmidt
9b74f25770 Backport macOS IME backspace fix for 1.6.x (#10450) 2017-09-06 11:25:14 -04:00
Zeke Sikelianos
dcb5a34922 Bump empty commit 2017-08-03 13:31:21 -07:00
Zeke Sikelianos
df55c1e717 Bump a third time 2017-08-03 10:43:29 -07:00
Zeke Sikelianos
a62f13856b Bump v1.6.12 2017-08-03 10:38:07 -07:00
Zeke Sikelianos
c83ff61fdf lock typescript generator to older version 2017-08-03 10:37:45 -07:00
John Kleinschmidt
2b83512c44 Merge pull request #10166 from electron/1-6-fixes
Backport fixes to 1.6
2017-08-02 16:58:14 -04:00
John Kleinschmidt
c12f7d3132 Fix commitText invocation 2017-08-02 09:45:42 -04:00
Zeke Sikelianos
9c0a8ab168 point to newer 1-6-fixes commit 2017-08-01 15:57:24 -07:00
Zeke Sikelianos
8842b04567 Merge pull request #10164 from electron/backport-10070-1-6-x
Backport 10070 to 1.6
2017-08-01 10:10:18 -07:00
Zeke Sikelianos
0573919fd3 use latest commit from libcc electron-1-6-x branch 2017-07-31 16:01:36 -07:00
Cheng Zhao
5253c0a816 Leak the Node environment when context is released 2017-07-31 13:23:35 -07:00
John Kleinschmidt
05b412313d Backport 10070 to 1.6 2017-07-31 10:20:49 -04:00
Kevin Sawicki
0428632a4e Bump v1.6.11 2017-05-25 10:56:30 -07:00
Kevin Sawicki
855d2c4b20 Merge pull request #9586 from electron/upgrade-libcc
Upgrade libcc with 1.6.x fixes
2017-05-25 10:55:25 -07:00
Kevin Sawicki
f0402be869 Enable verbose bootstrap on CI 2017-05-25 10:25:51 -07:00
Kevin Sawicki
5a1e3fc0f3 Upgrade to electron/libchromiumcontent@e2ec6935 2017-05-25 09:51:16 -07:00
Kevin Sawicki
01c31ee924 Merge pull request #9564 from rreimann/pdf-plugins-preference-backport
Backport suppress dispatching to PDF viewer if plugins are disabled to 1.6.x
2017-05-24 09:04:33 -07:00
rreimann
c29316b568 Remove superfluous method 2017-05-24 07:09:51 +02:00
Kevin Sawicki
21f15fa87e Delete mock.pdf after download completes
(cherry picked from commit 647e88da5a)
2017-05-23 14:22:26 +02:00
rreimann
ab95ecda42 Fix naming and formatting
(cherry picked from commit 25015c4c63)
2017-05-23 14:22:08 +02:00
rreimann
456e83f286 Extract common code into IsPreferenceEnabled method
(cherry picked from commit 791486433d)
2017-05-23 14:21:53 +02:00
rreimann
1612ebc539 Move preferences check to OnPdfResourceIntercepted
(cherry picked from commit 65da983ccb)
2017-05-23 14:21:35 +02:00
rreimann
1ddb8a8bf1 Add new test and enable plugins for existing tests
(cherry picked from commit 13665090d5)
2017-05-23 14:21:09 +02:00
rreimann
bbcdbc2e7c Fix linting violations
(cherry picked from commit 7982754958)
2017-05-23 14:20:41 +02:00
rreimann
d94bbd1573 Suppress pdf plugin dispatch if plugins are disabled
(cherry picked from commit 1b75e45a62)
2017-05-23 14:20:00 +02:00
Kevin Sawicki
583e14efcd Merge pull request #9514 from electron/disable-crash-specs-on-linux
Backport disabling crash specs on linux to 1.6
2017-05-17 15:25:14 -07:00
Kevin Sawicki
b96803e3a0 Disable crashReporter specs on Linux CI 2017-05-17 15:00:39 -07:00
Kevin Sawicki
c03cb11aaf Merge pull request #9505 from electron/backport-sandbox-remote-exception-fix
Backport sandbox remote exception fix
2017-05-17 11:19:25 -07:00
Kevin Sawicki
5de881e668 Merge pull request #9499 from electron/node-cert-patch
Upgrade node for StartCom/WoSign cert rejection
2017-05-17 11:07:21 -07:00
Thiago de Arruda
964505398d Add test for #9387 2017-05-17 07:29:22 -03:00
Thiago de Arruda
16f2958ad7 Fix how rpc-server releases references after page reload
In addition to listening for "render-view-deleted", listen for
"ELECTRON_BROWSER_CONTEXT_RELEASE" synchronous message, which is sent by the
remote module when the page is about to be navigated.

This is required to allow child windows running in the same renderer to
correctly manage remote object references, since `render-view-deleted` is only
called when the renderer exits.

Close #9387
2017-05-17 07:29:06 -03:00
Kevin Sawicki
332b92ebab Upgrade node for StartCom/WoSign cert rejection 2017-05-16 16:29:43 -07:00
Kevin Sawicki
b9f66a342c Bump v1.6.10 2017-05-16 10:38:35 -07:00
Kevin Sawicki
23ce796450 Merge pull request #9484 from electron/1-6-x-typescript-backport
backport electron.d.ts fixes 1.6
2017-05-16 10:15:29 -07:00
Samuel Attard
df6d316dc2 Fix webcontents capital 2017-05-15 15:16:22 -07:00
Kevin Sawicki
82a93ce645 Correct property name to pid 2017-05-15 14:19:02 -07:00
Kevin Sawicki
5ceaca66f5 fix setAutoResize options 2017-05-15 14:18:44 -07:00
Kevin Sawicki
4c0e35776b fix setAutoResize options 2017-05-15 14:18:02 -07:00
Birunthan Mohanathas
cc1f213d84 bump versions of electron-docs-linter and electron-typescript-definitions 2017-05-15 14:04:22 -07:00
Birunthan Mohanathas
4c18037e6a Fix copy paste typos in BrowserView docs 2017-05-15 14:02:05 -07:00
Samuel Attard
7f0ccdadcd Fix createFromDataURL return type
Fixes #9469
2017-05-15 14:02:00 -07:00
Birunthan Mohanathas
8ac9499b45 Make docs for webview.findInPage and webContents.findInPage consistent 2017-05-15 14:01:55 -07:00
Birunthan Mohanathas
8094d68acc Fix postData type definition in docs 2017-05-15 14:01:50 -07:00
Samuel Attard
80066c22b2 Fix return type of makeSingleInstance 2017-05-15 14:01:45 -07:00
Zeke Sikelianos
8f78f3b253 add npm scripts for convenience 2017-05-15 14:01:34 -07:00
1577 changed files with 70556 additions and 82804 deletions

View File

@@ -1,339 +0,0 @@
build-steps: &build-steps
steps:
- checkout
- run:
name: Install Node.js 10 on MacOS
command: |
if [ "$INSTALL_MACOS_NODE" == "true" ]; then
echo 'Installing Node.js 10 for MacOS'
brew update
brew install node@10
fi
- run:
name: Check for release
command: |
if [ -n "${RUN_RELEASE_BUILD}" ]; then
echo 'release build triggered from api'
echo 'export ELECTRON_RELEASE=1 UPLOAD_TO_S3=1' >> $BASH_ENV
fi
- run:
name: Bootstrap
command: |
if [ "$ELECTRON_RELEASE" == "1" ]; then
echo "Bootstrapping Electron for release build for $TARGET_ARCH"
script/bootstrap.py --target_arch=$TARGET_ARCH
else
echo "Bootstrapping Electron for debug build for $TARGET_ARCH"
script/bootstrap.py --target_arch=$TARGET_ARCH --dev
fi
- run:
name: Lint
command: npm run lint
- run:
name: Build
command: |
if [ "$ELECTRON_RELEASE" == "1" ]; then
echo 'Building Electron for release'
script/build.py -c R
else
echo 'Building Electron for debug'
script/build.py -c D
fi
- run:
name: Create distribution
command: |
if [ "$ELECTRON_RELEASE" == "1" ]; then
echo 'Creating Electron release distribution'
script/create-dist.py
else
echo 'Skipping create distribution because build is not for release'
fi
- run:
name: Upload distribution
command: |
if [ "$ELECTRON_RELEASE" == "1" ] && [ "$UPLOAD_TO_S3" != "1" ]; then
echo 'Uploading Electron release distribution to github releases'
script/upload.py
elif [ "$ELECTRON_RELEASE" == "1" ] && [ "$UPLOAD_TO_S3" == "1" ]; then
echo 'Uploading Electron release distribution to s3'
script/upload.py --upload_to_s3
else
echo 'Skipping upload distribution because build is not for release'
fi
- run:
name: Setup for headless testing
command: |
if [ "$RUN_HEADLESS_TESTS" == "true" ]; then
echo 'Setup for headless testing'
sh -e /etc/init.d/xvfb start
else
echo 'Headless testing not needed'
fi
- run:
name: Test
environment:
MOCHA_FILE: junit/test-results.xml
MOCHA_REPORTER: mocha-junit-reporter
command: |
if [ "$RUN_TESTS" == "true" ]; then
if [ "$ELECTRON_RELEASE" != "1" ]; then
echo 'Testing Electron debug build'
mkdir junit
script/test.py --ci --rebuild_native_modules
else
if [ "$UPLOAD_TO_S3" == "1" ]; then
echo 'Testing Electron release build'
mkdir junit
script/test.py --ci --rebuild_native_modules -c R
else
echo 'Skipping tests on GitHub release'
fi
fi
else
echo 'Skipping tests due to configuration'
fi
- run:
name: Verify FFmpeg
command: |
if [ "$RUN_TESTS" == "true" ]; then
if [ "$ELECTRON_RELEASE" != "1" ]; then
echo 'Verifying ffmpeg on debug build'
script/verify-ffmpeg.py
else
echo 'Verifying ffmpeg on release build'
script/verify-ffmpeg.py -R
fi
else
echo 'Skipping tests due to configuration'
fi
- run:
name: Generate Typescript Definitions
command: |
if [ "$CREATE_TYPESCRIPT_DEFS" == "true" ]; then
npm run create-typescript-definitions
fi
- persist_to_workspace:
root: out
paths:
- "*"
- store_test_results:
path: junit
- store_artifacts:
path: junit
- store_artifacts:
path: out
build-defaults: &build-defaults
docker:
- image: electronbuilds/electron:0.0.8
<<: *build-steps
version: 2
jobs:
electron-linux-arm:
environment:
TARGET_ARCH: arm
<<: *build-defaults
resource_class: 2xlarge
electron-linux-arm-test:
machine: true
steps:
- attach_workspace:
at: /tmp/workspace/project/out
- checkout
- run:
name: Test in ARM docker container
command: |
if [ "$ELECTRON_RELEASE" != "1" ]; then
docker run --rm --privileged multiarch/qemu-user-static:register --reset
docker run -it \
--mount type=bind,source=/tmp/workspace,target=/tmp/workspace \
--rm electronbuilds/electronarm7:0.0.5 > version.txt
cat version.txt
if grep -q `script/get-version.py` version.txt; then
echo "Versions match"
else
echo "Versions do not match"
exit 1
fi
else
echo "Skipping test for release build"
fi
electron-linux-arm-release-nightly:
environment:
TARGET_ARCH: arm
RUN_RELEASE_BUILD: true
<<: *build-defaults
resource_class: 2xlarge
electron-linux-arm64:
environment:
TARGET_ARCH: arm64
<<: *build-defaults
resource_class: 2xlarge
electron-linux-arm64-test:
machine: true
steps:
- attach_workspace:
at: /tmp/workspace/project/out
- checkout
- run:
name: Test in ARM64 docker container
command: |
if [ "$ELECTRON_RELEASE" != "1" ]; then
docker run --rm --privileged multiarch/qemu-user-static:register --reset
docker run -it \
--mount type=bind,source=/tmp/workspace,target=/tmp/workspace \
--rm electronbuilds/electronarm64:0.0.6 > version.txt
cat version.txt
if grep -q `script/get-version.py` version.txt; then
echo "Versions match"
else
echo "Versions do not match"
exit 1
fi
else
echo "Skipping test for release build"
fi
electron-linux-arm64-release-nightly:
environment:
TARGET_ARCH: arm64
RUN_RELEASE_BUILD: true
<<: *build-defaults
resource_class: 2xlarge
electron-linux-ia32:
environment:
TARGET_ARCH: ia32
DISPLAY: ':99.0'
RUN_TESTS: true
RUN_HEADLESS_TESTS: true
<<: *build-defaults
resource_class: xlarge
electron-linux-ia32-release-nightly:
environment:
TARGET_ARCH: ia32
RUN_RELEASE_BUILD: true
<<: *build-defaults
resource_class: xlarge
electron-linux-mips64el:
environment:
TARGET_ARCH: mips64el
<<: *build-defaults
resource_class: xlarge
electron-linux-x64:
environment:
TARGET_ARCH: x64
DISPLAY: ':99.0'
RUN_TESTS: true
RUN_HEADLESS_TESTS: true
CREATE_TYPESCRIPT_DEFS: true
<<: *build-defaults
resource_class: xlarge
electron-linux-x64-release-nightly:
environment:
TARGET_ARCH: x64
RUN_RELEASE_BUILD: true
<<: *build-defaults
resource_class: xlarge
electron-osx-x64:
environment:
TARGET_ARCH: x64
RUN_TESTS: true
INSTALL_MACOS_NODE: true
macos:
xcode: "8.3.3"
<<: *build-steps
electron-osx-x64-release-nightly:
environment:
TARGET_ARCH: x64
RUN_RELEASE_BUILD: true
INSTALL_MACOS_NODE: true
macos:
xcode: "8.3.3"
<<: *build-steps
electron-mas-x64:
environment:
TARGET_ARCH: x64
MAS_BUILD: 1
RUN_TESTS: true
INSTALL_MACOS_NODE: true
macos:
xcode: "8.3.3"
<<: *build-steps
electron-mas-x64-release-nightly:
environment:
TARGET_ARCH: x64
MAS_BUILD: 1
RUN_RELEASE_BUILD: true
INSTALL_MACOS_NODE: true
macos:
xcode: "8.3.3"
<<: *build-steps
workflows:
version: 2
build-arm:
jobs:
- electron-linux-arm
- electron-linux-arm-test:
requires:
- electron-linux-arm
build-arm64:
jobs:
- electron-linux-arm64
- electron-linux-arm64-test:
requires:
- electron-linux-arm64
build-ia32:
jobs:
- electron-linux-ia32
build-x64:
jobs:
- electron-linux-x64
build-osx-x64:
jobs:
- electron-osx-x64
build-mas-x64:
jobs:
- electron-mas-x64
nightly-release-test:
triggers:
- schedule:
cron: "0 0 * * *"
filters:
branches:
only:
- master
- 2-0-x
- 1-8-x
- 1-7-x
jobs:
- electron-linux-arm-release-nightly
- electron-linux-arm64-release-nightly
- electron-linux-ia32-release-nightly
- electron-linux-x64-release-nightly
experimental:
notify:
branches:
only:
- master
- 2-0-x
- 1-8-x
- 1-7-x

View File

@@ -1,3 +0,0 @@
*
!tools/xvfb-init.sh
!tools/run-electron.sh

View File

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

21
.github/CODEOWNERS vendored
View File

@@ -1,21 +0,0 @@
# Order is important. The LAST matching pattern has the MOST precedence.
# gitignore style patterns are used, not globs.
# https://help.github.com/articles/about-codeowners
# https://git-scm.com/docs/gitignore
# Everything that falls through the cracks:
* @electron/reviewers
# filename patterns
*browser_view* @electron/browserview
*notification* @electron/notifications
*pdf* @electron/printing
*printing* @electron/printing
*updater* @electron/updater
# directories
/.github/ @electron/electrocats
/default_app/ @electron/docs
/docs/ @electron/docs
/docs-translations/ @electron/i18n
/npm/ @electron/electrocats

View File

@@ -1,32 +0,0 @@
---
name: Bug report
about: Create a report to help us improve Electron
---
* Electron Version:
* Operating System (Platform and Version):
* Last known working Electron version:
**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 a 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.
**Additional Information**
Add any other context about the problem here.

View File

@@ -1,17 +0,0 @@
---
name: Feature request
about: Suggest an idea for Electron
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is.
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.

View File

@@ -1,15 +0,0 @@
<!--
Thank you for your Pull Request. Please provide a description above and review
the requirements below.
Contributors guide: https://github.com/electron/electron/blob/master/CONTRIBUTING.md
-->
##### Checklist
<!-- Remove items that do not apply. For completed items, change [ ] to [x]. -->
- [ ] PR description included and stakeholders cc'd
- [ ] `npm test` passes
- [ ] tests are [changed or added](https://github.com/electron/electron/blob/master/docs/development/testing.md)
- [ ] relevant documentation is changed or added
- [ ] commit messages or PR title follow semantic [commit guidelines](https://github.com/electron/electron/blob/master/docs/development/pull-requests.md#commit-message-guidelines)

53
.github/config.yml vendored
View File

@@ -1,53 +0,0 @@
# 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! 💖
We use [semantic commit messages](https://github.com/electron/electron/blob/master/docs/development/pull-requests.md#commit-message-guidelines) to streamline the release process. Before your pull request can be merged, you should **update your pull request title** to start with a semantic prefix, OR prefix at least one of your commit messages.
Examples of commit messages with semantic prefixes:
- `fix: don't overwrite prevent_default if default wasn't prevented`
- `feat: add app.isPackaged() method`
- `docs: app.isDefaultProtocolClient is now available on Linux`
Things that will help get your PR across the finish line:
- Follow the JavaScript, C++, and Python [coding style](https://github.com/electron/electron/blob/master/docs/development/coding-style.md).
- Run `npm run lint` locally to catch formatting errors earlier.
- Document any user-facing changes you've made following the [documentation styleguide](https://github.com/electron/electron/blob/master/docs/styleguide.md).
- Include tests when adding/changing behavior.
- Include screenshots and animated GIFs whenever possible.
We get a lot of pull requests on this repo, so please be patient and we will get back to you as soon as we can.
# Configuration for first-pr-merge - https://github.com/behaviorbot/first-pr-merge
# Comment to be posted to on pull requests merged by a first time user
firstPRMergeComment: >
Congrats on merging your first pull request! 🎉🎉🎉
# Configuration for trop - https://github.com/codebytere/trop
watchedProject:
name: Backports
authorizedUsers:
- alexeykuzmin
- ckerr
- codebytere
- deepak1556
- jkleinsc
- MarshallOfSound
- nitsakh
- nornagon
- zcbenz

25
.github/stale.yml vendored
View File

@@ -1,25 +0,0 @@
# Number of days of inactivity before an issue becomes stale
daysUntilStale: 45
# Number of days of inactivity before a stale issue is closed
daysUntilClose: 7
# Issues with these labels will never be considered stale
exemptLabels:
- fixme/bug
- fixme/crash
- fixme/regression
- fixme/security
- blocked
- blocking-stable
- needs-review
# Label to use when marking an issue as stale
staleLabel: stale
# Comment to post when marking an issue as stale. Set to `false` to disable
markComment: >
This issue has been automatically marked as stale because it has not had
recent activity and is not currently prioritized. It will be closed
in a week if no further activity occurs :)
# Comment to post when closing a stale issue. Set to `false` to disable
closeComment: >
If you still think this issue is relevant, please ping a maintainer or
leave a comment!

65
.gitignore vendored
View File

@@ -1,52 +1,29 @@
.DS_Store
.env
.gclient_done
**/.npmrc
.tags*
.vs/
.vscode/
*.log
*.pyc
*.sln
*.swp
*.VC.db
*.VC.VC.opendb
*.vcxproj
*.vcxproj.filters
*.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/
/build/
/dist/
/external_binaries/
/out/
/vendor/.gclient
/vendor/debian_jessie_mips64-sysroot/
/vendor/debian_stretch_amd64-sysroot/
/vendor/debian_stretch_arm-sysroot/
/vendor/debian_stretch_arm64-sysroot/
/vendor/debian_stretch_i386-sysroot/
/vendor/gcc-4.8.3-d197-n64-loongson/
/vendor/readme-gcc483-loongson.txt
/vendor/download/
/vendor/llvm-build/
/vendor/llvm/
/vendor/npm/
/vendor/brightray/vendor/download/
/vendor/debian_wheezy_amd64-sysroot/
/vendor/debian_wheezy_arm-sysroot/
/vendor/debian_wheezy_i386-sysroot/
/vendor/python_26/
/vendor/native_mksnapshot
/vendor/LICENSES.chromium.html
/vendor/npm/
/vendor/llvm/
/vendor/llvm-build/
/vendor/.gclient
node_modules/
SHASUMS256.txt
**/yarn.lock
compile_commands.json
.envrc
# npm package
/npm/dist
/npm/path.txt
*.xcodeproj
*.swp
*.pyc
*.VC.db
*.VC.VC.opendb
.vs/
.vscode/
*.vcxproj
*.vcxproj.user
*.vcxproj.filters
*.sln
*.log

12
.gitmodules vendored
View File

@@ -1,3 +1,6 @@
[submodule "vendor/brightray"]
path = vendor/brightray
url = https://github.com/electron/brightray.git
[submodule "vendor/node"]
path = vendor/node
url = https://github.com/electron/node.git
@@ -7,6 +10,9 @@
[submodule "vendor/breakpad"]
path = vendor/breakpad
url = https://github.com/electron/chromium-breakpad.git
[submodule "vendor/native_mate"]
path = vendor/native_mate
url = https://github.com/electron/native-mate.git
[submodule "vendor/crashpad"]
path = vendor/crashpad
url = https://github.com/electron/crashpad.git
@@ -19,9 +25,3 @@
[submodule "vendor/pdf_viewer"]
path = vendor/pdf_viewer
url = https://github.com/electron/pdf-viewer.git
[submodule "vendor/gyp"]
path = vendor/gyp
url = https://github.com/electron/gyp
[submodule "vendor/libchromiumcontent"]
path = vendor/libchromiumcontent
url = https://github.com/electron/libchromiumcontent

1
.node-version Normal file
View File

@@ -0,0 +1 @@
v7.4.0

View File

@@ -1,6 +0,0 @@
{
"plugins": [
["remark-lint-code-block-style", "fenced"],
["remark-lint-fenced-code-flag"]
]
}

View File

@@ -3,9 +3,6 @@ git:
notifications:
email: false
before_install:
- export BOTO_CONFIG=/dev/null
language: node_js
node_js:
- "4"
@@ -22,8 +19,6 @@ matrix:
env: TARGET_ARCH=arm
- os: linux
env: TARGET_ARCH=ia32
- os: linux
env: TARGET_ARCH=arm64
allow_failures:
- os: osx

592
BUILD.gn
View File

@@ -1,592 +0,0 @@
import("//build/config/locales.gni")
import("//tools/grit/repack.gni")
import("build/asar.gni")
import("build/npm.gni")
if (is_mac) {
import("//build/config/mac/rules.gni")
import("//third_party/icu/config.gni")
import("//v8/gni/v8.gni")
}
if (is_linux) {
import("//build/config/linux/pkg_config.gni")
pkg_config("gio_unix") {
packages = [ "gio-unix-2.0" ]
}
}
declare_args() {
electron_project_name = "electron"
electron_product_name = "Electron"
electron_company_name = "GitHub, Inc"
electron_company_abbr = "github"
electron_version = "0.0.0-dev"
enable_desktop_capturer = true
enable_run_as_node = true
enable_osr = true
# Provide a fake location provider for mocking
# the geolocation responses. Disable it if you
# need to test with chromium's location provider.
# Should not be enabled for release build.
enable_fake_location_provider = !is_official_build
}
filenames_gypi = exec_script(
"//build/gypi_to_gn.py",
[
rebase_path("filenames.gypi"),
"--replace=<(SHARED_INTERMEDIATE_DIR)=$target_gen_dir",
],
"scope",
[ "filenames.gypi" ]
)
config("branding") {
defines = [
"ATOM_PRODUCT_NAME=\"$electron_product_name\"",
"ATOM_PROJECT_NAME=\"$electron_project_name\"",
]
}
config("features") {
defines = []
if (enable_desktop_capturer) {
defines += [ "ENABLE_DESKTOP_CAPTURER=1" ]
}
if (enable_run_as_node) {
defines += [ "ENABLE_RUN_AS_NODE=1" ]
}
if (enable_osr) {
defines += [ "ENABLE_OSR=1" ]
}
}
config("native_mate_config") {
include_dirs = [
"//third_party/native_mate",
]
cflags_cc = [
"-Wno-deprecated-declarations",
]
cflags_objcc = cflags_cc
}
source_set("native_mate") {
deps = [
"//base",
"//net",
"//v8:v8_headers",
"build/node",
]
public_configs = [ ":native_mate_config" ]
sources = [
"//third_party/native_mate/native_mate/arguments.cc",
"//third_party/native_mate/native_mate/arguments.h",
"//third_party/native_mate/native_mate/compat.h",
"//third_party/native_mate/native_mate/constructor.h",
"//third_party/native_mate/native_mate/converter.cc",
"//third_party/native_mate/native_mate/converter.h",
"//third_party/native_mate/native_mate/dictionary.cc",
"//third_party/native_mate/native_mate/dictionary.h",
"//third_party/native_mate/native_mate/function_template.cc",
"//third_party/native_mate/native_mate/function_template.h",
"//third_party/native_mate/native_mate/handle.h",
"//third_party/native_mate/native_mate/object_template_builder.cc",
"//third_party/native_mate/native_mate/object_template_builder.h",
"//third_party/native_mate/native_mate/persistent_dictionary.cc",
"//third_party/native_mate/native_mate/persistent_dictionary.h",
"//third_party/native_mate/native_mate/scoped_persistent.h",
"//third_party/native_mate/native_mate/wrappable.cc",
"//third_party/native_mate/native_mate/wrappable.h",
"//third_party/native_mate/native_mate/wrappable_base.h",
]
}
npm_action("atom_browserify_sandbox") {
deps = [ ":atom_js2c_copy" ]
sandbox_args = [
"lib/sandboxed_renderer/init.js",
"-r", "./lib/sandboxed_renderer/api/exports/electron.js:electron",
"-r", "./lib/sandboxed_renderer/api/exports/fs.js:fs",
"-r", "./lib/sandboxed_renderer/api/exports/os.js:os",
"-r", "./lib/sandboxed_renderer/api/exports/path.js:path",
"-r", "./lib/sandboxed_renderer/api/exports/child_process.js:child_process",
]
inputs = [
"lib/sandboxed_renderer/init.js",
"lib/sandboxed_renderer/api/exports/electron.js",
"lib/sandboxed_renderer/api/exports/fs.js",
"lib/sandboxed_renderer/api/exports/os.js",
"lib/sandboxed_renderer/api/exports/path.js",
"lib/sandboxed_renderer/api/exports/child_process.js",
]
outputs = [ "$target_gen_dir/js2c/preload_bundle.js" ]
script = "browserify"
args = sandbox_args + [
"-o", rebase_path(outputs[0])
]
}
npm_action("atom_browserify_isolated") {
deps = [ ":atom_js2c_copy" ]
inputs = [ "lib/isolated_renderer/init.js" ]
outputs = [ "$target_gen_dir/js2c/isolated_bundle.js" ]
script = "browserify"
args = inputs + [
"-o", rebase_path(outputs[0])
]
}
copy("atom_js2c_copy") {
sources = [
"lib/common/asar.js",
"lib/common/asar_init.js",
]
outputs = [ "$target_gen_dir/js2c/{{source_file_part}}" ]
}
action("atom_js2c") {
deps = [
":atom_js2c_copy",
":atom_browserify_sandbox",
":atom_browserify_isolated",
]
js2c_sources = filenames_gypi.js2c_sources
browserify_sources = [
"$target_gen_dir/js2c/isolated_bundle.js",
"$target_gen_dir/js2c/preload_bundle.js",
]
inputs = js2c_sources + browserify_sources
outputs = [ "$target_gen_dir/atom_natives.h" ]
script = "tools/js2c.py"
args = [
rebase_path("//third_party/electron_node")
] + rebase_path(outputs, root_build_dir) + [
rebase_path("$target_gen_dir/js2c", root_build_dir)
]
}
asar("js2asar") {
sources = filenames_gypi.js_sources
outputs = [ "$root_out_dir/resources/electron.asar" ]
root = "lib"
}
asar("app2asar") {
sources = filenames_gypi.default_app_sources
outputs = [ "$root_out_dir/resources/default_app.asar" ]
root = "default_app"
}
group("electron") {
deps = [ ":electron_lib" ]
}
static_library("electron_lib") {
configs += [
"//v8:external_startup_data",
]
public_configs = [
":branding",
":features",
]
deps = [
"//chrome/common:constants",
"//components/cdm/renderer",
"//components/network_session_configurator/common",
"//components/prefs",
"//components/printing/common",
"//components/security_state/content",
"//content/public/browser",
"//device/geolocation",
"//gin",
"//net:net_resources",
"//ppapi/host",
"//ppapi/proxy",
"//ppapi/shared_impl",
"//printing",
"//services/device/wake_lock/power_save_blocker", # TODO: this requires a visibility patch to chromium src
"//skia",
"//third_party/WebKit/public:blink",
"//third_party/boringssl",
"//third_party/crashpad/crashpad/client",
"//third_party/leveldatabase",
"//third_party/libyuv",
"//third_party/webrtc/modules/desktop_capture",
"//third_party/webrtc/modules/desktop_capture:primitives",
"//ui/events:dom_keycode_converter",
"//ui/views",
"//v8",
":atom_js2c",
":native_mate",
"brightray",
"build/node",
]
if (is_mac) {
deps += [
"//ui/accelerated_widget_mac",
"//base/allocator:features",
]
}
if (is_linux) {
deps += [
"//build/config/linux/gtk3",
"//chrome/browser/ui/libgtkui",
"//device/bluetooth",
"//third_party/breakpad:client",
"//ui/events/devices/x11",
"//ui/events/platform/x11",
"//ui/native_theme",
"//ui/views/controls/webview",
"//ui/wm",
]
configs += [ ":gio_unix" ]
}
defines = [
# This is defined in skia/skia_common.gypi.
"SK_SUPPORT_LEGACY_GETTOPDEVICE",
# Disable warnings for g_settings_list_schemas.
"GLIB_DISABLE_DEPRECATION_WARNINGS",
# Import V8 symbols from shared library (node.dll / libnode.so)
"USING_V8_SHARED",
"USING_V8_PLATFORM_SHARED",
"USING_V8_BASE_SHARED",
# Enables SkBitmap size 64 operations
#"SK_SUPPORT_LEGACY_SAFESIZE64", # doesn't seem to be needed to build?
]
include_dirs = [
"chromium_src",
".",
"$target_gen_dir",
# TODO(nornagon): replace usage of SchemeRegistry by an actually exported
# API of blink, then delete this include dir.
"//third_party/WebKit/Source",
# NOTE(nornagon): other chromium files use the full path to include
# crashpad; this is just here for compatibility between GN and GYP, so that
# the #includes can be agnostic about where crashpad is vendored.
"//third_party/crashpad",
]
if (is_linux) {
include_dirs += [
"//third_party/breakpad",
]
}
extra_source_filters = []
if (!is_linux) {
extra_source_filters += [
"*\bx/*",
"*_x11.h",
"*_x11.cc",
"*_gtk.h",
"*_gtk.cc",
]
}
if (!is_win) {
extra_source_filters += [
"*\bwin_*.h",
"*\bwin_*.cc",
]
}
if (is_mac) {
extra_source_filters += [
"*_views.cc",
"*_views.h",
"*\bviews/*",
"*/autofill_popup.cc",
"*/autofill_popup.h",
]
}
set_sources_assignment_filter(sources_assignment_filter + extra_source_filters)
sources = filenames_gypi.lib_sources
set_sources_assignment_filter(sources_assignment_filter)
if (enable_fake_location_provider) {
defines += [
"OVERRIDE_LOCATION_PROVIDER"
]
sources += filenames_gypi.lib_sources_location_provider
}
if (enable_run_as_node) {
sources += [
"atom/app/node_main.cc",
"atom/app/node_main.h",
]
}
if (enable_osr) {
sources += [
"atom/browser/api/atom_api_web_contents_osr.cc",
"atom/browser/osr/osr_output_device.cc",
"atom/browser/osr/osr_output_device.h",
"atom/browser/osr/osr_render_widget_host_view.cc",
"atom/browser/osr/osr_render_widget_host_view.h",
"atom/browser/osr/osr_render_widget_host_view_mac.mm",
"atom/browser/osr/osr_view_proxy.cc",
"atom/browser/osr/osr_view_proxy.h",
"atom/browser/osr/osr_web_contents_view.cc",
"atom/browser/osr/osr_web_contents_view.h",
"atom/browser/osr/osr_web_contents_view_mac.mm",
]
deps += [
"//ui/compositor",
"//components/viz/service",
]
}
if (enable_desktop_capturer) {
sources += [
"atom/browser/api/atom_api_desktop_capturer.cc",
"atom/browser/api/atom_api_desktop_capturer.h",
]
}
if (is_mac) {
libs = [
"Squirrel.framework",
"ReactiveCocoa.framework",
"Mantle.framework",
]
cflags_objcc = [
"-F", rebase_path("external_binaries", root_build_dir)
]
if (true) { # !is_mas_build
# ReactiveCocoa which is used by Squirrel requires using __weak.
cflags_objcc += [ "-fobjc-weak" ]
}
}
if (is_linux) {
sources += filenames_gypi.lib_sources_linux
sources += filenames_gypi.lib_sources_nss
}
}
if (is_mac) {
electron_framework_name = electron_product_name + " Framework"
electron_helper_name = electron_product_name + " Helper"
electron_framework_version = "A"
electron_mac_bundle_id = "com.$electron_company_abbr.$electron_project_name"
mac_xib_bundle_data("electron_xibs") {
sources = [ "atom/common/resources/mac/MainMenu.xib" ]
}
bundle_data("electron_framework_resources") {
public_deps = [
"//content/shell:pak",
":electron_locales",
]
sources = [
"$root_out_dir/content_shell.pak",
]
if (icu_use_data_file) {
sources += [ "$root_out_dir/icudtl.dat" ]
public_deps += [ "//third_party/icu:icudata" ]
}
if (v8_use_external_startup_data) {
sources += [
"$root_out_dir/natives_blob.bin",
"$root_out_dir/snapshot_blob.bin",
]
public_deps += [ "//v8" ]
}
outputs = [
"{{bundle_resources_dir}}/{{source_file_part}}",
]
}
bundle_data("electron_framework_libraries") {
public_deps = [ "build/node" ]
sources = [
"$root_out_dir/libnode.dylib"
]
outputs = [
"{{bundle_contents_dir}}/Libraries/{{source_file_part}}"
]
}
bundle_data("electron_framework_helpers") {
sources = [
"$root_out_dir/crashpad_handler",
]
outputs = [
"{{bundle_resources_dir}}/{{source_file_part}}",
]
public_deps = [
"//third_party/crashpad/crashpad/handler:crashpad_handler",
]
}
mac_framework_bundle("electron_framework") {
output_name = electron_framework_name
framework_version = electron_framework_version
framework_contents = [ "Resources" ]
public_deps = [ ":electron_lib" ]
deps = [
"//base",
"//base:i18n",
":electron_framework_helpers",
":electron_framework_libraries",
":electron_framework_resources",
":electron_xibs",
]
info_plist = "atom/common/resources/mac/Info.plist"
extra_substitutions = [
"ATOM_BUNDLE_ID=$electron_mac_bundle_id.framework",
]
include_dirs = [
".",
]
sources = filenames_gypi.framework_sources
libs = [
"Carbon.framework",
"QuartzCore.framework",
"Quartz.framework",
"Security.framework",
"SecurityInterface.framework",
"ServiceManagement.framework",
"StoreKit.framework",
]
ldflags = [
"-F", rebase_path("external_binaries", root_build_dir),
"-Wl,-install_name,@rpath/$output_name.framework/$output_name",
"-rpath",
"@loader_path/Libraries",
]
if (is_component_build) {
ldflags += [
"-rpath",
"@executable_path/../../../../../.."
]
}
}
mac_app_bundle("electron_helper_app") {
output_name = electron_helper_name
deps = [ ":electron_framework+link" ]
sources = filenames_gypi.app_sources
include_dirs = [ "." ]
info_plist = "atom/renderer/resources/mac/Info.plist"
extra_substitutions = [
"ATOM_BUNDLE_ID=$electron_mac_bundle_id.helper",
]
ldflags = [
"-rpath",
"@executable_path/../../..",
]
}
bundle_data("electron_app_framework_bundle_data") {
sources = [
"$root_out_dir/$electron_framework_name.framework",
"$root_out_dir/$electron_helper_name.app",
"external_binaries/Squirrel.framework",
"external_binaries/ReactiveCocoa.framework",
"external_binaries/Mantle.framework",
]
outputs = [
"{{bundle_contents_dir}}/Frameworks/{{source_file_part}}",
]
public_deps = [
":electron_framework+link",
":electron_helper_app",
]
}
bundle_data("electron_app_resources") {
public_deps = [
":js2asar",
":app2asar",
]
sources = [
"$root_out_dir/resources/electron.asar",
"$root_out_dir/resources/default_app.asar",
]
outputs = [
"{{bundle_resources_dir}}/{{source_file_part}}"
]
}
repack_locales("electron_locales") {
source_patterns = [
"${root_gen_dir}/content/app/strings/content_strings_",
]
deps = [
"//content/app/strings",
]
input_locales = locales
if (is_mac) {
output_locales = locales_as_mac_outputs
} else {
output_locales = locales
}
if (is_mac) {
output_dir = "$root_gen_dir/repack"
copy_data_to_bundle = true
} else {
output_dir = root_out_dir
}
}
mac_app_bundle("electron_app") {
output_name = electron_product_name
sources = filenames_gypi.app_sources
include_dirs = [ "." ]
deps = [
":electron_app_framework_bundle_data",
":electron_app_resources",
]
info_plist = "atom/browser/resources/mac/Info.plist"
extra_substitutions = [
"ATOM_BUNDLE_ID=$electron_mac_bundle_id",
]
ldflags = [
"-rpath",
"@executable_path/../Frameworks",
]
}
}
if (is_linux) {
executable("electron_app") {
output_name = electron_project_name
sources = filenames_gypi.app_sources
include_dirs = [ "." ]
deps = [
":app2asar",
":electron_lib",
":js2asar",
"//build/config:exe_and_shlib_deps",
"//chrome:packed_resources",
"//content/shell:copy_shell_resources",
"//content/shell:pak",
"//third_party/WebKit/public:image_resources",
"//ui/strings",
]
}
}

View File

@@ -1,4 +1,4 @@
# Contributor Covenant Code of Conduct:
# Contributor Covenant Code of Conduct
## Our Pledge
@@ -34,13 +34,13 @@ This Code of Conduct applies both within project spaces and in public spaces whe
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at [coc@electronjs.org](mailto:coc@electronjs.org). All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at [electron@github.com](mailto:electron@github.com). All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
## Attribution
This Code of Conduct is adapted from the [Contributor-Covenant][homepage], version 1.4, available at [https://contributor-covenant.org/version/1/4][version]
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
[homepage]: https://contributor-covenant.org
[version]: https://contributor-covenant.org/version/1/4/
[homepage]: http://contributor-covenant.org
[version]: http://contributor-covenant.org/version/1/4/

View File

@@ -1,60 +1,79 @@
# Contributing to Electron
:memo: Available Translations: [Korean](https://github.com/electron/electron/tree/master/docs-translations/ko-KR/project/CONTRIBUTING.md) | [Simplified Chinese](https://github.com/electron/electron/tree/master/docs-translations/zh-CN/project/CONTRIBUTING.md) | [Brazilian Portuguese](https://github.com/electron/electron/tree/master/docs-translations/pt-BR/project/CONTRIBUTING.md) | [Dutch](https://github.com/electron/electron/tree/master/docs-translations/nl/project/CONTRIBUTING.md)
:+1::tada: First off, thanks for taking the time to contribute! :tada::+1:
This project adheres to the Contributor Covenant [code of conduct](CODE_OF_CONDUCT.md).
By participating, you are expected to uphold this code. Please report unacceptable
behavior to coc@electronjs.org.
behavior to atom@github.com.
The following is a set of guidelines for contributing to Electron.
These are just guidelines, not rules, use your best judgment and feel free to
propose changes to this document in a pull request.
## [Issues](https://electronjs.org/docs/development/issues)
## Submitting Issues
Issues are created [here](https://github.com/electron/electron/issues/new).
* You can create an issue [here](https://github.com/electron/electron/issues/new),
but before doing that please read the notes below and include as many details as
possible with your report. If you can, please include:
* The version of Electron you are using
* The operating system you are using
* If applicable, what you were doing when the issue arose and what you
expected to happen
* Other things that will help resolve your issue:
* Screenshots and animated GIFs
* Error output that appears in your terminal, dev tools or as an alert
* Perform a [cursory search](https://github.com/electron/electron/issues?utf8=✓&q=is%3Aissue+)
to see if a similar issue has already been submitted
* [How to Contribute in Issues](https://electronjs.org/docs/development/issues#how-to-contribute-in-issues)
* [Asking for General Help](https://electronjs.org/docs/development/issues#asking-for-general-help)
* [Submitting a Bug Report](https://electronjs.org/docs/development/issues#submitting-a-bug-report)
* [Triaging a Bug Report](https://electronjs.org/docs/development/issues#triaging-a-bug-report)
* [Resolving a Bug Report](https://electronjs.org/docs/development/issues#resolving-a-bug-report)
## Submitting Pull Requests
### Issue Maintenance and Closure
* If an issue is inactive for 45 days (no activity of any kind), it will be
marked for closure with `stale`.
* If after this label is applied, no further activity occurs in the next 7 days,
the issue will be closed.
* If an issue has been closed and you still feel it's relevant, feel free to
ping a maintainer or add a comment!
* Include screenshots and animated GIFs in your pull request whenever possible.
* Follow the JavaScript, C++, and Python [coding style defined in docs](/docs/development/coding-style.md).
* Write documentation in [Markdown](https://daringfireball.net/projects/markdown).
See the [Documentation Styleguide](/docs/styleguide.md).
* Use short, present tense commit messages. See [Commit Message Styleguide](#git-commit-messages).
## [Pull Requests](https://electronjs.org/docs/development/pull-requests)
## Styleguides
Pull Requests are the way concrete changes are made to the code, documentation,
dependencies, and tools contained in the `electron/electron` repository.
### General Code
* [Setting up your local environment](https://electronjs.org/docs/development/pull-requests#setting-up-your-local-environment)
* [Step 1: Fork](https://electronjs.org/docs/development/pull-requests#step-1-fork)
* [Step 2: Build](https://electronjs.org/docs/development/pull-requests#step-2-build)
* [Step 3: Branch](https://electronjs.org/docs/development/pull-requests#step-3-branch)
* [The Process of Making Changes](https://electronjs.org/docs/development/pull-requests#the-process-of-making-changes)
* [Step 4: Code](https://electronjs.org/docs/development/pull-requests#step-4-code)
* [Step 5: Commit](https://electronjs.org/docs/development/pull-requests#step-5-commit)
* [Commit message guidelines](https://electronjs.org/docs/development/pull-requests#commit-message-guidelines)
* [Step 6: Rebase](https://electronjs.org/docs/development/pull-requests#step-6-rebase)
* [Step 7: Test](https://electronjs.org/docs/development/pull-requests#step-7-test)
* [Step 8: Push](https://electronjs.org/docs/development/pull-requests#step-8-push)
* [Step 8: Opening the Pull Request](https://electronjs.org/docs/development/pull-requests#step-8-opening-the-pull-request)
* [Step 9: Discuss and Update](#step-9-discuss-and-update)
* [Approval and Request Changes Workflow](https://electronjs.org/docs/development/pull-requests#approval-and-request-changes-workflow)
* [Step 10: Landing](https://electronjs.org/docs/development/pull-requests#step-10-landing)
* [Continuous Integration Testing](https://electronjs.org/docs/development/pull-requests#continuous-integration-testing)
* End files with a newline.
* Place requires in the following order:
* Built in Node Modules (such as `path`)
* Built in Electron Modules (such as `ipc`, `app`)
* Local Modules (using relative paths)
* Place class properties in the following order:
* Class methods and properties (methods starting with a `@`)
* Instance methods and properties
* Avoid platform-dependent code:
* Use `path.join()` to concatenate filenames.
* Use `os.tmpdir()` rather than `/tmp` when you need to reference the
temporary directory.
* Using a plain `return` when returning explicitly at the end of a function.
* Not `return null`, `return undefined`, `null`, or `undefined`
## Style Guides
### Git Commit Messages
See [Coding Style](https://electronjs.org/docs/development/coding-style) for information about which standards Electron adheres to in different parts of its codebase.
## Further Reading
For more in-depth guides on developing Electron, see
[/docs/development](/docs/development/README.md)
* Use the present tense ("Add feature" not "Added feature")
* Use the imperative mood ("Move cursor to..." not "Moves cursor to...")
* Limit the first line to 72 characters or less
* Reference issues and pull requests liberally
* When only changing documentation, include `[ci skip]` in the commit description
* Consider starting the commit message with an applicable emoji:
* :art: `:art:` when improving the format/structure of the code
* :racehorse: `:racehorse:` when improving performance
* :non-potable_water: `:non-potable_water:` when plugging memory leaks
* :memo: `:memo:` when writing docs
* :penguin: `:penguin:` when fixing something on Linux
* :apple: `:apple:` when fixing something on macOS
* :checkered_flag: `:checkered_flag:` when fixing something on Windows
* :bug: `:bug:` when fixing a bug
* :fire: `:fire:` when removing code or files
* :green_heart: `:green_heart:` when fixing the CI build
* :white_check_mark: `:white_check_mark:` when adding tests
* :lock: `:lock:` when dealing with security
* :arrow_up: `:arrow_up:` when upgrading dependencies
* :arrow_down: `:arrow_down:` when downgrading dependencies
* :shirt: `:shirt:` when removing linter warnings

73
DEPS
View File

@@ -1,73 +0,0 @@
vars = {
'chromium_version':
'63.0.3239.150',
'libchromiumcontent_revision':
'dc2e7ebd2867d4329ebe7b6849e89cf3dc0afa8e',
'node_version':
'v9.7.0-33-g538a5023af',
'native_mate_revision':
'4cd7d113915de0cc08e9a218be35bff9c7361906',
'chromium_git':
'https://chromium.googlesource.com',
'electron_git':
'https://github.com/electron',
}
deps = {
'src':
(Var("chromium_git")) + '/chromium/src.git@' + (Var("chromium_version")),
'src/libchromiumcontent':
(Var("electron_git")) + '/libchromiumcontent.git@' + (Var("libchromiumcontent_revision")),
'src/third_party/electron_node':
(Var("electron_git")) + '/node.git@' + (Var("node_version")),
'src/third_party/native_mate':
(Var("electron_git")) + '/native-mate.git@' + (Var("native_mate_revision")),
}
hooks = [
{
'action': [
'src/libchromiumcontent/script/apply-patches'
],
'pattern':
'src/libchromiumcontent',
'name':
'patch_chromium'
},
{
'action': [
'src/electron/script/update-external-binaries.py'
],
'pattern':
'src/electron/script/update-external-binaries.py',
'name':
'electron_external_binaries'
},
{
'action': [
'bash',
'-c',
# NOTE(nornagon): this ridiculous {{}} stuff is because these strings get
# variable-substituted twice by gclient.
'echo -e "#\\n{{{{\'variables\':{{{{}}}}}}}}" > src/third_party/electron_node/config.gypi',
],
'pattern': 'src/third_party/electron_node',
'name': 'touch_node_config_gypi'
},
{
'action': [
'bash',
'-c',
'cd src/electron; npm install',
],
'pattern': 'src/electron/package.json',
'name': 'electron_npm_deps'
},
]
recursedeps = [
'src',
'src/libchromiumcontent',
]

View File

@@ -1,24 +0,0 @@
FROM electronbuilds/libchromiumcontent:0.0.4
USER root
# Set up HOME directory
ENV HOME=/home
RUN chmod a+rwx /home
# Install node.js
RUN curl -sL https://deb.nodesource.com/setup_10.x | bash -
RUN apt-get install -y nodejs
# Install wget used by crash reporter
RUN apt-get install -y wget
# Install python-dbusmock
RUN apt-get install -y python-dbusmock
# Install libnotify
RUN apt-get install -y libnotify-bin
# Add xvfb init script
ADD tools/xvfb-init.sh /etc/init.d/xvfb
RUN chmod a+x /etc/init.d/xvfb

View File

@@ -1,35 +0,0 @@
FROM multiarch/debian-debootstrap:arm64-jessie
RUN apt-get update && apt-get install -y\
bison \
build-essential \
clang \
curl \
gperf \
libasound2 \
libasound2-dev \
libcap-dev \
libcups2-dev \
libdbus-1-dev \
libgconf-2-4 \
libgconf2-dev \
libgnome-keyring-dev \
libgtk-3-0 \
libgtk-3-dev \
libnotify-bin \
libnotify-dev \
libnss3 \
libnss3-dev \
libx11-xcb-dev \
libxss1 \
libxtst-dev \
libxtst6 \
python-dbusmock \
wget \
xvfb
ADD tools/xvfb-init.sh /etc/init.d/xvfb
RUN chmod a+x /etc/init.d/xvfb
ADD tools/run-electron.sh /run-electron.sh
RUN chmod a+x /run-electron.sh
CMD sh /run-electron.sh

View File

@@ -1,63 +0,0 @@
FROM arm64v8/ubuntu:16.04
RUN groupadd --gid 1000 builduser \
&& useradd --uid 1000 --gid builduser --shell /bin/bash --create-home builduser
RUN groupadd --gid 114 jenkins \
&& useradd --uid 110 --gid jenkins --shell /bin/bash --create-home jenkins
# Set up TEMP directory
ENV TEMP=/tmp
RUN chmod a+rwx /tmp
RUN apt-get update && apt-get install -y\
bison \
build-essential \
clang \
curl \
gperf \
git \
libasound2 \
libasound2-dev \
libcap-dev \
libcups2-dev \
libdbus-1-dev \
libgconf-2-4 \
libgconf2-dev \
libgnome-keyring-dev \
libgtk2.0-0 \
libgtk2.0-dev \
libgtk-3-0 \
libgtk-3-dev \
libnotify-dev \
libnss3 \
libnss3-dev \
libx11-xcb-dev \
libxss1 \
libxtst-dev \
libxtst6 \
lsb-release \
locales \
ninja \
python-setuptools \
python-pip \
python-dbusmock \
wget \
xvfb
# Install node.js
RUN curl -sL https://deb.nodesource.com/setup_8.x | bash -
RUN apt-get update && apt-get install -y nodejs
# Install crcmod
RUN pip install -U crcmod
ADD tools/xvfb-init.sh /etc/init.d/xvfb
RUN chmod a+x /etc/init.d/xvfb
# Install ninja in /usr/local
RUN cd /usr/local && git clone https://github.com/martine/ninja.git -b v1.5.3
RUN cd /usr/local/ninja && ./configure.py --bootstrap
USER builduser
WORKDIR /home/builduser

View File

@@ -1,36 +0,0 @@
FROM multiarch/debian-debootstrap:armhf-jessie
RUN apt-get update && apt-get install -y\
bison \
build-essential \
clang \
curl \
gperf \
libasound2 \
libasound2-dev \
libcap-dev \
libcups2-dev \
libdbus-1-dev \
libgconf-2-4 \
libgconf2-dev \
libgnome-keyring-dev \
libgtk-3-0 \
libgtk-3-dev \
libnotify-bin \
libnotify-dev \
libnss3 \
libnss3-dev \
libx11-xcb-dev \
libxss1 \
libxtst-dev \
libxtst6 \
python-dbusmock \
git \
wget \
xvfb
ADD tools/xvfb-init.sh /etc/init.d/xvfb
RUN chmod a+x /etc/init.d/xvfb
ADD tools/run-electron.sh /run-electron.sh
RUN chmod a+x /run-electron.sh
CMD sh /run-electron.sh

View File

@@ -1,23 +0,0 @@
FROM electronbuilds/libchromiumcontent:0.0.4
USER root
# Install node.js
RUN curl -sL https://deb.nodesource.com/setup_10.x | bash -
RUN apt-get install -y nodejs
# Install wget used by crash reporter
RUN apt-get install -y wget
# Install python-dbusmock
RUN apt-get install -y python-dbusmock
# Install libnotify
RUN apt-get install -y libnotify-bin
# Add xvfb init script
ADD tools/xvfb-init.sh /etc/init.d/xvfb
RUN chmod a+x /etc/init.d/xvfb
USER builduser
WORKDIR /home/builduser

View File

@@ -10,9 +10,6 @@ Thanks for opening an issue! A few things to keep in mind:
* Electron version:
* Operating system:
<!-- If this used to work -->
* Last known working Electron version:
### Expected behavior
<!-- What do you think should happen? -->

View File

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

121
README.md
View File

@@ -1,95 +1,86 @@
[![Electron Logo](https://electronjs.org/images/electron-logo.svg)](https://electronjs.org)
[![Electron Logo](https://electron.atom.io/images/electron-logo.svg)](https://electron.atom.io/)
[![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://windows-ci.electronjs.org/api/projects/status/nilyf07hcef14dvj/branch/master?svg=true)](https://windows-ci.electronjs.org/project/AppVeyor/electron/branch/master)
[![Travis Build Status](https://travis-ci.org/electron/electron.svg?branch=master)](https://travis-ci.org/electron/electron)
[![AppVeyor Build Status](https://ci.appveyor.com/api/projects/status/bc56v83355fi3369/branch/master?svg=true)](https://ci.appveyor.com/project/electron-bot/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/)
[![Join the Electron Community on Slack](http://atom-slack.herokuapp.com/badge.svg)](http://atom-slack.herokuapp.com/)
:memo: Available Translations: 🇨🇳 🇹🇼 🇧🇷 🇪🇸 🇰🇷 🇯🇵 🇷🇺 🇫🇷 🇹🇭 🇳🇱 🇹🇷 🇮🇩 🇺🇦 🇨🇿 🇮🇹.
View these docs in other languages at [electron/i18n](https://github.com/electron/i18n/tree/master/content/).
:memo: Available Translations: [Korean](https://github.com/electron/electron/tree/master/docs-translations/ko-KR/project/README.md) | [Simplified Chinese](https://github.com/electron/electron/tree/master/docs-translations/zh-CN/project/README.md) | [Brazilian Portuguese](https://github.com/electron/electron/tree/master/docs-translations/pt-BR/project/README.md) | [Traditional Chinese](https://github.com/electron/electron/tree/master/docs-translations/zh-TW/project/README.md) | [Spanish](https://github.com/electron/electron/tree/master/docs-translations/es/project/README.md) | [Turkish](https://github.com/electron/electron/tree/master/docs-translations/tr-TR/project/README.md)
The Electron framework lets you write cross-platform desktop applications
using JavaScript, HTML and CSS. It is based on [Node.js](https://nodejs.org/) and
[Chromium](https://www.chromium.org) and is used by the [Atom
editor](https://github.com/atom/atom) and many other [apps](https://electronjs.org/apps).
[Chromium](http://www.chromium.org) and is used by the [Atom
editor](https://github.com/atom/atom) and many other [apps](https://electron.atom.io/apps).
Follow [@ElectronJS](https://twitter.com/electronjs) on Twitter for important
announcements.
This project adheres to the Contributor Covenant
[code of conduct](https://github.com/electron/electron/tree/master/CODE_OF_CONDUCT.md).
This project adheres to the Contributor Covenant [code of conduct](CODE_OF_CONDUCT.md).
By participating, you are expected to uphold this code. Please report unacceptable
behavior to [coc@electronjs.org](mailto:coc@electronjs.org).
behavior to electron@github.com.
## Installation
## Downloads
To install prebuilt Electron binaries, use [`npm`](https://docs.npmjs.com/).
The preferred method is to install Electron as a development dependency in your
app:
To install prebuilt Electron binaries, use
[`npm`](https://docs.npmjs.com/):
```sh
npm install electron --save-dev [--save-exact]
# Install as a development dependency
npm install electron --save-dev
# Install the `electron` command globally in your $PATH
npm install electron -g
```
The `--save-exact` flag is recommended for Electron prior to version 2, as it does not follow semantic
versioning. As of version 2.0.0, Electron follows semver, so you don't need `--save-exact` flag. For info on how to manage Electron versions in your apps, see
[Electron versioning](docs/tutorial/electron-versioning.md).
For more installation options and troubleshooting tips, see
[installation](docs/tutorial/installation.md).
## Quick start
Clone and run the
[electron/electron-quick-start](https://github.com/electron/electron-quick-start)
repository to see a minimal Electron app in action:
```sh
git clone https://github.com/electron/electron-quick-start
cd electron-quick-start
npm install
npm start
```
## Resources for learning Electron
- [electronjs.org/docs](https://electronjs.org/docs) - all of Electron's documentation
- [electron/electron-quick-start](https://github.com/electron/electron-quick-start) - a very basic starter Electron app
- [electronjs.org/community#boilerplates](https://electronjs.org/community#boilerplates) - sample starter apps created by the community
- [electron/simple-samples](https://github.com/electron/simple-samples) - small applications with ideas for taking them further
- [electron/electron-api-demos](https://github.com/electron/electron-api-demos) - an Electron app that teaches you how to use Electron
- [hokein/electron-sample-apps](https://github.com/hokein/electron-sample-apps) - small demo apps for the various Electron APIs
## Programmatic usage
Most people use Electron from the command line, but if you require `electron` inside
your **Node app** (not your Electron app) it will return the file path to the
binary. Use this to spawn Electron from Node scripts:
```javascript
const electron = require('electron')
const proc = require('child_process')
// will print something similar to /Users/maf/.../Electron
console.log(electron)
// spawn Electron
const child = proc.spawn(electron)
```
See the [releases page](https://github.com/electron/electron/releases) for
prebuilt binaries, debug symbols, and more.
### Mirrors
- [China](https://npm.taobao.org/mirrors/electron)
## Documentation
Guides and the API reference are located in the
[docs](https://github.com/electron/electron/tree/master/docs) directory. It also
contains documents describing how to build and contribute to Electron.
## Documentation Translations
Find documentation translations in [electron/i18n](https://github.com/electron/i18n).
- [Brazilian Portuguese](https://github.com/electron/electron/tree/master/docs-translations/pt-BR)
- [Korean](https://github.com/electron/electron/tree/master/docs-translations/ko-KR)
- [Japanese](https://github.com/electron/electron/tree/master/docs-translations/jp)
- [Spanish](https://github.com/electron/electron/tree/master/docs-translations/es)
- [Simplified Chinese](https://github.com/electron/electron/tree/master/docs-translations/zh-CN)
- [Traditional Chinese](https://github.com/electron/electron/tree/master/docs-translations/zh-TW)
- [Turkish](https://github.com/electron/electron/tree/master/docs-translations/tr-TR)
- [Thai](https://github.com/electron/electron/tree/master/docs-Translations/th-TH)
- [Ukrainian](https://github.com/electron/electron/tree/master/docs-translations/uk-UA)
- [Russian](https://github.com/electron/electron/tree/master/docs-translations/ru-RU)
- [French](https://github.com/electron/electron/tree/master/docs-translations/fr-FR)
## Quick Start
Clone and run the [`electron/electron-quick-start`](https://github.com/electron/electron-quick-start)
repository to see a minimal Electron app in action.
## Community
Info on reporting bugs, getting help, finding third-party tools and sample apps,
and more can be found in the [support document](docs/tutorial/support.md#finding-support).
You can ask questions and interact with the community in the following
locations:
- [`electron`](http://discuss.atom.io/c/electron) category on the Atom
forums
- `#atom-shell` channel on Freenode
- [`Atom`](http://atom-slack.herokuapp.com/) channel on Slack
- [`electron-ru`](https://telegram.me/electron_ru) *(Russian)*
- [`electron-br`](https://electron-br.slack.com) *(Brazilian Portuguese)*
- [`electron-kr`](http://www.meetup.com/electron-kr/) *(Korean)*
- [`electron-jp`](https://electron-jp.slack.com) *(Japanese)*
- [`electron-tr`](http://electron-tr.herokuapp.com) *(Turkish)*
- [`electron-id`](https://electron-id.slack.com) *(Indonesia)*
Check out [awesome-electron](https://github.com/sindresorhus/awesome-electron)
for a community maintained list of useful example apps, tools and resources.
## License

View File

@@ -2,11 +2,8 @@
The Electron team and community take security bugs in Electron seriously. We appreciate your efforts to responsibly disclose your findings, and will make every effort to acknowledge your contributions.
To report a security issue, email [security@electronjs.org](mailto:security@electronjs.org) and include the word "SECURITY" in the subject line.
To report a security issue, email [electron@github.com](mailto:electron@github.com) and include the word "SECURITY" in the subject line.
The Electron team will send a response indicating the next steps in handling your report. After the initial reply to your report, the security team will keep you informed of the progress towards a fix and full announcement, and may ask for additional information or guidance.
Report security bugs in third-party modules to the person or team maintaining the module. You can also report a vulnerability through the [Node Security Project](https://nodesecurity.io/report).
## Learning More About Security
To learn more about securing an Electron application, please see the [security tutorial](docs/tutorial/security.md).

View File

@@ -1,71 +0,0 @@
build_cloud: electron-16
image: electron-16-vs2017-15.4.5
build_script:
- ps: >-
echo "Build worker image $env:APPVEYOR_BUILD_WORKER_IMAGE"
&"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe"
if(($env:APPVEYOR_PULL_REQUEST_HEAD_REPO_NAME -split "/")[0] -eq ($env:APPVEYOR_REPO_NAME -split "/")[0]) {
Write-warning "Skipping PR build for branch"; Exit-AppveyorBuild
} else {
Add-Path "$env:ProgramFiles (x86)\Windows Kits\10\Debuggers\x64"
$env:path = "$env:ProgramFiles (x86)\Windows Kits\10\Debuggers\x64;$env:path"
if($env:APPVEYOR_SCHEDULED_BUILD -eq 'True') {
$env:RUN_RELEASE_BUILD = "1"
}
$Message = (git log --format=%B -n 1 HEAD) | Out-String
if ((Test-Path Env:\RUN_RELEASE_BUILD)) {
$env:ELECTRON_RELEASE = '1'
Write-Output "release build triggered from api"
}
if ((Test-Path Env:\ELECTRON_RELEASE)) {
Write-Output "Running release build"
python script\bootstrap.py --target_arch=$env:TARGET_ARCH
python script\build.py -c R
python script\create-dist.py
} else {
Write-Output "Running debug build"
python script\bootstrap.py --target_arch=$env:TARGET_ARCH --dev
python script\build.py -c D
}
if ($? -ne 'True') {
throw "Build failed with exit code $?"
} else {
"Build succeeded."
}
Push-AppveyorArtifact out
}
test_script:
- ps: >-
if (Test-Path Env:\ELECTRON_RELEASE) {
Write-Output "Skipping tests for release build"
} else {
Write-Output "Running tests for debug build"
python script\test.py --ci --rebuild_native_modules
if ($LASTEXITCODE -ne '0') {
throw "Tests failed with exit code $LASTEXITCODE"
} else {
Write-Output "Tests succeeded."
}
python script\verify-ffmpeg.py
if ($LASTEXITCODE -ne '0') {
throw "Verify ffmpeg failed with exit code $LASTEXITCODE"
} else {
"Verify ffmpeg succeeded."
}
}
artifacts:
- path: test-results.xml
name: test-results.xml
deploy_script:
- ps: >-
if (Test-Path Env:\ELECTRON_RELEASE) {
if (Test-Path Env:\RUN_RELEASE_BUILD) {
Write-Output "Uploading Electron release distribution to s3"
& python script\upload.py --upload_to_s3
} else {
Write-Output "Uploading Electron release distribution to github releases"
& python script\upload.py
}
}

25
appveyor.yml Normal file
View File

@@ -0,0 +1,25 @@
# appveyor file
# http://www.appveyor.com/docs/appveyor-yml
version: "{build}"
os: Visual Studio 2015
init:
- git config --global core.autocrlf input
platform:
- x86
- x64
install:
- cmd: SET PATH=C:\Program Files (x86)\MSBuild\14.0\bin\;%PATH%
- cmd: SET PATH=C:\python27;%PATH%
- cmd: python script/cibuild
branches:
only:
- master
# disable build and test pahses
build: off
test: off

1
atom/CPPLINT.cfg Normal file
View File

@@ -0,0 +1 @@
filter=+build/include_alpha

View File

@@ -7,6 +7,7 @@
#include <string>
#include <vector>
#include "atom/common/atom_constants.h"
#include "atom/common/atom_version.h"
#include "atom/common/chrome_version.h"
#include "atom/common/options_switches.h"
@@ -18,20 +19,16 @@
#include "content/public/common/content_constants.h"
#include "content/public/common/pepper_plugin_info.h"
#include "content/public/common/user_agent.h"
#include "media/media_features.h"
#include "pdf/pdf.h"
#include "ppapi/shared_impl/ppapi_permissions.h"
#include "third_party/widevine/cdm/stub/widevine_cdm_version.h"
#include "ui/base/l10n/l10n_util.h"
#include "url/url_constants.h"
#if defined(WIDEVINE_CDM_AVAILABLE) && BUILDFLAG(ENABLE_LIBRARY_CDMS)
#if defined(WIDEVINE_CDM_AVAILABLE) && BUILDFLAG(ENABLE_PEPPER_CDMS)
#include "chrome/common/widevine_cdm_constants.h"
#endif
#if defined(ENABLE_PDF_VIEWER)
#include "atom/common/atom_constants.h"
#include "pdf/pdf.h"
#endif // defined(ENABLE_PDF_VIEWER)
namespace atom {
namespace {
@@ -60,43 +57,59 @@ content::PepperPluginInfo CreatePepperFlashInfo(const base::FilePath& path,
flash_version_numbers.push_back("999");
// E.g., "Shockwave Flash 10.2 r154":
plugin.description = plugin.name + " " + flash_version_numbers[0] + "." +
flash_version_numbers[1] + " r" +
flash_version_numbers[2];
flash_version_numbers[1] + " r" + flash_version_numbers[2];
plugin.version = base::JoinString(flash_version_numbers, ".");
content::WebPluginMimeType swf_mime_type(content::kFlashPluginSwfMimeType,
content::kFlashPluginSwfExtension,
content::kFlashPluginSwfDescription);
content::WebPluginMimeType swf_mime_type(
content::kFlashPluginSwfMimeType,
content::kFlashPluginSwfExtension,
content::kFlashPluginSwfDescription);
plugin.mime_types.push_back(swf_mime_type);
content::WebPluginMimeType spl_mime_type(content::kFlashPluginSplMimeType,
content::kFlashPluginSplExtension,
content::kFlashPluginSplDescription);
content::WebPluginMimeType spl_mime_type(
content::kFlashPluginSplMimeType,
content::kFlashPluginSplExtension,
content::kFlashPluginSplDescription);
plugin.mime_types.push_back(spl_mime_type);
return plugin;
}
#if defined(WIDEVINE_CDM_AVAILABLE) && BUILDFLAG(ENABLE_LIBRARY_CDMS)
#if defined(WIDEVINE_CDM_AVAILABLE) && BUILDFLAG(ENABLE_PEPPER_CDMS)
content::PepperPluginInfo CreateWidevineCdmInfo(const base::FilePath& path,
const std::string& version) {
content::PepperPluginInfo widevine_cdm;
widevine_cdm.is_out_of_process = true;
widevine_cdm.path = path;
widevine_cdm.name = kWidevineCdmDisplayName;
widevine_cdm.description =
kWidevineCdmDescription + std::string(" (version: ") + version + ")";
widevine_cdm.description = kWidevineCdmDescription +
std::string(" (version: ") +
version + ")";
widevine_cdm.version = version;
content::WebPluginMimeType widevine_cdm_mime_type(
kWidevineCdmPluginMimeType, kWidevineCdmPluginExtension,
kWidevineCdmPluginMimeType,
kWidevineCdmPluginExtension,
kWidevineCdmPluginMimeTypeDescription);
// Add the supported codecs as if they came from the component manifest.
std::vector<std::string> codecs;
codecs.push_back(kCdmSupportedCodecVp8);
codecs.push_back(kCdmSupportedCodecVp9);
#if defined(USE_PROPRIETARY_CODECS)
codecs.push_back(kCdmSupportedCodecAvc1);
#endif // defined(USE_PROPRIETARY_CODECS)
std::string codec_string = base::JoinString(
codecs, std::string(1, kCdmSupportedCodecsValueDelimiter));
widevine_cdm_mime_type.additional_param_names.push_back(
base::ASCIIToUTF16(kCdmSupportedCodecsParamName));
widevine_cdm_mime_type.additional_param_values.push_back(
base::ASCIIToUTF16(codec_string));
widevine_cdm.mime_types.push_back(widevine_cdm_mime_type);
widevine_cdm.permissions = kWidevineCdmPluginPermissions;
return widevine_cdm;
}
#endif // defined(WIDEVINE_CDM_AVAILABLE) && BUILDFLAG(ENABLE_LIBRARY_CDMS)
#endif
#if defined(ENABLE_PDF_VIEWER)
void ComputeBuiltInPlugins(std::vector<content::PepperPluginInfo>* plugins) {
content::PepperPluginInfo pdf_info;
pdf_info.is_internal = true;
@@ -115,130 +128,111 @@ void ComputeBuiltInPlugins(std::vector<content::PepperPluginInfo>* plugins) {
pdf_info.permissions = ppapi::PERMISSION_PRIVATE | ppapi::PERMISSION_DEV;
plugins->push_back(pdf_info);
}
#endif // defined(ENABLE_PDF_VIEWER)
void ConvertStringWithSeparatorToVector(std::vector<std::string>* vec,
const char* separator,
const char* cmd_switch) {
auto* command_line = base::CommandLine::ForCurrentProcess();
auto command_line = base::CommandLine::ForCurrentProcess();
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);
base::TRIM_WHITESPACE,
base::SPLIT_WANT_NONEMPTY);
}
} // namespace
void AddPepperFlashFromCommandLine(
std::vector<content::PepperPluginInfo>* plugins) {
auto* command_line = base::CommandLine::ForCurrentProcess();
base::FilePath flash_path =
command_line->GetSwitchValuePath(switches::kPpapiFlashPath);
auto command_line = base::CommandLine::ForCurrentProcess();
base::FilePath flash_path = command_line->GetSwitchValuePath(
switches::kPpapiFlashPath);
if (flash_path.empty())
return;
auto flash_version =
command_line->GetSwitchValueASCII(switches::kPpapiFlashVersion);
auto flash_version = command_line->GetSwitchValueASCII(
switches::kPpapiFlashVersion);
plugins->push_back(CreatePepperFlashInfo(flash_path, flash_version));
}
#if defined(WIDEVINE_CDM_AVAILABLE) && BUILDFLAG(ENABLE_LIBRARY_CDMS)
#if defined(WIDEVINE_CDM_AVAILABLE) && BUILDFLAG(ENABLE_PEPPER_CDMS)
void AddWidevineCdmFromCommandLine(
std::vector<content::PepperPluginInfo>* plugins) {
auto* command_line = base::CommandLine::ForCurrentProcess();
base::FilePath widevine_cdm_path =
command_line->GetSwitchValuePath(switches::kWidevineCdmPath);
auto command_line = base::CommandLine::ForCurrentProcess();
base::FilePath widevine_cdm_path = command_line->GetSwitchValuePath(
switches::kWidevineCdmPath);
if (widevine_cdm_path.empty())
return;
if (!base::PathExists(widevine_cdm_path))
return;
auto widevine_cdm_version =
command_line->GetSwitchValueASCII(switches::kWidevineCdmVersion);
auto widevine_cdm_version = command_line->GetSwitchValueASCII(
switches::kWidevineCdmVersion);
if (widevine_cdm_version.empty())
return;
plugins->push_back(
CreateWidevineCdmInfo(widevine_cdm_path, widevine_cdm_version));
plugins->push_back(CreateWidevineCdmInfo(widevine_cdm_path,
widevine_cdm_version));
}
#endif // defined(WIDEVINE_CDM_AVAILABLE) && BUILDFLAG(ENABLE_LIBRARY_CDMS)
#endif
AtomContentClient::AtomContentClient() {}
AtomContentClient::AtomContentClient() {
}
AtomContentClient::~AtomContentClient() {}
AtomContentClient::~AtomContentClient() {
}
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);
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);
}
void AtomContentClient::AddAdditionalSchemes(Schemes* schemes) {
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::AddAdditionalSchemes(
std::vector<url::SchemeWithType>* standard_schemes,
std::vector<url::SchemeWithType>* referrer_schemes,
std::vector<std::string>* savable_schemes) {
standard_schemes->push_back({"chrome-extension", url::SCHEME_WITHOUT_PORT});
}
void AtomContentClient::AddPepperPlugins(
std::vector<content::PepperPluginInfo>* plugins) {
AddPepperFlashFromCommandLine(plugins);
#if defined(WIDEVINE_CDM_AVAILABLE) && BUILDFLAG(ENABLE_LIBRARY_CDMS)
#if defined(WIDEVINE_CDM_AVAILABLE) && BUILDFLAG(ENABLE_PEPPER_CDMS)
AddWidevineCdmFromCommandLine(plugins);
#endif // defined(WIDEVINE_CDM_AVAILABLE) && BUILDFLAG(ENABLE_LIBRARY_CDMS)
#if defined(ENABLE_PDF_VIEWER)
#endif
ComputeBuiltInPlugins(plugins);
#endif // defined(ENABLE_PDF_VIEWER)
}
void AtomContentClient::AddContentDecryptionModules(
std::vector<content::CdmInfo>* cdms,
std::vector<media::CdmHostFilePath>* cdm_host_file_paths) {
#if defined(WIDEVINE_CDM_AVAILABLE) && BUILDFLAG(ENABLE_LIBRARY_CDMS)
auto command_line = base::CommandLine::ForCurrentProcess();
base::FilePath widevine_cdm_path =
command_line->GetSwitchValuePath(switches::kWidevineCdmPath);
if (widevine_cdm_path.empty())
return;
void AtomContentClient::AddServiceWorkerSchemes(
std::set<std::string>* service_worker_schemes) {
std::vector<std::string> schemes;
ConvertStringWithSeparatorToVector(&schemes, ",",
switches::kRegisterServiceWorkerSchemes);
for (const std::string& scheme : schemes)
service_worker_schemes->insert(scheme);
if (!base::PathExists(widevine_cdm_path))
return;
auto widevine_cdm_version =
command_line->GetSwitchValueASCII(switches::kWidevineCdmVersion);
if (widevine_cdm_version.empty())
return;
std::vector<media::VideoCodec> supported_video_codecs;
supported_video_codecs.push_back(media::VideoCodec::kCodecVP8);
supported_video_codecs.push_back(media::VideoCodec::kCodecVP9);
#if BUILDFLAG(USE_PROPRIETARY_CODECS)
supported_video_codecs.push_back(media::VideoCodec::kCodecH264);
#endif // BUILDFLAG(USE_PROPRIETARY_CODECS)
content::CdmRegistry::GetInstance()->RegisterCdm(
content::CdmInfo(kWidevineCdmDisplayName, kWidevineCdmGuid,
base::Version(widevine_cdm_version), widevine_cdm_path,
kWidevineCdmFileSystemId, supported_video_codecs, false,
kWidevineKeySystem, false));
#endif // defined(WIDEVINE_CDM_AVAILABLE) && BUILDFLAG(ENABLE_LIBRARY_CDMS)
service_worker_schemes->insert(url::kFileScheme);
}
void AtomContentClient::AddSecureSchemesAndOrigins(
std::set<std::string>* secure_schemes,
std::set<GURL>* secure_origins) {
std::vector<std::string> schemes;
ConvertStringWithSeparatorToVector(&schemes, ",", switches::kSecureSchemes);
for (const std::string& scheme : schemes)
secure_schemes->insert(scheme);
}
} // namespace atom

View File

@@ -16,19 +16,24 @@ namespace atom {
class AtomContentClient : public brightray::ContentClient {
public:
AtomContentClient();
~AtomContentClient() override;
virtual ~AtomContentClient();
protected:
// content::ContentClient:
std::string GetProduct() const override;
std::string GetUserAgent() const override;
base::string16 GetLocalizedString(int message_id) const override;
void AddAdditionalSchemes(Schemes* schemes) override;
void AddAdditionalSchemes(
std::vector<url::SchemeWithType>* standard_schemes,
std::vector<url::SchemeWithType>* referrer_schemes,
std::vector<std::string>* savable_schemes) override;
void AddPepperPlugins(
std::vector<content::PepperPluginInfo>* plugins) override;
void AddContentDecryptionModules(
std::vector<content::CdmInfo>* cdms,
std::vector<media::CdmHostFilePath>* cdm_host_file_paths) override;
void AddServiceWorkerSchemes(
std::set<std::string>* service_worker_schemes) override;
void AddSecureSchemesAndOrigins(
std::set<std::string>* secure_schemes,
std::set<GURL>* secure_origins) override;
private:
DISALLOW_COPY_AND_ASSIGN(AtomContentClient);

View File

@@ -9,13 +9,11 @@
#if defined(OS_MACOSX)
extern "C" {
__attribute__((visibility("default"))) int AtomMain(int argc, char* argv[]);
__attribute__((visibility("default")))
int AtomMain(int argc, const char* argv[]);
#ifdef ENABLE_RUN_AS_NODE
__attribute__((visibility("default"))) int AtomInitializeICUandStartNode(
int argc,
char* argv[]);
#endif
__attribute__((visibility("default")))
int AtomInitializeICUandStartNode(int argc, char *argv[]);
}
#endif // OS_MACOSX

View File

@@ -14,17 +14,17 @@
#include "brightray/common/mac/main_application_bundle.h"
#include "content/public/app/content_main.h"
int AtomMain(int argc, char* argv[]) {
#if defined(OS_MACOSX)
int AtomMain(int argc, const char* argv[]) {
atom::AtomMainDelegate delegate;
content::ContentMainParams params(&delegate);
params.argc = argc;
params.argv = const_cast<const char**>(argv);
params.argv = argv;
atom::AtomCommandLine::Init(argc, argv);
return content::ContentMain(params);
}
#ifdef ENABLE_RUN_AS_NODE
int AtomInitializeICUandStartNode(int argc, char* argv[]) {
int AtomInitializeICUandStartNode(int argc, char *argv[]) {
base::AtExitManager atexit_manager;
base::mac::ScopedNSAutoreleasePool pool;
base::mac::SetOverrideFrameworkBundlePath(
@@ -35,4 +35,4 @@ int AtomInitializeICUandStartNode(int argc, char* argv[]) {
base::i18n::InitializeICU();
return atom::NodeMain(argc, argv);
}
#endif
#endif // OS_MACOSX

View File

@@ -1,12 +0,0 @@
#import <Cocoa/Cocoa.h>
int main(int argc, char* argv[]) {
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
NSArray* pathComponents = [[[NSBundle mainBundle] bundlePath] pathComponents];
pathComponents = [pathComponents
subarrayWithRange:NSMakeRange(0, [pathComponents count] - 4)];
NSString* path = [NSString pathWithComponents:pathComponents];
[[NSWorkspace sharedWorkspace] launchApplication:path];
[pool drain];
return 0;
}

View File

@@ -4,27 +4,23 @@
#include "atom/app/atom_main.h"
#include <cstdlib>
#include <vector>
#include <stdlib.h>
#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)
#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)
@@ -38,11 +34,8 @@
namespace {
#ifdef ENABLE_RUN_AS_NODE
const char kRunAsNode[] = "ELECTRON_RUN_AS_NODE";
#endif
const char* kRunAsNode = "ELECTRON_RUN_AS_NODE";
#if defined(ENABLE_RUN_AS_NODE) || defined(OS_WIN)
bool IsEnvSet(const char* name) {
#if defined(OS_WIN)
size_t required_size;
@@ -53,95 +46,63 @@ bool IsEnvSet(const char* name) {
return indicator && indicator[0] != '\0';
#endif
}
#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);
int argc = 0;
wchar_t** wargv = ::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 auto 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
#ifdef 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
// Convert argv to to UTF8
char** argv = new char*[argc];
for (int i = 0; i < argc; i++) {
// Compute the size of the required buffer
DWORD size = WideCharToMultiByte(CP_UTF8,
0,
wargv[i],
-1,
NULL,
0,
NULL,
NULL);
if (size == 0) {
// This should never happen.
fprintf(stderr, "Could not convert arguments to utf8.");
exit(1);
}
// Do the actual conversion
argv[i] = new char[size];
DWORD result = WideCharToMultiByte(CP_UTF8,
0,
wargv[i],
-1,
argv[i],
size,
NULL,
NULL);
if (result == 0) {
// This should never happen.
fprintf(stderr, "Could not convert arguments to utf8.");
exit(1);
}
}
#ifdef 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()); });
// Now that argv conversion is done, we can finally start.
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 atom::NodeMain(argc, argv);
} else 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;
@@ -149,37 +110,34 @@ int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE, wchar_t* cmd, int) {
content::ContentMainParams params(&delegate);
params.instance = instance;
params.sandbox_info = &sandbox_info;
atom::AtomCommandLine::Init(arguments.argc, arguments.argv);
atom::AtomCommandLine::Init(argc, argv);
atom::AtomCommandLine::InitW(argc, wargv);
return content::ContentMain(params);
}
#elif defined(OS_LINUX) // defined(OS_WIN)
int main(int argc, char* argv[]) {
#ifdef ENABLE_RUN_AS_NODE
int main(int argc, const char* argv[]) {
if (IsEnvSet(kRunAsNode)) {
base::i18n::InitializeICU();
base::AtExitManager atexit_manager;
return atom::NodeMain(argc, argv);
return atom::NodeMain(argc, const_cast<char**>(argv));
}
#endif
atom::AtomMainDelegate delegate;
content::ContentMainParams params(&delegate);
params.argc = argc;
params.argv = const_cast<const char**>(argv);
params.argv = argv;
atom::AtomCommandLine::Init(argc, argv);
return content::ContentMain(params);
}
#else // defined(OS_LINUX)
int main(int argc, char* argv[]) {
#ifdef ENABLE_RUN_AS_NODE
int main(int argc, const char* argv[]) {
if (IsEnvSet(kRunAsNode)) {
return AtomInitializeICUandStartNode(argc, argv);
return AtomInitializeICUandStartNode(argc, const_cast<char**>(argv));
}
#endif
return AtomMain(argc, argv);
}

View File

@@ -21,19 +21,9 @@
#include "base/logging.h"
#include "chrome/common/chrome_paths.h"
#include "content/public/common/content_switches.h"
#include "ipc/ipc_features.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
namespace atom {
namespace {
@@ -46,23 +36,22 @@ bool IsBrowserProcess(base::CommandLine* cmd) {
}
#if defined(OS_WIN)
void InvalidParameterHandler(const wchar_t*,
const wchar_t*,
const wchar_t*,
unsigned int,
uintptr_t) {
void InvalidParameterHandler(const wchar_t*, const wchar_t*, const wchar_t*,
unsigned int, uintptr_t) {
// noop.
}
#endif
} // namespace
AtomMainDelegate::AtomMainDelegate() {}
AtomMainDelegate::AtomMainDelegate() {
}
AtomMainDelegate::~AtomMainDelegate() {}
AtomMainDelegate::~AtomMainDelegate() {
}
bool AtomMainDelegate::BasicStartupComplete(int* exit_code) {
auto* command_line = base::CommandLine::ForCurrentProcess();
auto command_line = base::CommandLine::ForCurrentProcess();
logging::LoggingSettings settings;
#if defined(OS_WIN)
@@ -79,12 +68,12 @@ bool AtomMainDelegate::BasicStartupComplete(int* exit_code) {
#else
settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG;
#endif // defined(DEBUG)
#else // defined(OS_WIN)
#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();
std::unique_ptr<base::Environment> env(base::Environment::Create());
if (!command_line->HasSwitch(::switches::kEnableLogging) &&
!env->HasVar("ELECTRON_ENABLE_LOGGING")) {
settings.logging_dest = logging::LOG_NONE;
@@ -97,15 +86,9 @@ bool AtomMainDelegate::BasicStartupComplete(int* exit_code) {
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;
#if defined(DEBUG) && defined(OS_LINUX)
enable_stack_dumping = true;
#endif
if (enable_stack_dumping)
base::debug::EnableInProcessStackDumping();
@@ -130,24 +113,26 @@ bool AtomMainDelegate::BasicStartupComplete(int* exit_code) {
void AtomMainDelegate::PreSandboxStartup() {
brightray::MainDelegate::PreSandboxStartup();
auto* command_line = base::CommandLine::ForCurrentProcess();
std::string process_type =
command_line->GetSwitchValueASCII(::switches::kProcessType);
// Set google API key.
std::unique_ptr<base::Environment> env(base::Environment::Create());
if (!env->HasVar("GOOGLE_API_KEY"))
env->SetVar("GOOGLE_API_KEY", GOOGLEAPIS_API_KEY);
auto command_line = base::CommandLine::ForCurrentProcess();
std::string process_type = command_line->GetSwitchValueASCII(
::switches::kProcessType);
// 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(::switches::kNoSandbox);
}
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(::switches::kDisableSetuidSandbox);
} else {
// Disable renderer sandbox for most of node's functions.
command_line->AppendSwitch(::switches::kNoSandbox);
}
// Allow file:// URIs to read other file:// URIs by default.
@@ -165,11 +150,9 @@ content::ContentBrowserClient* AtomMainDelegate::CreateContentBrowserClient() {
}
content::ContentRendererClient*
AtomMainDelegate::CreateContentRendererClient() {
AtomMainDelegate::CreateContentRendererClient() {
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kEnableSandbox) ||
!base::CommandLine::ForCurrentProcess()->HasSwitch(
::switches::kNoSandbox)) {
switches::kEnableSandbox)) {
renderer_client_.reset(new AtomSandboxedRendererClient);
} else {
renderer_client_.reset(new AtomRendererClient);
@@ -205,7 +188,7 @@ bool AtomMainDelegate::DelaySandboxInitialization(
std::unique_ptr<brightray::ContentClient>
AtomMainDelegate::CreateContentClient() {
return std::make_unique<AtomContentClient>();
return std::unique_ptr<brightray::ContentClient>(new AtomContentClient);
}
} // namespace atom

View File

@@ -15,7 +15,7 @@ namespace atom {
class AtomMainDelegate : public brightray::MainDelegate {
public:
AtomMainDelegate();
~AtomMainDelegate() override;
~AtomMainDelegate();
protected:
// content::ContentMainDelegate:
@@ -44,6 +44,7 @@ class AtomMainDelegate : public brightray::MainDelegate {
void SetUpBundleOverrides();
#endif
brightray::ContentClient content_client_;
std::unique_ptr<content::ContentBrowserClient> browser_client_;
std::unique_ptr<content::ContentRendererClient> renderer_client_;
std::unique_ptr<content::ContentUtilityClient> utility_client_;

View File

@@ -4,9 +4,9 @@
#include "atom/app/atom_main_delegate.h"
#include "base/mac/bundle_locations.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/mac/bundle_locations.h"
#include "base/mac/foundation_util.h"
#include "base/mac/scoped_nsautorelease_pool.h"
#include "base/path_service.h"
@@ -20,17 +20,16 @@ namespace atom {
namespace {
base::FilePath GetFrameworksPath() {
return brightray::MainApplicationBundlePath()
.Append("Contents")
.Append("Frameworks");
return brightray::MainApplicationBundlePath().Append("Contents")
.Append("Frameworks");
}
base::FilePath GetHelperAppPath(const base::FilePath& frameworks_path,
const std::string& name) {
return frameworks_path.Append(name + " Helper.app")
.Append("Contents")
.Append("MacOS")
.Append(name + " Helper");
.Append("Contents")
.Append("MacOS")
.Append(name + " Helper");
}
} // namespace
@@ -42,11 +41,11 @@ void AtomMainDelegate::OverrideFrameworkBundlePath() {
void AtomMainDelegate::OverrideChildProcessPath() {
base::FilePath frameworks_path = GetFrameworksPath();
base::FilePath helper_path =
GetHelperAppPath(frameworks_path, ATOM_PRODUCT_NAME);
base::FilePath helper_path = GetHelperAppPath(frameworks_path,
ATOM_PRODUCT_NAME);
if (!base::PathExists(helper_path))
helper_path =
GetHelperAppPath(frameworks_path, brightray::GetApplicationName());
helper_path = GetHelperAppPath(frameworks_path,
brightray::GetApplicationName());
if (!base::PathExists(helper_path))
LOG(FATAL) << "Unable to find helper app";
PathService::Override(content::CHILD_PROCESS_EXE, helper_path);

View File

@@ -1,53 +0,0 @@
// Copyright (c) 2018 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/app/command_line_args.h"
namespace {
bool IsUrlArg(const base::CommandLine::CharType* arg) {
// the first character must be a letter for this to be a URL
auto c = *arg;
if (('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z')) {
for (auto* p = arg + 1; *p; ++p) {
c = *p;
// colon indicates that the argument starts with a URI scheme
if (c == ':') {
// it could also be a Windows filesystem path
if (p == arg + 1)
break;
return true;
}
// white-space before a colon means it's not a URL
if (c == ' ' || (0x9 <= c && c <= 0xD))
break;
}
}
return false;
}
} // namespace
namespace atom {
bool CheckCommandLineArguments(int argc, base::CommandLine::CharType** argv) {
const base::CommandLine::StringType dashdash(2, '-');
bool block_args = false;
for (int i = 0; i < argc; ++i) {
if (argv[i] == dashdash)
break;
if (block_args) {
return false;
} else if (IsUrlArg(argv[i])) {
block_args = true;
}
}
return true;
}
} // namespace atom

View File

@@ -1,16 +0,0 @@
// Copyright (c) 2018 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef ATOM_APP_COMMAND_LINE_ARGS_H_
#define ATOM_APP_COMMAND_LINE_ARGS_H_
#include "base/command_line.h"
namespace atom {
bool CheckCommandLineArguments(int argc, base::CommandLine::CharType** argv);
} // namespace atom
#endif // ATOM_APP_COMMAND_LINE_ARGS_H_

View File

@@ -2,8 +2,6 @@
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifdef ENABLE_RUN_AS_NODE
#include "atom/app/node_main.h"
#include "atom/app/uv_task_runner.h"
@@ -12,10 +10,8 @@
#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_scheduler/task_scheduler.h"
#include "base/threading/thread_task_runner_handle.h"
#include "gin/array_buffer.h"
#include "gin/public/isolate_holder.h"
@@ -26,7 +22,7 @@
namespace atom {
int NodeMain(int argc, char* argv[]) {
int NodeMain(int argc, char *argv[]) {
base::CommandLine::Init(argc, argv);
int exit_code = 1;
@@ -38,34 +34,27 @@ int NodeMain(int argc, char* argv[]) {
base::ThreadTaskRunnerHandle handle(uv_task_runner);
// Initialize feature list.
auto feature_list = std::make_unique<base::FeatureList>();
std::unique_ptr<base::FeatureList> feature_list(new base::FeatureList);
feature_list->InitializeFromCommandLine("", "");
base::FeatureList::SetInstance(std::move(feature_list));
gin::V8Initializer::LoadV8Snapshot(
gin::V8Initializer::V8SnapshotFileType::kWithAdditionalContext);
gin::V8Initializer::LoadV8Snapshot();
gin::V8Initializer::LoadV8Natives();
// V8 requires a task scheduler apparently
base::TaskScheduler::CreateAndStartWithDefaultParams("Electron");
// Initialize gin::IsolateHolder.
JavascriptEnvironment gin_env;
// Explicitly register electron's builtin modules.
NodeBindings::RegisterBuiltinModules();
int exec_argc;
const char** exec_argv;
node::Init(&argc, const_cast<const char**>(argv), &exec_argc, &exec_argv);
node::IsolateData isolate_data(gin_env.isolate(), loop);
node::Environment* env = node::CreateEnvironment(
node::CreateIsolateData(gin_env.isolate(), loop, gin_env.platform()),
gin_env.context(), argc, argv, exec_argc, exec_argv);
&isolate_data, gin_env.context(), argc, argv,
exec_argc, exec_argv);
// Enable support for v8 inspector.
NodeDebugger node_debugger(env);
node_debugger.Start(gin_env.platform());
// Start our custom debugger implementation.
NodeDebugger node_debugger(gin_env.isolate());
if (node_debugger.IsRunning())
env->AssignToContext(v8::Debug::GetDebugContext(gin_env.isolate()));
mate::Dictionary process(gin_env.isolate(), env->process_object());
#if defined(OS_WIN)
@@ -83,7 +72,6 @@ int NodeMain(int argc, char* argv[]) {
bool more;
do {
more = uv_run(env->event_loop(), UV_RUN_ONCE);
gin_env.platform()->DrainBackgroundTasks(env->isolate());
if (more == false) {
node::EmitBeforeExit(env);
@@ -97,24 +85,13 @@ int NodeMain(int argc, char* argv[]) {
exit_code = node::EmitExit(env);
node::RunAtExit(env);
gin_env.platform()->DrainBackgroundTasks(env->isolate());
gin_env.platform()->CancelPendingDelayedTasks(env->isolate());
node::FreeEnvironment(env);
}
// According to "src/gin/shell/gin_main.cc":
//
// 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::TaskScheduler::GetInstance()->Shutdown();
v8::V8::Dispose();
return exit_code;
}
} // namespace atom
#endif // ENABLE_RUN_AS_NODE

View File

@@ -5,14 +5,10 @@
#ifndef ATOM_APP_NODE_MAIN_H_
#define ATOM_APP_NODE_MAIN_H_
#ifdef ENABLE_RUN_AS_NODE
namespace atom {
int NodeMain(int argc, char* argv[]);
int NodeMain(int argc, char *argv[]);
} // namespace atom
#endif // ENABLE_RUN_AS_NODE
#endif // ATOM_APP_NODE_MAIN_H_

View File

@@ -1,16 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleIdentifier</key>
<string>${ATOM_BUNDLE_ID}</string>
<key>CFBundleName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundleExecutable</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>LSBackgroundOnly</key>
<true/>
</dict>
</plist>

View File

@@ -2,15 +2,14 @@
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include <utility>
#include "atom/app/uv_task_runner.h"
#include "base/stl_util.h"
namespace atom {
UvTaskRunner::UvTaskRunner(uv_loop_t* loop) : loop_(loop) {}
UvTaskRunner::UvTaskRunner(uv_loop_t* loop) : loop_(loop) {
}
UvTaskRunner::~UvTaskRunner() {
for (auto& iter : tasks_) {
@@ -19,25 +18,26 @@ UvTaskRunner::~UvTaskRunner() {
}
}
bool UvTaskRunner::PostDelayedTask(const base::Location& from_here,
base::OnceClosure task,
bool UvTaskRunner::PostDelayedTask(const tracked_objects::Location& from_here,
const base::Closure& task,
base::TimeDelta delay) {
auto* timer = new uv_timer_t;
timer->data = this;
uv_timer_init(loop_, timer);
uv_timer_start(timer, UvTaskRunner::OnTimeout, delay.InMilliseconds(), 0);
tasks_[timer] = std::move(task);
tasks_[timer] = task;
return true;
}
bool UvTaskRunner::RunsTasksInCurrentSequence() const {
bool UvTaskRunner::RunsTasksOnCurrentThread() const {
return true;
}
bool UvTaskRunner::PostNonNestableDelayedTask(const base::Location& from_here,
base::OnceClosure task,
base::TimeDelta delay) {
return PostDelayedTask(from_here, std::move(task), delay);
bool UvTaskRunner::PostNonNestableDelayedTask(
const tracked_objects::Location& from_here,
const base::Closure& task,
base::TimeDelta delay) {
return PostDelayedTask(from_here, task, delay);
}
// static
@@ -46,7 +46,7 @@ void UvTaskRunner::OnTimeout(uv_timer_t* timer) {
if (!ContainsKey(self->tasks_, timer))
return;
std::move(self->tasks_[timer]).Run();
self->tasks_[timer].Run();
self->tasks_.erase(timer);
uv_timer_stop(timer);
uv_close(reinterpret_cast<uv_handle_t*>(timer), UvTaskRunner::OnClose);

View File

@@ -8,9 +8,8 @@
#include <map>
#include "base/callback.h"
#include "base/location.h"
#include "base/single_thread_task_runner.h"
#include "uv.h" // NOLINT(build/include)
#include "vendor/node/deps/uv/include/uv.h"
namespace atom {
@@ -18,24 +17,25 @@ namespace atom {
class UvTaskRunner : public base::SingleThreadTaskRunner {
public:
explicit UvTaskRunner(uv_loop_t* loop);
~UvTaskRunner() override;
// base::SingleThreadTaskRunner:
bool PostDelayedTask(const base::Location& from_here,
base::OnceClosure task,
bool PostDelayedTask(const tracked_objects::Location& from_here,
const base::Closure& task,
base::TimeDelta delay) override;
bool RunsTasksInCurrentSequence() const override;
bool PostNonNestableDelayedTask(const base::Location& from_here,
base::OnceClosure task,
base::TimeDelta delay) override;
bool RunsTasksOnCurrentThread() const override;
bool PostNonNestableDelayedTask(
const tracked_objects::Location& from_here,
const base::Closure& task,
base::TimeDelta delay) override;
private:
~UvTaskRunner() override;
static void OnTimeout(uv_timer_t* timer);
static void OnClose(uv_handle_t* handle);
uv_loop_t* loop_;
std::map<uv_timer_t*, base::OnceClosure> tasks_;
std::map<uv_timer_t*, base::Closure> tasks_;
DISALLOW_COPY_AND_ASSIGN(UvTaskRunner);
};

View File

@@ -20,7 +20,6 @@
#include "atom/common/native_mate_converters/gurl_converter.h"
#include "atom/common/native_mate_converters/image_converter.h"
#include "atom/common/native_mate_converters/net_converter.h"
#include "atom/common/native_mate_converters/network_converter.h"
#include "atom/common/native_mate_converters/value_converter.h"
#include "atom/common/node_includes.h"
#include "atom/common/options_switches.h"
@@ -30,25 +29,19 @@
#include "base/files/file_util.h"
#include "base/path_service.h"
#include "base/strings/string_util.h"
#include "base/sys_info.h"
#include "brightray/browser/brightray_paths.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/icon_manager.h"
#include "chrome/common/chrome_paths.h"
#include "content/browser/gpu/compositor_util.h"
#include "content/browser/gpu/gpu_data_manager_impl.h"
#include "content/public/browser/browser_accessibility_state.h"
#include "content/public/browser/browser_child_process_host.h"
#include "content/public/browser/child_process_data.h"
#include "content/public/browser/client_certificate_delegate.h"
#include "content/public/browser/gpu_data_manager.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/common/content_switches.h"
#include "media/audio/audio_manager.h"
#include "native_mate/object_template_builder.h"
#include "net/ssl/client_cert_identity.h"
#include "net/ssl/ssl_cert_request_info.h"
#include "services/network/public/cpp/network_switches.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/gfx/image/image.h"
@@ -57,19 +50,14 @@
#include "base/strings/utf_string_conversions.h"
#endif
#if defined(OS_MACOSX)
#include "atom/browser/ui/cocoa/atom_bundle_mover.h"
#endif
using atom::Browser;
namespace mate {
#if defined(OS_WIN)
template <>
template<>
struct Converter<Browser::UserTask> {
static bool FromV8(v8::Isolate* isolate,
v8::Local<v8::Value> val,
static bool FromV8(v8::Isolate* isolate, v8::Local<v8::Value> val,
Browser::UserTask* out) {
mate::Dictionary dict;
if (!ConvertFromV8(isolate, val, &dict))
@@ -86,14 +74,13 @@ struct Converter<Browser::UserTask> {
}
};
using atom::JumpListCategory;
using atom::JumpListItem;
using atom::JumpListCategory;
using atom::JumpListResult;
template <>
template<>
struct Converter<JumpListItem::Type> {
static bool FromV8(v8::Isolate* isolate,
v8::Local<v8::Value> val,
static bool FromV8(v8::Isolate* isolate, v8::Local<v8::Value> val,
JumpListItem::Type* out) {
std::string item_type;
if (!ConvertFromV8(isolate, val, &item_type))
@@ -131,10 +118,9 @@ struct Converter<JumpListItem::Type> {
}
};
template <>
template<>
struct Converter<JumpListItem> {
static bool FromV8(v8::Isolate* isolate,
v8::Local<v8::Value> val,
static bool FromV8(v8::Isolate* isolate, v8::Local<v8::Value> val,
JumpListItem* out) {
mate::Dictionary dict;
if (!ConvertFromV8(isolate, val, &dict))
@@ -194,10 +180,9 @@ struct Converter<JumpListItem> {
}
};
template <>
template<>
struct Converter<JumpListCategory::Type> {
static bool FromV8(v8::Isolate* isolate,
v8::Local<v8::Value> val,
static bool FromV8(v8::Isolate* isolate, v8::Local<v8::Value> val,
JumpListCategory::Type* out) {
std::string category_type;
if (!ConvertFromV8(isolate, val, &category_type))
@@ -241,10 +226,9 @@ struct Converter<JumpListCategory::Type> {
}
};
template <>
template<>
struct Converter<JumpListCategory> {
static bool FromV8(v8::Isolate* isolate,
v8::Local<v8::Value> val,
static bool FromV8(v8::Isolate* isolate, v8::Local<v8::Value> val,
JumpListCategory* out) {
mate::Dictionary dict;
if (!ConvertFromV8(isolate, val, &dict))
@@ -271,7 +255,7 @@ struct Converter<JumpListCategory> {
};
// static
template <>
template<>
struct Converter<JumpListResult> {
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate, JumpListResult val) {
std::string result_code;
@@ -305,10 +289,9 @@ struct Converter<JumpListResult> {
};
#endif
template <>
template<>
struct Converter<Browser::LoginItemSettings> {
static bool FromV8(v8::Isolate* isolate,
v8::Local<v8::Value> val,
static bool FromV8(v8::Isolate* isolate, v8::Local<v8::Value> val,
Browser::LoginItemSettings* out) {
mate::Dictionary dict;
if (!ConvertFromV8(isolate, val, &dict))
@@ -333,16 +316,15 @@ struct Converter<Browser::LoginItemSettings> {
}
};
template <>
template<>
struct Converter<content::CertificateRequestResultType> {
static bool FromV8(v8::Isolate* isolate,
v8::Local<v8::Value> val,
static bool FromV8(v8::Isolate* isolate, v8::Local<v8::Value> val,
content::CertificateRequestResultType* out) {
bool b;
if (!ConvertFromV8(isolate, val, &b))
return false;
*out = b ? content::CERTIFICATE_REQUEST_RESULT_TYPE_CONTINUE
: content::CERTIFICATE_REQUEST_RESULT_TYPE_CANCEL;
*out = b ? content::CERTIFICATE_REQUEST_RESULT_TYPE_CONTINUE :
content::CERTIFICATE_REQUEST_RESULT_TYPE_CANCEL;
return true;
}
};
@@ -351,16 +333,6 @@ struct Converter<content::CertificateRequestResultType> {
namespace atom {
ProcessMetric::ProcessMetric(int type,
base::ProcessId pid,
std::unique_ptr<base::ProcessMetrics> metrics) {
this->type = type;
this->pid = pid;
this->metrics = std::move(metrics);
}
ProcessMetric::~ProcessMetric() = default;
namespace api {
namespace {
@@ -395,8 +367,6 @@ int GetPathConstant(const std::string& name) {
return brightray::DIR_CACHE;
else if (name == "userCache")
return brightray::DIR_USER_CACHE;
else if (name == "logs")
return brightray::DIR_APP_LOGS;
else if (name == "home")
return base::DIR_HOME;
else if (name == "temp")
@@ -424,9 +394,7 @@ int GetPathConstant(const std::string& name) {
}
bool NotificationCallbackWrapper(
const base::Callback<
void(const base::CommandLine::StringVector& command_line,
const base::FilePath& current_directory)>& callback,
const ProcessSingleton::NotificationCallback& callback,
const base::CommandLine::StringVector& cmd,
const base::FilePath& cwd) {
// Make sure the callback is called after app gets ready.
@@ -436,32 +404,25 @@ bool NotificationCallbackWrapper(
scoped_refptr<base::SingleThreadTaskRunner> task_runner(
base::ThreadTaskRunnerHandle::Get());
task_runner->PostTask(
FROM_HERE, base::BindOnce(base::IgnoreResult(callback), cmd, cwd));
FROM_HERE, base::Bind(base::IgnoreResult(callback), cmd, cwd));
}
// ProcessSingleton needs to know whether current process is quiting.
return !Browser::Get()->is_shutting_down();
}
void GotPrivateKey(std::shared_ptr<content::ClientCertificateDelegate> delegate,
scoped_refptr<net::X509Certificate> cert,
scoped_refptr<net::SSLPrivateKey> private_key) {
delegate->ContinueWithCertificate(cert, private_key);
}
void OnClientCertificateSelected(
v8::Isolate* isolate,
std::shared_ptr<content::ClientCertificateDelegate> delegate,
std::shared_ptr<net::ClientCertIdentityList> identities,
mate::Arguments* args) {
if (args->Length() == 2) {
delegate->ContinueWithCertificate(nullptr, nullptr);
delegate->ContinueWithCertificate(nullptr);
return;
}
v8::Local<v8::Value> val;
args->GetNext(&val);
if (val->IsNull()) {
delegate->ContinueWithCertificate(nullptr, nullptr);
delegate->ContinueWithCertificate(nullptr);
return;
}
@@ -477,17 +438,8 @@ void OnClientCertificateSelected(
auto certs = net::X509Certificate::CreateCertificateListFromBytes(
data.c_str(), data.length(), net::X509Certificate::FORMAT_AUTO);
if (!certs.empty()) {
scoped_refptr<net::X509Certificate> cert(certs[0].get());
for (size_t i = 0; i < identities->size(); ++i) {
if (cert->Equals((*identities)[i]->certificate())) {
net::ClientCertIdentity::SelfOwningAcquirePrivateKey(
std::move((*identities)[i]),
base::Bind(&GotPrivateKey, delegate, std::move(cert)));
break;
}
}
}
if (!certs.empty())
delegate->ContinueWithCertificate(certs[0].get());
}
void PassLoginInformation(scoped_refptr<LoginHandler> login_handler,
@@ -500,25 +452,30 @@ void PassLoginInformation(scoped_refptr<LoginHandler> login_handler,
}
#if defined(USE_NSS_CERTS)
int ImportIntoCertStore(CertificateManagerModel* model,
const base::DictionaryValue& options) {
int ImportIntoCertStore(
CertificateManagerModel* model,
const base::DictionaryValue& options) {
std::string file_data, cert_path;
base::string16 password;
net::ScopedCERTCertificateList imported_certs;
net::CertificateList imported_certs;
int rv = -1;
options.GetString("certificate", &cert_path);
options.GetString("password", &password);
if (!cert_path.empty()) {
if (base::ReadFileToString(base::FilePath(cert_path), &file_data)) {
auto module = model->cert_db()->GetPrivateSlot();
rv = model->ImportFromPKCS12(module.get(), file_data, password, true,
auto module = model->cert_db()->GetPublicModule();
rv = model->ImportFromPKCS12(module,
file_data,
password,
true,
&imported_certs);
if (imported_certs.size() > 1) {
auto it = imported_certs.begin();
++it; // skip first which would be the client certificate.
for (; it != imported_certs.end(); ++it)
rv &= model->SetCertTrust(it->get(), net::CA_CERT,
rv &= model->SetCertTrust(it->get(),
net::CA_CERT,
net::NSSCertDatabase::TRUSTED_SSL);
}
}
@@ -537,7 +494,7 @@ void OnIconDataAvailable(v8::Isolate* isolate,
callback.Run(v8::Null(isolate), *icon);
} else {
v8::Local<v8::String> error_message =
v8::String::NewFromUtf8(isolate, "Failed to get file icon.");
v8::String::NewFromUtf8(isolate, "Failed to get file icon.");
callback.Run(v8::Exception::Error(error_message), gfx::Image());
}
}
@@ -548,32 +505,22 @@ App::App(v8::Isolate* isolate) {
static_cast<AtomBrowserClient*>(AtomBrowserClient::Get())->set_delegate(this);
Browser::Get()->AddObserver(this);
content::GpuDataManager::GetInstance()->AddObserver(this);
base::ProcessId pid = base::GetCurrentProcId();
auto process_metric = std::make_unique<atom::ProcessMetric>(
content::PROCESS_TYPE_BROWSER, pid,
base::ProcessMetrics::CreateCurrentProcessMetrics());
app_metrics_[pid] = std::move(process_metric);
Init(isolate);
}
App::~App() {
static_cast<AtomBrowserClient*>(AtomBrowserClient::Get())
->set_delegate(nullptr);
static_cast<AtomBrowserClient*>(AtomBrowserClient::Get())->set_delegate(
nullptr);
Browser::Get()->RemoveObserver(this);
content::GpuDataManager::GetInstance()->RemoveObserver(this);
content::BrowserChildProcessObserver::Remove(this);
}
void App::OnBeforeQuit(bool* prevent_default) {
if (Emit("before-quit")) {
*prevent_default = true;
}
*prevent_default = Emit("before-quit");
}
void App::OnWillQuit(bool* prevent_default) {
if (Emit("will-quit")) {
*prevent_default = true;
}
*prevent_default = Emit("will-quit");
}
void App::OnWindowAllClosed() {
@@ -591,9 +538,7 @@ void App::OnQuit() {
}
void App::OnOpenFile(bool* prevent_default, const std::string& file_path) {
if (Emit("open-file", file_path)) {
*prevent_default = true;
}
*prevent_default = Emit("open-file", file_path);
}
void App::OnOpenURL(const std::string& url) {
@@ -617,101 +562,57 @@ void App::OnFinishLaunching(const base::DictionaryValue& launch_info) {
Emit("ready", launch_info);
}
void App::OnPreMainMessageLoopRun() {
content::BrowserChildProcessObserver::Add(this);
if (process_singleton_) {
process_singleton_->OnBrowserReady();
}
}
void App::OnAccessibilitySupportChanged() {
Emit("accessibility-support-changed", IsAccessibilitySupportEnabled());
}
#if defined(OS_MACOSX)
void App::OnWillContinueUserActivity(bool* prevent_default,
const std::string& type) {
if (Emit("will-continue-activity", type)) {
*prevent_default = true;
}
}
void App::OnDidFailToContinueUserActivity(const std::string& type,
const std::string& error) {
Emit("continue-activity-error", type, error);
}
void App::OnContinueUserActivity(bool* prevent_default,
const std::string& type,
const base::DictionaryValue& user_info) {
if (Emit("continue-activity", type, user_info)) {
*prevent_default = true;
}
}
void App::OnUserActivityWasContinued(const std::string& type,
const base::DictionaryValue& user_info) {
Emit("activity-was-continued", type, user_info);
}
void App::OnUpdateUserActivityState(bool* prevent_default,
const std::string& type,
const base::DictionaryValue& user_info) {
if (Emit("update-activity-state", type, user_info)) {
*prevent_default = true;
}
}
void App::OnNewWindowForTab() {
Emit("new-window-for-tab");
void App::OnContinueUserActivity(
bool* prevent_default,
const std::string& type,
const base::DictionaryValue& user_info) {
*prevent_default = Emit("continue-activity", type, user_info);
}
#endif
void App::OnLogin(scoped_refptr<LoginHandler> login_handler,
void App::OnLogin(LoginHandler* login_handler,
const base::DictionaryValue& request_details) {
v8::Locker locker(isolate());
v8::HandleScope handle_scope(isolate());
bool prevent_default = false;
content::WebContents* web_contents = login_handler->GetWebContents();
if (web_contents) {
prevent_default = Emit(
"login", WebContents::CreateFrom(isolate(), web_contents),
request_details, login_handler->auth_info(),
base::Bind(&PassLoginInformation, base::RetainedRef(login_handler)));
}
bool prevent_default = Emit(
"login",
WebContents::CreateFrom(isolate(), login_handler->GetWebContents()),
request_details,
login_handler->auth_info(),
base::Bind(&PassLoginInformation, make_scoped_refptr(login_handler)));
// Default behavior is to always cancel the auth.
if (!prevent_default)
login_handler->CancelAuth();
}
bool App::CanCreateWindow(
content::RenderFrameHost* opener,
const GURL& opener_url,
const GURL& opener_top_level_frame_url,
const GURL& source_origin,
content::mojom::WindowContainerType container_type,
void App::OnCreateWindow(
const GURL& target_url,
const content::Referrer& referrer,
const std::string& frame_name,
WindowOpenDisposition disposition,
const blink::mojom::WindowFeatures& features,
const std::vector<std::string>& additional_features,
const scoped_refptr<network::ResourceRequestBody>& body,
bool user_gesture,
bool opener_suppressed,
bool* no_javascript_access) {
const std::vector<std::string>& features,
const scoped_refptr<content::ResourceRequestBodyImpl>& body,
int render_process_id,
int render_frame_id) {
v8::Locker locker(isolate());
v8::HandleScope handle_scope(isolate());
content::RenderFrameHost* rfh =
content::RenderFrameHost::FromID(render_process_id, render_frame_id);
content::WebContents* web_contents =
content::WebContents::FromRenderFrameHost(opener);
content::WebContents::FromRenderFrameHost(rfh);
if (web_contents) {
auto api_web_contents = WebContents::CreateFrom(isolate(), web_contents);
api_web_contents->OnCreateWindow(target_url, referrer, frame_name,
disposition, additional_features, body);
api_web_contents->OnCreateWindow(target_url,
frame_name,
disposition,
features,
body);
}
return false;
}
void App::AllowCertificateError(
@@ -720,15 +621,19 @@ void App::AllowCertificateError(
const net::SSLInfo& ssl_info,
const GURL& request_url,
content::ResourceType resource_type,
bool overridable,
bool strict_enforcement,
bool expired_previous_decision,
const base::Callback<void(content::CertificateRequestResultType)>&
callback) {
v8::Locker locker(isolate());
v8::HandleScope handle_scope(isolate());
bool prevent_default = Emit(
"certificate-error", WebContents::CreateFrom(isolate(), web_contents),
request_url, net::ErrorToString(cert_error), ssl_info.cert, callback);
bool prevent_default = Emit("certificate-error",
WebContents::CreateFrom(isolate(), web_contents),
request_url,
net::ErrorToString(cert_error),
ssl_info.cert,
callback);
// Deny the certificate by default.
if (!prevent_default)
@@ -738,87 +643,27 @@ void App::AllowCertificateError(
void App::SelectClientCertificate(
content::WebContents* web_contents,
net::SSLCertRequestInfo* cert_request_info,
net::ClientCertIdentityList identities,
std::unique_ptr<content::ClientCertificateDelegate> delegate) {
std::shared_ptr<content::ClientCertificateDelegate> shared_delegate(
delegate.release());
// Convert the ClientCertIdentityList to a CertificateList
// to avoid changes in the API.
auto client_certs = net::CertificateList();
for (const std::unique_ptr<net::ClientCertIdentity>& identity : identities)
client_certs.push_back(identity->certificate());
auto shared_identities =
std::make_shared<net::ClientCertIdentityList>(std::move(identities));
std::shared_ptr<content::ClientCertificateDelegate>
shared_delegate(delegate.release());
bool prevent_default =
Emit("select-client-certificate",
WebContents::CreateFrom(isolate(), web_contents),
cert_request_info->host_and_port.ToString(), std::move(client_certs),
base::Bind(&OnClientCertificateSelected, isolate(), shared_delegate,
shared_identities));
cert_request_info->host_and_port.ToString(),
cert_request_info->client_certs,
base::Bind(&OnClientCertificateSelected,
isolate(),
shared_delegate));
// Default to first certificate from the platform store.
if (!prevent_default) {
scoped_refptr<net::X509Certificate> cert =
(*shared_identities)[0]->certificate();
net::ClientCertIdentity::SelfOwningAcquirePrivateKey(
std::move((*shared_identities)[0]),
base::Bind(&GotPrivateKey, shared_delegate, std::move(cert)));
}
if (!prevent_default)
shared_delegate->ContinueWithCertificate(
cert_request_info->client_certs[0].get());
}
void App::OnGpuProcessCrashed(base::TerminationStatus status) {
Emit("gpu-process-crashed",
status == base::TERMINATION_STATUS_PROCESS_WAS_KILLED);
}
void App::BrowserChildProcessLaunchedAndConnected(
const content::ChildProcessData& data) {
ChildProcessLaunched(data.process_type, data.handle);
}
void App::BrowserChildProcessHostDisconnected(
const content::ChildProcessData& data) {
ChildProcessDisconnected(base::GetProcId(data.handle));
}
void App::BrowserChildProcessCrashed(const content::ChildProcessData& data,
int exit_code) {
ChildProcessDisconnected(base::GetProcId(data.handle));
}
void App::BrowserChildProcessKilled(const content::ChildProcessData& data,
int exit_code) {
ChildProcessDisconnected(base::GetProcId(data.handle));
}
void App::RenderProcessReady(content::RenderProcessHost* host) {
ChildProcessLaunched(content::PROCESS_TYPE_RENDERER, host->GetHandle());
}
void App::RenderProcessDisconnected(base::ProcessId host_pid) {
ChildProcessDisconnected(host_pid);
}
void App::ChildProcessLaunched(int process_type, base::ProcessHandle handle) {
auto pid = base::GetProcId(handle);
#if defined(OS_MACOSX)
std::unique_ptr<base::ProcessMetrics> metrics(
base::ProcessMetrics::CreateProcessMetrics(
handle, content::BrowserChildProcessHost::GetPortProvider()));
#else
std::unique_ptr<base::ProcessMetrics> metrics(
base::ProcessMetrics::CreateProcessMetrics(handle));
#endif
app_metrics_[pid] = std::make_unique<atom::ProcessMetric>(process_type, pid,
std::move(metrics));
}
void App::ChildProcessDisconnected(base::ProcessId pid) {
app_metrics_.erase(pid);
status == base::TERMINATION_STATUS_PROCESS_WAS_KILLED);
}
base::FilePath App::GetAppPath() const {
@@ -864,46 +709,32 @@ void App::SetDesktopName(const std::string& desktop_name) {
}
std::string App::GetLocale() {
return g_browser_process->GetApplicationLocale();
return l10n_util::GetApplicationLocale("");
}
void App::OnSecondInstance(const base::CommandLine::StringVector& cmd,
const base::FilePath& cwd) {
Emit("second-instance", cmd, cwd);
}
bool App::HasSingleInstanceLock() const {
bool App::MakeSingleInstance(
const ProcessSingleton::NotificationCallback& callback) {
if (process_singleton_)
return true;
return false;
}
bool App::RequestSingleInstanceLock() {
if (HasSingleInstanceLock())
return true;
return false;
base::FilePath user_dir;
PathService::Get(brightray::DIR_USER_DATA, &user_dir);
auto cb = base::Bind(&App::OnSecondInstance, base::Unretained(this));
process_singleton_.reset(new ProcessSingleton(
user_dir, base::Bind(NotificationCallbackWrapper, cb)));
user_dir, base::Bind(NotificationCallbackWrapper, callback)));
switch (process_singleton_->NotifyOtherProcessOrCreate()) {
case ProcessSingleton::NotifyResult::LOCK_ERROR:
case ProcessSingleton::NotifyResult::PROFILE_IN_USE:
case ProcessSingleton::NotifyResult::PROCESS_NOTIFIED: {
case ProcessSingleton::NotifyResult::PROCESS_NOTIFIED:
process_singleton_.reset();
return false;
}
return true;
case ProcessSingleton::NotifyResult::PROCESS_NONE:
default: // Shouldn't be needed, but VS warns if it is not there.
return true;
return false;
}
}
void App::ReleaseSingleInstanceLock() {
void App::ReleaseSingleInstance() {
if (process_singleton_) {
process_singleton_->Cleanup();
process_singleton_.reset();
@@ -923,7 +754,11 @@ bool App::Relaunch(mate::Arguments* js_args) {
}
if (!override_argv) {
#if defined(OS_WIN)
const relauncher::StringVector& argv = atom::AtomCommandLine::wargv();
#else
const relauncher::StringVector& argv = atom::AtomCommandLine::argv();
#endif
return relauncher::RelaunchApp(argv);
}
@@ -945,40 +780,18 @@ bool App::Relaunch(mate::Arguments* js_args) {
void App::DisableHardwareAcceleration(mate::Arguments* args) {
if (Browser::Get()->is_ready()) {
args->ThrowError(
"app.disableHardwareAcceleration() can only be called "
"before app is ready");
args->ThrowError("app.disableHardwareAcceleration() can only be called "
"before app is ready");
return;
}
content::GpuDataManager::GetInstance()->DisableHardwareAcceleration();
}
void App::DisableDomainBlockingFor3DAPIs(mate::Arguments* args) {
if (Browser::Get()->is_ready()) {
args->ThrowError(
"app.disableDomainBlockingFor3DAPIs() can only be called "
"before app is ready");
return;
}
content::GpuDataManagerImpl::GetInstance()
->DisableDomainBlockingFor3DAPIsForTesting();
}
bool App::IsAccessibilitySupportEnabled() {
auto* ax_state = content::BrowserAccessibilityState::GetInstance();
auto ax_state = content::BrowserAccessibilityState::GetInstance();
return ax_state->IsAccessibleBrowser();
}
void App::SetAccessibilitySupportEnabled(bool enabled) {
auto* ax_state = content::BrowserAccessibilityState::GetInstance();
if (enabled) {
ax_state->OnScreenReaderDetected();
} else {
ax_state->DisableAccessibility();
}
Browser::Get()->OnAccessibilitySupportChanged();
}
Browser::LoginItemSettings App::GetLoginItemSettings(mate::Arguments* args) {
Browser::LoginItemSettings options;
args->GetNext(&options);
@@ -986,15 +799,18 @@ Browser::LoginItemSettings App::GetLoginItemSettings(mate::Arguments* args) {
}
#if defined(USE_NSS_CERTS)
void App::ImportCertificate(const base::DictionaryValue& options,
const net::CompletionCallback& callback) {
void App::ImportCertificate(
const base::DictionaryValue& options,
const net::CompletionCallback& callback) {
auto browser_context = AtomBrowserContext::From("", false);
if (!certificate_manager_model_) {
std::unique_ptr<base::DictionaryValue> copy = options.CreateDeepCopy();
CertificateManagerModel::Create(
browser_context.get(),
base::Bind(&App::OnCertificateManagerModelCreated,
base::Unretained(this), base::Passed(&copy), callback));
base::Unretained(this),
base::Passed(&copy),
callback));
return;
}
@@ -1007,8 +823,8 @@ void App::OnCertificateManagerModelCreated(
const net::CompletionCallback& callback,
std::unique_ptr<CertificateManagerModel> model) {
certificate_manager_model_ = std::move(model);
int rv =
ImportIntoCertStore(certificate_manager_model_.get(), *(options.get()));
int rv = ImportIntoCertStore(certificate_manager_model_.get(),
*(options.get()));
callback.Run(rv);
}
#endif
@@ -1037,7 +853,7 @@ JumpListResult App::SetJumpList(v8::Local<v8::Value> val,
std::vector<JumpListCategory> categories;
bool delete_jump_list = val->IsNull();
if (!delete_jump_list &&
!mate::ConvertFromV8(args->isolate(), val, &categories)) {
!mate::ConvertFromV8(args->isolate(), val, &categories)) {
args->ThrowError("Argument must be null or an array of categories");
return JumpListResult::ARGUMENT_ERROR;
}
@@ -1045,8 +861,9 @@ JumpListResult App::SetJumpList(v8::Local<v8::Value> val,
JumpList jump_list(Browser::Get()->GetAppUserModelID());
if (delete_jump_list) {
return jump_list.Delete() ? JumpListResult::SUCCESS
: JumpListResult::GENERIC_ERROR;
return jump_list.Delete()
? JumpListResult::SUCCESS
: JumpListResult::GENERIC_ERROR;
}
// Start a transaction that updates the JumpList of this application.
@@ -1069,7 +886,8 @@ JumpListResult App::SetJumpList(v8::Local<v8::Value> val,
}
#endif // defined(OS_WIN)
void App::GetFileIcon(const base::FilePath& path, mate::Arguments* args) {
void App::GetFileIcon(const base::FilePath& path,
mate::Arguments* args) {
mate::Dictionary options;
IconLoader::IconSize icon_size;
FileIconCallback callback;
@@ -1092,7 +910,7 @@ void App::GetFileIcon(const base::FilePath& path, mate::Arguments* args) {
return;
}
auto* icon_manager = g_browser_process->GetIconManager();
auto icon_manager = g_browser_process->GetIconManager();
gfx::Image* icon =
icon_manager->LookupIconFromFilepath(normalized_path, icon_size);
if (icon) {
@@ -1105,109 +923,55 @@ void App::GetFileIcon(const base::FilePath& path, mate::Arguments* args) {
}
}
std::vector<mate::Dictionary> App::GetAppMetrics(v8::Isolate* isolate) {
std::vector<mate::Dictionary> App::GetAppMemoryInfo(v8::Isolate* isolate) {
AppIdProcessIterator process_iterator;
auto process_entry = process_iterator.NextProcessEntry();
std::vector<mate::Dictionary> result;
int processor_count = base::SysInfo::NumberOfProcessors();
for (const auto& process_metric : app_metrics_) {
while (process_entry != nullptr) {
int64_t pid = process_entry->pid();
auto process = base::Process::OpenWithExtraPrivileges(pid);
#if defined(OS_MACOSX)
std::unique_ptr<base::ProcessMetrics> metrics(
base::ProcessMetrics::CreateProcessMetrics(
process.Handle(), content::BrowserChildProcessHost::GetPortProvider()));
#else
std::unique_ptr<base::ProcessMetrics> metrics(
base::ProcessMetrics::CreateProcessMetrics(process.Handle()));
#endif
mate::Dictionary pid_dict = mate::Dictionary::CreateEmpty(isolate);
mate::Dictionary memory_dict = mate::Dictionary::CreateEmpty(isolate);
mate::Dictionary cpu_dict = mate::Dictionary::CreateEmpty(isolate);
memory_dict.Set(
"workingSetSize",
static_cast<double>(
process_metric.second->metrics->GetWorkingSetSize() >> 10));
memory_dict.Set(
"peakWorkingSetSize",
static_cast<double>(
process_metric.second->metrics->GetPeakWorkingSetSize() >> 10));
memory_dict.Set("workingSetSize",
static_cast<double>(metrics->GetWorkingSetSize() >> 10));
memory_dict.Set("peakWorkingSetSize",
static_cast<double>(metrics->GetPeakWorkingSetSize() >> 10));
size_t private_bytes, shared_bytes;
if (process_metric.second->metrics->GetMemoryBytes(&private_bytes,
&shared_bytes)) {
if (metrics->GetMemoryBytes(&private_bytes, &shared_bytes)) {
memory_dict.Set("privateBytes", static_cast<double>(private_bytes >> 10));
memory_dict.Set("sharedBytes", static_cast<double>(shared_bytes >> 10));
}
pid_dict.Set("memory", memory_dict);
cpu_dict.Set(
"percentCPUUsage",
process_metric.second->metrics->GetPlatformIndependentCPUUsage() /
processor_count);
#if !defined(OS_WIN)
cpu_dict.Set("idleWakeupsPerSecond",
process_metric.second->metrics->GetIdleWakeupsPerSecond());
#else
// Chrome's underlying process_metrics.cc will throw a non-fatal warning
// that this method isn't implemented on Windows, so set it to 0 instead
// of calling it
cpu_dict.Set("idleWakeupsPerSecond", 0);
#endif
pid_dict.Set("cpu", cpu_dict);
pid_dict.Set("pid", process_metric.second->pid);
pid_dict.Set("type", content::GetProcessTypeNameInEnglish(
process_metric.second->type));
pid_dict.Set("pid", pid);
result.push_back(pid_dict);
process_entry = process_iterator.NextProcessEntry();
}
return result;
}
v8::Local<v8::Value> App::GetGPUFeatureStatus(v8::Isolate* isolate) {
auto status = content::GetFeatureStatus();
base::DictionaryValue temp;
return mate::ConvertToV8(isolate, status ? *status : temp);
}
void App::EnableMixedSandbox(mate::Arguments* args) {
if (Browser::Get()->is_ready()) {
args->ThrowError(
"app.enableMixedSandbox() can only be called "
"before app is ready");
return;
}
auto* command_line = base::CommandLine::ForCurrentProcess();
if (command_line->HasSwitch(::switches::kNoSandbox)) {
#if defined(OS_WIN)
const base::CommandLine::CharType* noSandboxArg = L"--no-sandbox";
#else
const base::CommandLine::CharType* noSandboxArg = "--no-sandbox";
#endif
// Remove the --no-sandbox switch
base::CommandLine::StringVector modified_command_line;
for (auto& arg : command_line->argv()) {
if (arg.compare(noSandboxArg) != 0) {
modified_command_line.push_back(arg);
}
}
command_line->InitFromArgv(modified_command_line);
}
command_line->AppendSwitch(switches::kEnableMixedSandbox);
}
#if defined(OS_MACOSX)
bool App::MoveToApplicationsFolder(mate::Arguments* args) {
return ui::cocoa::AtomBundleMover::Move(args);
}
bool App::IsInApplicationsFolder() {
return ui::cocoa::AtomBundleMover::IsCurrentAppInApplicationsFolder();
}
#endif
// static
mate::Handle<App> App::Create(v8::Isolate* isolate) {
return mate::CreateHandle(isolate, new App(isolate));
}
// static
void App::BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype) {
void App::BuildPrototype(
v8::Isolate* isolate, v8::Local<v8::FunctionTemplate> prototype) {
prototype->SetClassName(mate::StringToV8(isolate, "App"));
auto browser = base::Unretained(Browser::Get());
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
@@ -1243,10 +1007,6 @@ void App::BuildPrototype(v8::Isolate* isolate,
base::Bind(&Browser::SetUserActivity, browser))
.SetMethod("getCurrentActivityType",
base::Bind(&Browser::GetCurrentActivityType, browser))
.SetMethod("invalidateCurrentActivity",
base::Bind(&Browser::InvalidateCurrentActivity, browser))
.SetMethod("updateCurrentActivity",
base::Bind(&Browser::UpdateCurrentActivity, browser))
.SetMethod("setAboutPanelOptions",
base::Bind(&Browser::SetAboutPanelOptions, browser))
#endif
@@ -1268,45 +1028,30 @@ void App::BuildPrototype(v8::Isolate* isolate,
#if defined(USE_NSS_CERTS)
.SetMethod("importCertificate", &App::ImportCertificate)
#endif
.SetMethod("hasSingleInstanceLock", &App::HasSingleInstanceLock)
.SetMethod("requestSingleInstanceLock", &App::RequestSingleInstanceLock)
.SetMethod("releaseSingleInstanceLock", &App::ReleaseSingleInstanceLock)
.SetMethod("makeSingleInstance", &App::MakeSingleInstance)
.SetMethod("releaseSingleInstance", &App::ReleaseSingleInstance)
.SetMethod("relaunch", &App::Relaunch)
.SetMethod("isAccessibilitySupportEnabled",
&App::IsAccessibilitySupportEnabled)
.SetMethod("setAccessibilitySupportEnabled",
&App::SetAccessibilitySupportEnabled)
.SetMethod("disableHardwareAcceleration",
&App::DisableHardwareAcceleration)
.SetMethod("disableDomainBlockingFor3DAPIs",
&App::DisableDomainBlockingFor3DAPIs)
.SetMethod("getFileIcon", &App::GetFileIcon)
.SetMethod("getAppMetrics", &App::GetAppMetrics)
.SetMethod("getGPUFeatureStatus", &App::GetGPUFeatureStatus)
// TODO(juturu): Remove in 2.0, deprecate before then with warnings
#if defined(OS_MACOSX)
.SetMethod("moveToApplicationsFolder", &App::MoveToApplicationsFolder)
.SetMethod("isInApplicationsFolder", &App::IsInApplicationsFolder)
#endif
#if defined(MAS_BUILD)
.SetMethod("startAccessingSecurityScopedResource",
&App::StartAccessingSecurityScopedResource)
#endif
.SetMethod("enableMixedSandbox", &App::EnableMixedSandbox);
.SetMethod("getAppMemoryInfo", &App::GetAppMemoryInfo);
}
} // namespace api
} // namespace atom
namespace {
void AppendSwitch(const std::string& switch_string, mate::Arguments* args) {
auto* command_line = base::CommandLine::ForCurrentProcess();
auto command_line = base::CommandLine::ForCurrentProcess();
if (base::EndsWith(switch_string, "-path",
base::CompareCase::INSENSITIVE_ASCII) ||
switch_string == network::switches::kLogNetLog) {
switch_string == switches::kLogNetLog) {
base::FilePath path;
args->GetNext(&path);
command_line->AppendSwitchPath(switch_string, path);
@@ -1335,19 +1080,18 @@ void DockSetMenu(atom::api::Menu* menu) {
}
#endif
void Initialize(v8::Local<v8::Object> exports,
v8::Local<v8::Value> unused,
v8::Local<v8::Context> context,
void* priv) {
void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
v8::Local<v8::Context> context, void* priv) {
v8::Isolate* isolate = context->GetIsolate();
auto* command_line = base::CommandLine::ForCurrentProcess();
auto command_line = base::CommandLine::ForCurrentProcess();
mate::Dictionary dict(isolate, exports);
dict.Set("App", atom::api::App::GetConstructor(isolate)->GetFunction());
dict.Set("app", atom::api::App::Create(isolate));
dict.SetMethod("appendSwitch", &AppendSwitch);
dict.SetMethod("appendArgument", base::Bind(&base::CommandLine::AppendArg,
base::Unretained(command_line)));
dict.SetMethod("appendArgument",
base::Bind(&base::CommandLine::AppendArg,
base::Unretained(command_line)));
#if defined(OS_MACOSX)
auto browser = base::Unretained(Browser::Get());
dict.SetMethod("dockBounce", &DockBounce);
@@ -1369,4 +1113,4 @@ void Initialize(v8::Local<v8::Object> exports,
} // namespace
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_app, Initialize)
NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_app, Initialize)

View File

@@ -5,9 +5,7 @@
#ifndef ATOM_BROWSER_API_ATOM_API_APP_H_
#define ATOM_BROWSER_API_ATOM_API_APP_H_
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include "atom/browser/api/event_emitter.h"
@@ -19,13 +17,10 @@
#include "base/task/cancelable_task_tracker.h"
#include "chrome/browser/icon_manager.h"
#include "chrome/browser/process_singleton.h"
#include "content/public/browser/browser_child_process_observer.h"
#include "content/public/browser/gpu_data_manager_observer.h"
#include "content/public/browser/render_process_host.h"
#include "native_mate/dictionary.h"
#include "native_mate/handle.h"
#include "net/base/completion_callback.h"
#include "net/ssl/client_cert_identity.h"
#if defined(USE_NSS_CERTS)
#include "chrome/browser/certificate_manager_model.h"
@@ -45,33 +40,31 @@ namespace atom {
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,
public mate::EventEmitter<App>,
public BrowserObserver,
public content::GpuDataManagerObserver,
public content::BrowserChildProcessObserver {
public content::GpuDataManagerObserver {
public:
using FileIconCallback =
base::Callback<void(v8::Local<v8::Value>, const gfx::Image&)>;
using FileIconCallback = base::Callback<void(v8::Local<v8::Value>,
const gfx::Image&)>;
static mate::Handle<App> Create(v8::Isolate* isolate);
static void BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype);
// Called when window with disposition needs to be created.
void OnCreateWindow(
const GURL& target_url,
const std::string& frame_name,
WindowOpenDisposition disposition,
const std::vector<std::string>& features,
const scoped_refptr<content::ResourceRequestBodyImpl>& body,
int render_process_id,
int render_frame_id);
#if defined(USE_NSS_CERTS)
void OnCertificateManagerModelCreated(
std::unique_ptr<base::DictionaryValue> options,
@@ -80,9 +73,6 @@ class App : public AtomBrowserClient::Delegate,
#endif
base::FilePath GetAppPath() const;
void RenderProcessReady(content::RenderProcessHost* host);
void RenderProcessDisconnected(base::ProcessId host_pid);
void PreMainMessageLoopRun();
protected:
explicit App(v8::Isolate* isolate);
@@ -98,26 +88,14 @@ 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,
void OnLogin(LoginHandler* login_handler,
const base::DictionaryValue& request_details) override;
void OnAccessibilitySupportChanged() override;
void OnPreMainMessageLoopRun() override;
#if defined(OS_MACOSX)
void OnWillContinueUserActivity(bool* prevent_default,
const std::string& type) override;
void OnDidFailToContinueUserActivity(const std::string& type,
const std::string& error) override;
void OnContinueUserActivity(bool* prevent_default,
const std::string& type,
const base::DictionaryValue& user_info) override;
void OnUserActivityWasContinued(
const std::string& type,
const base::DictionaryValue& user_info) override;
void OnUpdateUserActivityState(
void OnContinueUserActivity(
bool* prevent_default,
const std::string& type,
const base::DictionaryValue& user_info) override;
void OnNewWindowForTab() override;
#endif
// content::ContentBrowserClient:
@@ -127,6 +105,7 @@ class App : public AtomBrowserClient::Delegate,
const net::SSLInfo& ssl_info,
const GURL& request_url,
content::ResourceType resource_type,
bool overridable,
bool strict_enforcement,
bool expired_previous_decision,
const base::Callback<void(content::CertificateRequestResultType)>&
@@ -134,41 +113,13 @@ class App : public AtomBrowserClient::Delegate,
void SelectClientCertificate(
content::WebContents* web_contents,
net::SSLCertRequestInfo* cert_request_info,
net::ClientCertIdentityList client_certs,
std::unique_ptr<content::ClientCertificateDelegate> delegate) override;
bool CanCreateWindow(content::RenderFrameHost* opener,
const GURL& opener_url,
const GURL& opener_top_level_frame_url,
const GURL& source_origin,
content::mojom::WindowContainerType container_type,
const GURL& target_url,
const content::Referrer& referrer,
const std::string& frame_name,
WindowOpenDisposition disposition,
const blink::mojom::WindowFeatures& features,
const std::vector<std::string>& additional_features,
const scoped_refptr<network::ResourceRequestBody>& body,
bool user_gesture,
bool opener_suppressed,
bool* no_javascript_access) override;
// content::GpuDataManagerObserver:
void OnGpuProcessCrashed(base::TerminationStatus status) override;
// content::BrowserChildProcessObserver:
void BrowserChildProcessLaunchedAndConnected(
const content::ChildProcessData& data) override;
void BrowserChildProcessHostDisconnected(
const content::ChildProcessData& data) override;
void BrowserChildProcessCrashed(const content::ChildProcessData& data,
int exit_code) override;
void BrowserChildProcessKilled(const content::ChildProcessData& data,
int exit_code) override;
private:
void SetAppPath(const base::FilePath& app_path);
void ChildProcessLaunched(int process_type, base::ProcessHandle handle);
void ChildProcessDisconnected(base::ProcessId pid);
// Get/Set the pre-defined path in PathService.
base::FilePath GetPath(mate::Arguments* args, const std::string& name);
@@ -178,35 +129,21 @@ class App : public AtomBrowserClient::Delegate,
void SetDesktopName(const std::string& desktop_name);
std::string GetLocale();
void OnSecondInstance(const base::CommandLine::StringVector& cmd,
const base::FilePath& cwd);
bool HasSingleInstanceLock() const;
bool RequestSingleInstanceLock();
void ReleaseSingleInstanceLock();
bool MakeSingleInstance(
const ProcessSingleton::NotificationCallback& callback);
void ReleaseSingleInstance();
bool Relaunch(mate::Arguments* args);
void DisableHardwareAcceleration(mate::Arguments* args);
void DisableDomainBlockingFor3DAPIs(mate::Arguments* args);
bool IsAccessibilitySupportEnabled();
void SetAccessibilitySupportEnabled(bool enabled);
Browser::LoginItemSettings GetLoginItemSettings(mate::Arguments* args);
#if defined(USE_NSS_CERTS)
void ImportCertificate(const base::DictionaryValue& options,
const net::CompletionCallback& callback);
#endif
void 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);
void EnableMixedSandbox(mate::Arguments* args);
#if defined(OS_MACOSX)
bool MoveToApplicationsFolder(mate::Arguments* args);
bool IsInApplicationsFolder();
#endif
#if defined(MAS_BUILD)
base::Callback<void()> StartAccessingSecurityScopedResource(
mate::Arguments* args);
#endif
std::vector<mate::Dictionary> GetAppMemoryInfo(v8::Isolate* isolate);
#if defined(OS_WIN)
// Get the current Jump List settings.
@@ -227,10 +164,6 @@ class App : public AtomBrowserClient::Delegate,
base::FilePath app_path_;
using ProcessMetricMap =
std::unordered_map<base::ProcessId, std::unique_ptr<atom::ProcessMetric>>;
ProcessMetricMap app_metrics_;
DISALLOW_COPY_AND_ASSIGN(App);
};

View File

@@ -1,63 +0,0 @@
// 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_app.h"
#import <Cocoa/Cocoa.h>
#include "base/strings/sys_string_conversions.h"
namespace atom {
namespace api {
// Callback passed to js which will stop accessing the given bookmark.
void OnStopAccessingSecurityScopedResource(NSURL* bookmarkUrl) {
[bookmarkUrl stopAccessingSecurityScopedResource];
[bookmarkUrl release];
}
// Get base64 encoded NSData, create a bookmark for it and start accessing it.
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];
// Create bookmarkUrl from NSData.
BOOL isStale = false;
NSError* error = nil;
NSURL* bookmarkUrl =
[NSURL URLByResolvingBookmarkData:bookmarkData
options:NSURLBookmarkResolutionWithSecurityScope
relativeToURL:nil
bookmarkDataIsStale:&isStale
error:&error];
if (error != nil) {
NSString* err =
[NSString stringWithFormat:@"NSError: %@ %@", error, [error userInfo]];
args->ThrowError(base::SysNSStringToUTF8(err));
}
if (isStale) {
args->ThrowError("bookmarkDataIsStale - try recreating the bookmark");
}
if (error == nil && isStale == false) {
[bookmarkUrl startAccessingSecurityScopedResource];
}
// Stop the NSURL from being GC'd.
[bookmarkUrl retain];
// Return a js callback which will close the bookmark.
return base::Bind(&OnStopAccessingSecurityScopedResource, bookmarkUrl);
}
} // namespace atom
} // namespace api

View File

@@ -16,12 +16,12 @@
namespace mate {
template <>
template<>
struct Converter<base::Time> {
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
const base::Time& val) {
v8::MaybeLocal<v8::Value> date =
v8::Date::New(isolate->GetCurrentContext(), val.ToJsTime());
v8::MaybeLocal<v8::Value> date = v8::Date::New(
isolate->GetCurrentContext(), val.ToJsTime());
if (date.IsEmpty())
return v8::Null(isolate);
else
@@ -49,30 +49,14 @@ void AutoUpdater::OnError(const std::string& message) {
v8::HandleScope handle_scope(isolate());
auto error = v8::Exception::Error(mate::StringToV8(isolate(), message));
mate::EmitEvent(
isolate(), GetWrapper(), "error",
isolate(),
GetWrapper(),
"error",
error->ToObject(isolate()->GetCurrentContext()).ToLocalChecked(),
// Message is also emitted to keep compatibility with old code.
message);
}
void AutoUpdater::OnError(const std::string& message,
const int code,
const std::string& domain) {
v8::Locker locker(isolate());
v8::HandleScope handle_scope(isolate());
auto error = v8::Exception::Error(mate::StringToV8(isolate(), message));
auto errorObject =
error->ToObject(isolate()->GetCurrentContext()).ToLocalChecked();
// add two new params for better error handling
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);
}
void AutoUpdater::OnCheckingForUpdate() {
Emit("checking-for-update");
}
@@ -98,13 +82,13 @@ void AutoUpdater::OnWindowAllClosed() {
QuitAndInstall();
}
void AutoUpdater::SetFeedURL(mate::Arguments* args) {
auto_updater::AutoUpdater::SetFeedURL(args);
void AutoUpdater::SetFeedURL(const std::string& url, mate::Arguments* args) {
auto_updater::AutoUpdater::HeaderMap headers;
args->GetNext(&headers);
auto_updater::AutoUpdater::SetFeedURL(url, headers);
}
void AutoUpdater::QuitAndInstall() {
Emit("before-quit-for-update");
// If we don't have any window then quitAndInstall immediately.
if (WindowList::IsEmpty()) {
auto_updater::AutoUpdater::QuitAndInstall();
@@ -122,8 +106,8 @@ mate::Handle<AutoUpdater> AutoUpdater::Create(v8::Isolate* isolate) {
}
// static
void AutoUpdater::BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype) {
void AutoUpdater::BuildPrototype(
v8::Isolate* isolate, v8::Local<v8::FunctionTemplate> prototype) {
prototype->SetClassName(mate::StringToV8(isolate, "AutoUpdater"));
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
.SetMethod("checkForUpdates", &auto_updater::AutoUpdater::CheckForUpdates)
@@ -136,14 +120,13 @@ void AutoUpdater::BuildPrototype(v8::Isolate* isolate,
} // namespace atom
namespace {
using atom::api::AutoUpdater;
void Initialize(v8::Local<v8::Object> exports,
v8::Local<v8::Value> unused,
v8::Local<v8::Context> context,
void* priv) {
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("autoUpdater", AutoUpdater::Create(isolate));
@@ -152,4 +135,4 @@ void Initialize(v8::Local<v8::Object> exports,
} // namespace
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_auto_updater, Initialize)
NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_auto_updater, Initialize)

View File

@@ -32,9 +32,6 @@ class AutoUpdater : public mate::EventEmitter<AutoUpdater>,
// Delegate implementations.
void OnError(const std::string& error) override;
void OnError(const std::string& message,
const int code,
const std::string& domain) override;
void OnCheckingForUpdate() override;
void OnUpdateAvailable() override;
void OnUpdateNotAvailable() override;
@@ -48,7 +45,7 @@ class AutoUpdater : public mate::EventEmitter<AutoUpdater>,
private:
std::string GetFeedURL();
void SetFeedURL(mate::Arguments* args);
void SetFeedURL(const std::string& url, mate::Arguments* args);
void QuitAndInstall();
DISALLOW_COPY_AND_ASSIGN(AutoUpdater);

View File

@@ -1,87 +0,0 @@
// Copyright (c) 2018 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/browser/api/atom_api_box_layout.h"
#include <string>
#include "atom/browser/api/atom_api_view.h"
#include "atom/common/api/constructor.h"
#include "native_mate/dictionary.h"
#include "atom/common/node_includes.h"
namespace mate {
template <>
struct Converter<views::BoxLayout::Orientation> {
static bool FromV8(v8::Isolate* isolate,
v8::Handle<v8::Value> val,
views::BoxLayout::Orientation* out) {
std::string orientation;
if (!ConvertFromV8(isolate, val, &orientation))
return false;
if (orientation == "horizontal")
*out = views::BoxLayout::kHorizontal;
else if (orientation == "vertical")
*out = views::BoxLayout::kVertical;
else
return false;
return true;
}
};
} // namespace mate
namespace atom {
namespace api {
BoxLayout::BoxLayout(views::BoxLayout::Orientation orientation)
: LayoutManager(new views::BoxLayout(orientation)) {}
BoxLayout::~BoxLayout() {}
void BoxLayout::SetFlexForView(mate::Handle<View> view, int flex) {
auto* box_layout = static_cast<views::BoxLayout*>(layout_manager());
box_layout->SetFlexForView(view->view(), flex);
}
// static
mate::WrappableBase* BoxLayout::New(mate::Arguments* args,
views::BoxLayout::Orientation orientation) {
auto* layout = new BoxLayout(orientation);
layout->InitWith(args->isolate(), args->GetThis());
return layout;
}
// static
void BoxLayout::BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype) {
prototype->SetClassName(mate::StringToV8(isolate, "BoxLayout"));
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
.SetMethod("setFlexForView", &BoxLayout::SetFlexForView);
}
} // namespace api
} // namespace atom
namespace {
using atom::api::BoxLayout;
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("BoxLayout", mate::CreateConstructor<BoxLayout>(
isolate, base::Bind(&BoxLayout::New)));
}
} // namespace
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_box_layout, Initialize)

View File

@@ -1,40 +0,0 @@
// Copyright (c) 2018 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef ATOM_BROWSER_API_ATOM_API_BOX_LAYOUT_H_
#define ATOM_BROWSER_API_ATOM_API_BOX_LAYOUT_H_
#include "atom/browser/api/atom_api_layout_manager.h"
#include "native_mate/handle.h"
#include "ui/views/layout/box_layout.h"
namespace atom {
namespace api {
class View;
class BoxLayout : public LayoutManager {
public:
static mate::WrappableBase* New(mate::Arguments* args,
views::BoxLayout::Orientation orientation);
static void BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype);
void SetFlexForView(mate::Handle<View> view, int flex);
protected:
explicit BoxLayout(views::BoxLayout::Orientation orientation);
~BoxLayout() override;
private:
DISALLOW_COPY_AND_ASSIGN(BoxLayout);
};
} // namespace api
} // namespace atom
#endif // ATOM_BROWSER_API_ATOM_API_BOX_LAYOUT_H_

View File

@@ -51,7 +51,8 @@ namespace api {
BrowserView::BrowserView(v8::Isolate* isolate,
v8::Local<v8::Object> wrapper,
const mate::Dictionary& options) {
const mate::Dictionary& options)
: api_web_contents_(nullptr) {
Init(isolate, wrapper, options);
}
@@ -67,8 +68,8 @@ void BrowserView::Init(v8::Isolate* isolate,
web_contents_.Reset(isolate, web_contents.ToV8());
api_web_contents_ = web_contents.get();
view_.reset(
NativeBrowserView::Create(api_web_contents_->managed_web_contents()));
view_.reset(NativeBrowserView::Create(
api_web_contents_->managed_web_contents()->GetView()));
InitWith(isolate, wrapper);
}
@@ -113,7 +114,7 @@ void BrowserView::SetBackgroundColor(const std::string& color_name) {
view_->SetBackgroundColor(ParseHexColor(color_name));
}
v8::Local<v8::Value> BrowserView::GetWebContents() {
v8::Local<v8::Value> BrowserView::WebContents() {
if (web_contents_.IsEmpty()) {
return v8::Null(isolate());
}
@@ -130,7 +131,7 @@ void BrowserView::BuildPrototype(v8::Isolate* isolate,
.SetMethod("setAutoResize", &BrowserView::SetAutoResize)
.SetMethod("setBounds", &BrowserView::SetBounds)
.SetMethod("setBackgroundColor", &BrowserView::SetBackgroundColor)
.SetProperty("webContents", &BrowserView::GetWebContents)
.SetProperty("webContents", &BrowserView::WebContents)
.SetProperty("id", &BrowserView::ID);
}
@@ -151,14 +152,11 @@ void Initialize(v8::Local<v8::Object> exports,
mate::Dictionary browser_view(
isolate, BrowserView::GetConstructor(isolate)->GetFunction());
browser_view.SetMethod("fromId",
&mate::TrackableObject<BrowserView>::FromWeakMapID);
browser_view.SetMethod("getAllViews",
&mate::TrackableObject<BrowserView>::GetAll);
mate::Dictionary dict(isolate, exports);
dict.Set("BrowserView", browser_view);
}
} // namespace
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_browser_view, Initialize)
NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_browser_view, Initialize)

View File

@@ -36,7 +36,6 @@ class BrowserView : public mate::TrackableObject<BrowserView> {
static void BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype);
WebContents* web_contents() const { return api_web_contents_; }
NativeBrowserView* view() const { return view_.get(); }
int32_t ID() const;
@@ -56,10 +55,10 @@ class BrowserView : public mate::TrackableObject<BrowserView> {
void SetBounds(const gfx::Rect& bounds);
void SetBackgroundColor(const std::string& color_name);
v8::Local<v8::Value> GetWebContents();
v8::Local<v8::Value> WebContents();
v8::Global<v8::Value> web_contents_;
class WebContents* api_web_contents_ = nullptr;
class WebContents* api_web_contents_;
std::unique_ptr<NativeBrowserView> view_;

View File

@@ -1,452 +0,0 @@
// 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_browser_window.h"
#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"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h"
#include "native_mate/dictionary.h"
#include "ui/gl/gpu_switching_manager.h"
#include "atom/common/node_includes.h"
namespace atom {
namespace api {
BrowserWindow::BrowserWindow(v8::Isolate* isolate,
v8::Local<v8::Object> wrapper,
const mate::Dictionary& options)
: TopLevelWindow(isolate, options), weak_factory_(this) {
mate::Handle<class WebContents> web_contents;
// Use options.webPreferences in WebContents.
mate::Dictionary web_preferences = mate::Dictionary::CreateEmpty(isolate);
options.Get(options::kWebPreferences, &web_preferences);
// Copy the backgroundColor to webContents.
v8::Local<v8::Value> value;
if (options.Get(options::kBackgroundColor, &value))
web_preferences.Set(options::kBackgroundColor, value);
v8::Local<v8::Value> transparent;
if (options.Get("transparent", &transparent))
web_preferences.Set("transparent", transparent);
if (options.Get("webContents", &web_contents) && !web_contents.IsEmpty()) {
// Set webPreferences from options if using an existing webContents.
// These preferences will be used when the webContent launches new
// render processes.
auto* existing_preferences =
WebContentsPreferences::From(web_contents->web_contents());
base::DictionaryValue web_preferences_dict;
if (mate::ConvertFromV8(isolate, web_preferences.GetHandle(),
&web_preferences_dict)) {
existing_preferences->dict()->Clear();
existing_preferences->Merge(web_preferences_dict);
}
} else {
// Creates the WebContents used by BrowserWindow.
web_contents = WebContents::Create(isolate, web_preferences);
}
web_contents_.Reset(isolate, web_contents.ToV8());
api_web_contents_ = web_contents.get();
api_web_contents_->AddObserver(this);
Observe(api_web_contents_->web_contents());
// Keep a copy of the options for later use.
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());
auto* host = web_contents->web_contents()->GetRenderViewHost();
if (host)
host->GetWidget()->AddInputEventObserver(this);
InitWith(isolate, wrapper);
#if defined(OS_MACOSX)
if (!window()->has_frame())
OverrideNSWindowContentView(web_contents->managed_web_contents());
#endif
// Init window after everything has been setup.
window()->InitFromOptions(options);
}
BrowserWindow::~BrowserWindow() {
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())
Cleanup();
}
void BrowserWindow::OnInputEvent(const blink::WebInputEvent& event) {
switch (event.GetType()) {
case blink::WebInputEvent::kGestureScrollBegin:
case blink::WebInputEvent::kGestureScrollUpdate:
case blink::WebInputEvent::kGestureScrollEnd:
Emit("scroll-touch-edge");
break;
default:
break;
}
}
void BrowserWindow::RenderViewHostChanged(content::RenderViewHost* old_host,
content::RenderViewHost* new_host) {
if (old_host)
old_host->GetWidget()->RemoveInputEventObserver(this);
if (new_host)
new_host->GetWidget()->AddInputEventObserver(this);
}
void BrowserWindow::RenderViewCreated(
content::RenderViewHost* render_view_host) {
if (!window()->transparent())
return;
content::RenderWidgetHostImpl* impl = content::RenderWidgetHostImpl::FromID(
render_view_host->GetProcess()->GetID(),
render_view_host->GetRoutingID());
if (impl)
impl->SetBackgroundOpaque(false);
}
void BrowserWindow::DidFirstVisuallyNonEmptyPaint() {
if (window()->IsVisible())
return;
// When there is a non-empty first paint, resize the RenderWidget to force
// Chromium to draw.
auto* const view = web_contents()->GetRenderWidgetHostView();
view->Show();
view->SetSize(window()->GetContentSize());
// Emit the ReadyToShow event in next tick in case of pending drawing work.
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::BindOnce(
[](base::WeakPtr<BrowserWindow> self) {
if (self)
self->Emit("ready-to-show");
},
GetWeakPtr()));
}
void BrowserWindow::BeforeUnloadDialogCancelled() {
WindowList::WindowCloseCancelled(window());
// Cancel unresponsive event when window close is cancelled.
window_unresponsive_closure_.Cancel();
}
void BrowserWindow::OnRendererUnresponsive(content::RenderProcessHost*) {
// Schedule the unresponsive shortly later, since we may receive the
// responsive event soon. This could happen after the whole application had
// blocked for a while.
// Also notice that when closing this event would be ignored because we have
// explicitly started a close timeout counter. This is on purpose because we
// don't want the unresponsive event to be sent too early when user is closing
// the window.
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() {
DCHECK(web_contents());
// Close all child windows before closing current window.
v8::Locker locker(isolate());
v8::HandleScope handle_scope(isolate());
for (v8::Local<v8::Value> value : child_windows_.Values(isolate())) {
mate::Handle<BrowserWindow> child;
if (mate::ConvertFromV8(isolate(), value, &child) && !child.IsEmpty())
child->window()->CloseImmediately();
}
// When the web contents is gone, close the window immediately, but the
// memory will not be freed until you call delete.
// In this way, it would be safe to manage windows via smart pointers. If you
// want to free memory when the window is closed, you can do deleting by
// overriding the OnWindowClosed method in the observer.
window()->CloseImmediately();
// Do not sent "unresponsive" event after window is closed.
window_unresponsive_closure_.Cancel();
}
void BrowserWindow::OnRendererResponsive() {
window_unresponsive_closure_.Cancel();
Emit("responsive");
}
void BrowserWindow::RequestPreferredWidth(int* width) {
*width = web_contents()->GetPreferredSize().width();
}
void BrowserWindow::OnCloseButtonClicked(bool* prevent_default) {
// When user tries to close the window by clicking the close button, we do
// not close the window immediately, instead we try to close the web page
// first, and when the web page is closed the window will also be closed.
*prevent_default = true;
// Assume the window is not responding if it doesn't cancel the close and is
// not closed in 5s, in this way we can quickly show the unresponsive
// dialog when the window is busy executing some script withouth waiting for
// the unresponsive timeout.
if (window_unresponsive_closure_.IsCancelled())
ScheduleUnresponsiveEvent(5000);
if (!web_contents())
// Already closed by renderer
return;
if (web_contents()->NeedToFireBeforeUnload())
web_contents()->DispatchBeforeUnload();
else
web_contents()->Close();
}
void BrowserWindow::OnWindowClosed() {
Cleanup();
TopLevelWindow::OnWindowClosed();
}
void BrowserWindow::OnWindowBlur() {
web_contents()->StoreFocus();
#if defined(OS_MACOSX)
auto* rwhv = web_contents()->GetRenderWidgetHostView();
if (rwhv)
rwhv->SetActive(false);
#endif
TopLevelWindow::OnWindowBlur();
}
void BrowserWindow::OnWindowFocus() {
web_contents()->RestoreFocus();
#if defined(OS_MACOSX)
auto* rwhv = web_contents()->GetRenderWidgetHostView();
if (rwhv)
rwhv->SetActive(true);
#else
if (!api_web_contents_->IsDevToolsOpened())
web_contents()->Focus();
#endif
TopLevelWindow::OnWindowFocus();
}
void BrowserWindow::OnWindowResize() {
#if defined(OS_MACOSX)
if (!draggable_regions_.empty())
UpdateDraggableRegions(nullptr, draggable_regions_);
#endif
TopLevelWindow::OnWindowResize();
}
void BrowserWindow::OnWindowLeaveFullScreen() {
TopLevelWindow::OnWindowLeaveFullScreen();
#if defined(OS_MACOSX)
if (web_contents()->IsFullscreenForCurrentTab())
web_contents()->ExitFullscreen(true);
#endif
}
void BrowserWindow::Focus() {
if (api_web_contents_->IsOffScreen())
FocusOnWebView();
else
TopLevelWindow::Focus();
}
void BrowserWindow::Blur() {
if (api_web_contents_->IsOffScreen())
BlurWebView();
else
TopLevelWindow::Blur();
}
void BrowserWindow::SetBackgroundColor(const std::string& color_name) {
TopLevelWindow::SetBackgroundColor(color_name);
auto* view = web_contents()->GetRenderWidgetHostView();
if (view)
view->SetBackgroundColor(ParseHexColor(color_name));
}
void BrowserWindow::SetBrowserView(v8::Local<v8::Value> value) {
TopLevelWindow::SetBrowserView(value);
#if defined(OS_MACOSX)
UpdateDraggableRegions(nullptr, draggable_regions_);
#endif
}
void BrowserWindow::SetVibrancy(v8::Isolate* isolate,
v8::Local<v8::Value> value) {
std::string type = mate::V8ToString(value);
auto* render_view_host = web_contents()->GetRenderViewHost();
if (render_view_host) {
auto* impl = content::RenderWidgetHostImpl::FromID(
render_view_host->GetProcess()->GetID(),
render_view_host->GetRoutingID());
if (impl)
impl->SetBackgroundOpaque(type.empty() ? !window_->transparent() : false);
}
TopLevelWindow::SetVibrancy(isolate, value);
}
void BrowserWindow::FocusOnWebView() {
web_contents()->GetRenderViewHost()->GetWidget()->Focus();
}
void BrowserWindow::BlurWebView() {
web_contents()->GetRenderViewHost()->GetWidget()->Blur();
}
bool BrowserWindow::IsWebViewFocused() {
auto* host_view = web_contents()->GetRenderViewHost()->GetWidget()->GetView();
return host_view && host_view->HasFocus();
}
v8::Local<v8::Value> BrowserWindow::GetWebContents(v8::Isolate* isolate) {
if (web_contents_.IsEmpty())
return v8::Null(isolate);
return v8::Local<v8::Value>::New(isolate, web_contents_);
}
// Convert draggable regions in raw format to SkRegion format.
std::unique_ptr<SkRegion> BrowserWindow::DraggableRegionsToSkRegion(
const std::vector<DraggableRegion>& regions) {
auto sk_region = std::make_unique<SkRegion>();
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);
}
return sk_region;
}
void BrowserWindow::ScheduleUnresponsiveEvent(int ms) {
if (!window_unresponsive_closure_.IsCancelled())
return;
window_unresponsive_closure_.Reset(
base::Bind(&BrowserWindow::NotifyWindowUnresponsive, GetWeakPtr()));
base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
FROM_HERE, window_unresponsive_closure_.callback(),
base::TimeDelta::FromMilliseconds(ms));
}
void BrowserWindow::NotifyWindowUnresponsive() {
window_unresponsive_closure_.Cancel();
if (!window_->IsClosed() && window_->IsEnabled() &&
!IsUnresponsiveEventSuppressed()) {
Emit("unresponsive");
}
}
void BrowserWindow::Cleanup() {
auto* host = web_contents()->GetRenderViewHost();
if (host)
host->GetWidget()->RemoveInputEventObserver(this);
api_web_contents_->DestroyWebContents(true /* async */);
Observe(nullptr);
}
// static
mate::WrappableBase* BrowserWindow::New(mate::Arguments* args) {
if (!Browser::Get()->is_ready()) {
args->ThrowError("Cannot create BrowserWindow before app is ready");
return nullptr;
}
if (args->Length() > 1) {
args->ThrowError();
return nullptr;
}
mate::Dictionary options;
if (!(args->Length() == 1 && args->GetNext(&options))) {
options = mate::Dictionary::CreateEmpty(args->isolate());
}
return new BrowserWindow(args->isolate(), args->GetThis(), options);
}
// static
void BrowserWindow::BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype) {
prototype->SetClassName(mate::StringToV8(isolate, "BrowserWindow"));
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
.SetMethod("focusOnWebView", &BrowserWindow::FocusOnWebView)
.SetMethod("blurWebView", &BrowserWindow::BlurWebView)
.SetMethod("isWebViewFocused", &BrowserWindow::IsWebViewFocused)
.SetProperty("webContents", &BrowserWindow::GetWebContents);
}
// static
v8::Local<v8::Value> BrowserWindow::From(v8::Isolate* isolate,
NativeWindow* native_window) {
auto* existing = TrackableObject::FromWrappedClass(isolate, native_window);
if (existing)
return existing->GetWrapper();
else
return v8::Null(isolate);
}
} // namespace api
} // namespace atom
namespace {
using atom::api::BrowserWindow;
using atom::api::TopLevelWindow;
void Initialize(v8::Local<v8::Object> exports,
v8::Local<v8::Value> unused,
v8::Local<v8::Context> context,
void* priv) {
v8::Isolate* isolate = context->GetIsolate();
mate::Dictionary dict(isolate, exports);
dict.Set("BrowserWindow", mate::CreateConstructor<BrowserWindow>(
isolate, base::Bind(&BrowserWindow::New)));
}
} // namespace
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_window, Initialize)

View File

@@ -1,126 +0,0 @@
// 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_BROWSER_WINDOW_H_
#define ATOM_BROWSER_API_ATOM_API_BROWSER_WINDOW_H_
#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"
namespace atom {
namespace api {
class BrowserWindow : public TopLevelWindow,
public content::RenderWidgetHost::InputEventObserver,
public content::WebContentsObserver,
public ExtendedWebContentsObserver {
public:
static mate::WrappableBase* New(mate::Arguments* args);
static void BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype);
// Returns the BrowserWindow object from |native_window|.
static v8::Local<v8::Value> From(v8::Isolate* isolate,
NativeWindow* native_window);
base::WeakPtr<BrowserWindow> GetWeakPtr() {
return weak_factory_.GetWeakPtr();
}
protected:
BrowserWindow(v8::Isolate* isolate,
v8::Local<v8::Object> wrapper,
const mate::Dictionary& options);
~BrowserWindow() override;
// content::RenderWidgetHost::InputEventObserver:
void OnInputEvent(const blink::WebInputEvent& event) override;
// content::WebContentsObserver:
void RenderViewHostChanged(content::RenderViewHost* old_host,
content::RenderViewHost* new_host) override;
void RenderViewCreated(content::RenderViewHost* render_view_host) override;
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;
// NativeWindowObserver:
void RequestPreferredWidth(int* width) override;
void OnCloseButtonClicked(bool* prevent_default) override;
// TopLevelWindow:
void OnWindowClosed() override;
void OnWindowBlur() override;
void OnWindowFocus() override;
void OnWindowResize() override;
void OnWindowLeaveFullScreen() override;
void Focus() override;
void Blur() override;
void SetBackgroundColor(const std::string& color_name) override;
void SetBrowserView(v8::Local<v8::Value> value) override;
void SetVibrancy(v8::Isolate* isolate, v8::Local<v8::Value> value) override;
// BrowserWindow APIs.
void FocusOnWebView();
void BlurWebView();
bool IsWebViewFocused();
v8::Local<v8::Value> GetWebContents(v8::Isolate* isolate);
private:
#if defined(OS_MACOSX)
void OverrideNSWindowContentView(brightray::InspectableWebContents* iwc);
#endif
// Helpers.
// Called when the window needs to update its draggable region.
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<DraggableRegion>& regions);
// Schedule a notification unresponsive event.
void ScheduleUnresponsiveEvent(int ms);
// Dispatch unresponsive event to observers.
void NotifyWindowUnresponsive();
// Cleanup our WebContents observers.
void Cleanup();
// Closure that would be called when window is unresponsive when closing,
// it should be cancelled when we can prove that the window is responsive.
base::CancelableClosure window_unresponsive_closure_;
#if defined(OS_MACOSX)
std::vector<DraggableRegion> draggable_regions_;
#endif
v8::Global<v8::Value> web_contents_;
api::WebContents* api_web_contents_;
base::WeakPtrFactory<BrowserWindow> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(BrowserWindow);
};
} // namespace api
} // namespace atom
#endif // ATOM_BROWSER_API_ATOM_API_BROWSER_WINDOW_H_

View File

@@ -1,130 +0,0 @@
// Copyright (c) 2018 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/browser/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 "brightray/browser/inspectable_web_contents_view.h"
@interface NSView (WebContentsView)
- (void)setMouseDownCanMoveWindow:(BOOL)can_move;
@end
@interface ControlRegionView : NSView
@end
@implementation ControlRegionView
- (BOOL)mouseDownCanMoveWindow {
return NO;
}
- (NSView*)hitTest:(NSPoint)aPoint {
return nil;
}
@end
namespace atom {
namespace api {
namespace {
// Return a vector of non-draggable regions that fill a window of size
// |width| by |height|, but leave gaps where the window should be draggable.
std::vector<gfx::Rect> CalculateNonDraggableRegions(
std::unique_ptr<SkRegion> draggable,
int width,
int height) {
std::vector<gfx::Rect> result;
SkRegion non_draggable;
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()));
}
return result;
}
} // namespace
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();
NSView* contentView = [window()->GetNativeWindow() contentView];
[webView setFrame:[contentView bounds]];
[contentView addSubview:webView];
[contentView viewDidMoveToWindow];
}
void BrowserWindow::UpdateDraggableRegions(
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();
NSInteger webViewWidth = NSWidth([webView bounds]);
NSInteger webViewHeight = NSHeight([webView bounds]);
if ([webView respondsToSelector:@selector(setMouseDownCanMoveWindow:)]) {
[webView setMouseDownCanMoveWindow:YES];
}
// Remove all ControlRegionViews that are added last time.
// Note that [webView subviews] returns the view's mutable internal array and
// it should be copied to avoid mutating the original array while enumerating
// it.
base::scoped_nsobject<NSArray> subviews([[webView subviews] copy]);
for (NSView* subview in subviews.get())
if ([subview isKindOfClass:[ControlRegionView class]])
[subview removeFromSuperview];
// Draggable regions is implemented by having the whole web view draggable
// (mouseDownCanMoveWindow) and overlaying regions that are not draggable.
draggable_regions_ = regions;
std::vector<gfx::Rect> drag_exclude_rects;
if (regions.empty()) {
drag_exclude_rects.push_back(gfx::Rect(0, 0, webViewWidth, webViewHeight));
} else {
drag_exclude_rects = CalculateNonDraggableRegions(
DraggableRegionsToSkRegion(regions), webViewWidth, webViewHeight);
}
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.
for (const auto& rect : drag_exclude_rects) {
base::scoped_nsobject<NSView> controlRegion(
[[ControlRegionView alloc] initWithFrame:NSZeroRect]);
[controlRegion setFrame:NSMakeRect(rect.x(), webViewHeight - rect.bottom(),
rect.width(), rect.height())];
[webView addSubview:controlRegion];
}
// AppKit will not update its cache of mouseDownCanMoveWindow unless something
// changes. Previously we tried adding an NSView and removing it, but for some
// reason it required reposting the mouse-down event, and didn't always work.
// Calling the below seems to be an effective solution.
[[webView window] setMovableByWindowBackground:NO];
[[webView window] setMovableByWindowBackground:YES];
}
} // namespace api
} // namespace atom

View File

@@ -1,24 +0,0 @@
// Copyright (c) 2018 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/browser/api/atom_api_browser_window.h"
#include "atom/browser/native_window_views.h"
namespace atom {
namespace api {
void BrowserWindow::UpdateDraggableRegions(
content::RenderFrameHost* rfh,
const std::vector<DraggableRegion>& regions) {
if (window_->has_frame())
return;
static_cast<NativeWindowViews*>(window_.get())
->UpdateDraggableRegions(DraggableRegionsToSkRegion(regions));
}
} // namespace api
} // namespace atom

View File

@@ -1,58 +0,0 @@
// Copyright (c) 2018 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/browser/api/atom_api_button.h"
#include "atom/common/api/constructor.h"
#include "native_mate/dictionary.h"
#include "atom/common/node_includes.h"
namespace atom {
namespace api {
Button::Button(views::Button* button) : View(button) {
view()->set_owned_by_client();
}
Button::~Button() {}
void Button::ButtonPressed(views::Button* sender, const ui::Event& event) {
Emit("click");
}
// static
mate::WrappableBase* Button::New(mate::Arguments* args) {
args->ThrowError("Button can not be created directly");
return nullptr;
}
// static
void Button::BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype) {
prototype->SetClassName(mate::StringToV8(isolate, "Button"));
}
} // namespace api
} // namespace atom
namespace {
using atom::api::Button;
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("Button",
mate::CreateConstructor<Button>(isolate, base::Bind(&Button::New)));
}
} // namespace
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_button, Initialize)

View File

@@ -1,38 +0,0 @@
// Copyright (c) 2018 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef ATOM_BROWSER_API_ATOM_API_BUTTON_H_
#define ATOM_BROWSER_API_ATOM_API_BUTTON_H_
#include "atom/browser/api/atom_api_view.h"
#include "native_mate/handle.h"
#include "ui/views/controls/button/button.h"
namespace atom {
namespace api {
class Button : public View, public views::ButtonListener {
public:
static mate::WrappableBase* New(mate::Arguments* args);
static void BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype);
protected:
explicit Button(views::Button* view);
~Button() override;
// views::ButtonListener:
void ButtonPressed(views::Button* sender, const ui::Event& event) override;
private:
DISALLOW_COPY_AND_ASSIGN(Button);
};
} // namespace api
} // namespace atom
#endif // ATOM_BROWSER_API_ATOM_API_BUTTON_H_

View File

@@ -18,7 +18,7 @@ using content::TracingController;
namespace mate {
template <>
template<>
struct Converter<base::trace_event::TraceConfig> {
static bool FromV8(v8::Isolate* isolate,
v8::Local<v8::Value> val,
@@ -41,39 +41,36 @@ namespace {
using CompletionCallback = base::Callback<void(const base::FilePath&)>;
scoped_refptr<TracingController::TraceDataEndpoint> GetTraceDataEndpoint(
const base::FilePath& path,
const CompletionCallback& callback) {
scoped_refptr<TracingController::TraceDataSink> GetTraceDataSink(
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));
return TracingController::CreateFileSink(result_file_path,
base::Bind(callback,
result_file_path));
}
void StopRecording(const base::FilePath& path,
const CompletionCallback& callback) {
TracingController::GetInstance()->StopTracing(
GetTraceDataEndpoint(path, callback));
GetTraceDataSink(path, callback));
}
void Initialize(v8::Local<v8::Object> exports,
v8::Local<v8::Value> unused,
v8::Local<v8::Context> context,
void* priv) {
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("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));
dict.SetMethod("getTraceBufferUsage", base::Bind(
&TracingController::GetTraceBufferUsage, controller));
}
} // namespace
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_content_tracing, Initialize)
NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_content_tracing, Initialize)

View File

@@ -5,7 +5,6 @@
#include "atom/browser/api/atom_api_cookies.h"
#include "atom/browser/atom_browser_context.h"
#include "atom/browser/request_context_delegate.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"
@@ -15,17 +14,18 @@
#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_monster.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 atom::AtomCookieDelegate;
using content::BrowserThread;
namespace mate {
template <>
template<>
struct Converter<atom::api::Cookies::Error> {
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
atom::api::Cookies::Error val) {
@@ -36,7 +36,7 @@ struct Converter<atom::api::Cookies::Error> {
}
};
template <>
template<>
struct Converter<net::CanonicalCookie> {
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
const net::CanonicalCookie& val) {
@@ -55,21 +55,21 @@ struct Converter<net::CanonicalCookie> {
}
};
template <>
struct Converter<net::CookieChangeCause> {
template<>
struct Converter<net::CookieStore::ChangeCause> {
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
const net::CookieChangeCause& val) {
const net::CookieStore::ChangeCause& val) {
switch (val) {
case net::CookieChangeCause::INSERTED:
case net::CookieChangeCause::EXPLICIT:
case net::CookieStore::ChangeCause::INSERTED:
case net::CookieStore::ChangeCause::EXPLICIT:
return mate::StringToV8(isolate, "explicit");
case net::CookieChangeCause::OVERWRITE:
case net::CookieStore::ChangeCause::OVERWRITE:
return mate::StringToV8(isolate, "overwrite");
case net::CookieChangeCause::EXPIRED:
case net::CookieStore::ChangeCause::EXPIRED:
return mate::StringToV8(isolate, "expired");
case net::CookieChangeCause::EVICTED:
case net::CookieStore::ChangeCause::EVICTED:
return mate::StringToV8(isolate, "evicted");
case net::CookieChangeCause::EXPIRED_OVERWRITE:
case net::CookieStore::ChangeCause::EXPIRED_OVERWRITE:
return mate::StringToV8(isolate, "expired-overwrite");
default:
return mate::StringToV8(isolate, "unknown");
@@ -162,16 +162,15 @@ void GetCookiesOnIO(scoped_refptr<net::URLRequestContextGetter> getter,
GetCookieStore(getter)->GetAllCookiesAsync(filtered_callback);
else
GetCookieStore(getter)->GetAllCookiesForURLAsync(GURL(url),
filtered_callback);
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 GURL& url, const std::string& name,
const base::Closure& callback) {
GetCookieStore(getter)->DeleteCookieAsync(
url, name, base::BindOnce(RunCallbackInUI, callback));
url, name, base::Bind(RunCallbackInUI, callback));
}
// Callback of SetCookie.
@@ -184,7 +183,7 @@ void OnSetCookie(const Cookies::SetCallback& callback, bool success) {
void FlushCookieStoreOnIOThread(
scoped_refptr<net::URLRequestContextGetter> getter,
const base::Closure& callback) {
GetCookieStore(getter)->FlushStore(base::BindOnce(RunCallbackInUI, callback));
GetCookieStore(getter)->FlushStore(base::Bind(RunCallbackInUI, callback));
}
// Sets cookie with |details| in IO thread.
@@ -207,106 +206,90 @@ void SetCookieOnIO(scoped_refptr<net::URLRequestContextGetter> getter,
base::Time creation_time;
if (details->GetDouble("creationDate", &creation_date)) {
creation_time = (creation_date == 0)
? base::Time::UnixEpoch()
: base::Time::FromDoubleT(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);
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);
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));
GetCookieStore(getter)->SetCookieWithDetailsAsync(
GURL(url), name, value, domain, path, creation_time,
expiration_time, last_access_time, secure, http_only,
net::CookieSameSite::DEFAULT_MODE, false,
net::COOKIE_PRIORITY_DEFAULT, base::Bind(OnSetCookie, callback));
}
} // namespace
Cookies::Cookies(v8::Isolate* isolate, AtomBrowserContext* browser_context)
: browser_context_(browser_context) {
Cookies::Cookies(v8::Isolate* isolate,
AtomBrowserContext* browser_context)
: request_context_getter_(browser_context->url_request_context_getter()),
cookie_delegate_(browser_context->cookie_delegate()) {
Init(isolate);
cookie_change_subscription_ =
browser_context->GetRequestContextDelegate()
->RegisterCookieChangeCallback(
base::Bind(&Cookies::OnCookieChanged, base::Unretained(this)));
cookie_delegate_->AddObserver(this);
}
Cookies::~Cookies() {}
Cookies::~Cookies() {
cookie_delegate_->RemoveObserver(this);
}
void Cookies::Get(const base::DictionaryValue& filter,
const GetCallback& callback) {
std::unique_ptr<base::DictionaryValue> copied(filter.CreateDeepCopy());
auto* getter = browser_context_->GetRequestContext();
auto getter = make_scoped_refptr(request_context_getter_);
content::BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::BindOnce(GetCookiesOnIO, base::RetainedRef(getter),
std::move(copied), callback));
base::Bind(GetCookiesOnIO, getter, Passed(&copied), callback));
}
void Cookies::Remove(const GURL& url,
const std::string& name,
void Cookies::Remove(const GURL& url, const std::string& name,
const base::Closure& callback) {
auto* getter = browser_context_->GetRequestContext();
auto getter = make_scoped_refptr(request_context_getter_);
content::BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::BindOnce(RemoveCookieOnIOThread, base::RetainedRef(getter), url,
name, callback));
base::Bind(RemoveCookieOnIOThread, getter, url, name, callback));
}
void Cookies::Set(const base::DictionaryValue& details,
const SetCallback& callback) {
std::unique_ptr<base::DictionaryValue> copied(details.CreateDeepCopy());
auto* getter = browser_context_->GetRequestContext();
auto getter = make_scoped_refptr(request_context_getter_);
content::BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::BindOnce(SetCookieOnIO, base::RetainedRef(getter),
std::move(copied), callback));
base::Bind(SetCookieOnIO, getter, Passed(&copied), callback));
}
void Cookies::FlushStore(const base::Closure& callback) {
auto* getter = browser_context_->GetRequestContext();
auto getter = make_scoped_refptr(request_context_getter_);
content::BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::BindOnce(FlushCookieStoreOnIOThread, base::RetainedRef(getter),
callback));
base::Bind(FlushCookieStoreOnIOThread, getter, callback));
}
void Cookies::OnCookieChanged(const CookieDetails* details) {
Emit("changed", *(details->cookie), details->cause, details->removed);
void Cookies::OnCookieChanged(const net::CanonicalCookie& cookie,
bool removed,
net::CookieStore::ChangeCause cause) {
Emit("changed", cookie, cause, removed);
}
// static
mate::Handle<Cookies> Cookies::Create(v8::Isolate* isolate,
AtomBrowserContext* browser_context) {
mate::Handle<Cookies> Cookies::Create(
v8::Isolate* isolate,
AtomBrowserContext* browser_context) {
return mate::CreateHandle(isolate, new Cookies(isolate, browser_context));
}

View File

@@ -8,8 +8,8 @@
#include <string>
#include "atom/browser/api/trackable_object.h"
#include "atom/browser/net/cookie_details.h"
#include "base/callback_list.h"
#include "atom/browser/net/atom_cookie_delegate.h"
#include "base/callback.h"
#include "native_mate/handle.h"
#include "net/cookies/canonical_cookie.h"
@@ -27,7 +27,8 @@ class AtomBrowserContext;
namespace api {
class Cookies : public mate::TrackableObject<Cookies> {
class Cookies : public mate::TrackableObject<Cookies>,
public AtomCookieDelegate::Observer {
public:
enum Error {
SUCCESS,
@@ -49,19 +50,19 @@ class Cookies : public mate::TrackableObject<Cookies> {
~Cookies() override;
void Get(const base::DictionaryValue& filter, const GetCallback& callback);
void Remove(const GURL& url,
const std::string& name,
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);
// AtomBrowserContext::RegisterCookieChangeCallback subscription:
void OnCookieChanged(const CookieDetails*);
// AtomCookieDelegate::Observer:
void OnCookieChanged(const net::CanonicalCookie& cookie,
bool removed,
net::CookieStore::ChangeCause cause) override;
private:
std::unique_ptr<base::CallbackList<void(const CookieDetails*)>::Subscription>
cookie_change_subscription_;
scoped_refptr<AtomBrowserContext> browser_context_;
net::URLRequestContextGetter* request_context_getter_;
scoped_refptr<AtomCookieDelegate> cookie_delegate_;
DISALLOW_COPY_AND_ASSIGN(Cookies);
};

View File

@@ -9,9 +9,7 @@
#include "atom/browser/atom_browser_main_parts.h"
#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 "base/memory/ptr_util.h"
#include "content/public/browser/devtools_agent_host.h"
#include "content/public/browser/web_contents.h"
#include "native_mate/dictionary.h"
@@ -26,14 +24,19 @@ namespace atom {
namespace api {
Debugger::Debugger(v8::Isolate* isolate, content::WebContents* web_contents)
: web_contents_(web_contents) {
: web_contents_(web_contents),
previous_request_id_(0) {
Init(isolate);
}
Debugger::~Debugger() {}
Debugger::~Debugger() {
}
void Debugger::AgentHostClosed(DevToolsAgentHost* agent_host) {
void Debugger::AgentHostClosed(DevToolsAgentHost* agent_host,
bool replaced_with_another_client) {
std::string detach_reason = "target closed";
if (replaced_with_another_client)
detach_reason = "replaced with devtools";
Emit("detach", detach_reason);
}
@@ -44,11 +47,20 @@ void Debugger::DispatchProtocolMessage(DevToolsAgentHost* agent_host,
v8::Locker locker(isolate());
v8::HandleScope handle_scope(isolate());
std::unique_ptr<base::Value> parsed_message = base::JSONReader::Read(message);
if (!parsed_message || !parsed_message->is_dict())
v8::Local<v8::String> local_message =
v8::String::NewFromUtf8(isolate(), message.data());
v8::MaybeLocal<v8::Value> parsed_message = v8::JSON::Parse(
isolate()->GetCurrentContext(), local_message);
if (parsed_message.IsEmpty()) {
return;
base::DictionaryValue* dict =
static_cast<base::DictionaryValue*>(parsed_message.get());
}
std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
if (!mate::ConvertFromV8(isolate(), parsed_message.ToLocalChecked(),
dict.get())) {
return;
}
int id;
if (!dict->GetInteger("id", &id)) {
std::string method;
@@ -107,7 +119,7 @@ void Debugger::Detach() {
if (!agent_host_.get())
return;
agent_host_->DetachClient(this);
AgentHostClosed(agent_host_.get());
AgentHostClosed(agent_host_.get(), false);
agent_host_ = nullptr;
}
@@ -131,7 +143,7 @@ void Debugger::SendCommand(mate::Arguments* args) {
request.SetInteger("id", request_id);
request.SetString("method", method);
if (!command_params.empty())
request.Set("params", base::WrapUnique(command_params.DeepCopy()));
request.Set("params", command_params.DeepCopy());
std::string json_args;
base::JSONWriter::Write(request, &json_args);
@@ -139,8 +151,9 @@ void Debugger::SendCommand(mate::Arguments* args) {
}
// static
mate::Handle<Debugger> Debugger::Create(v8::Isolate* isolate,
content::WebContents* web_contents) {
mate::Handle<Debugger> Debugger::Create(
v8::Isolate* isolate,
content::WebContents* web_contents) {
return mate::CreateHandle(isolate, new Debugger(isolate, web_contents));
}
@@ -163,10 +176,8 @@ namespace {
using atom::api::Debugger;
void Initialize(v8::Local<v8::Object> exports,
v8::Local<v8::Value> unused,
v8::Local<v8::Context> context,
void* priv) {
void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
v8::Local<v8::Context> context, void* priv) {
v8::Isolate* isolate = context->GetIsolate();
mate::Dictionary(isolate, exports)
.Set("Debugger", Debugger::GetConstructor(isolate)->GetFunction());
@@ -174,4 +185,4 @@ void Initialize(v8::Local<v8::Object> exports,
} // namespace
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_debugger, Initialize);
NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_debugger, Initialize);

View File

@@ -17,7 +17,7 @@
namespace content {
class DevToolsAgentHost;
class WebContents;
} // namespace content
}
namespace mate {
class Arguments;
@@ -27,15 +27,15 @@ namespace atom {
namespace api {
class Debugger : public mate::TrackableObject<Debugger>,
public content::DevToolsAgentHostClient {
class Debugger: public mate::TrackableObject<Debugger>,
public content::DevToolsAgentHostClient {
public:
using SendCommandCallback =
base::Callback<void(const base::DictionaryValue&,
const base::DictionaryValue&)>;
static mate::Handle<Debugger> Create(v8::Isolate* isolate,
content::WebContents* web_contents);
static mate::Handle<Debugger> Create(
v8::Isolate* isolate, content::WebContents* web_contents);
// mate::TrackableObject:
static void BuildPrototype(v8::Isolate* isolate,
@@ -46,7 +46,8 @@ class Debugger : public mate::TrackableObject<Debugger>,
~Debugger() override;
// content::DevToolsAgentHostClient:
void AgentHostClosed(content::DevToolsAgentHost* agent_host) override;
void AgentHostClosed(content::DevToolsAgentHost* agent_host,
bool replaced_with_another_client) override;
void DispatchProtocolMessage(content::DevToolsAgentHost* agent_host,
const std::string& message) override;
@@ -62,7 +63,7 @@ class Debugger : public mate::TrackableObject<Debugger>,
scoped_refptr<content::DevToolsAgentHost> agent_host_;
PendingRequestMap pending_requests_;
int previous_request_id_ = 0;
int previous_request_id_;
DISALLOW_COPY_AND_ASSIGN(Debugger);
};

View File

@@ -4,172 +4,92 @@
#include "atom/browser/api/atom_api_desktop_capturer.h"
#include <vector>
using base::PlatformThreadRef;
#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/task_scheduler/post_task.h"
#include "base/threading/thread_task_runner_handle.h"
#include "chrome/browser/media/desktop_media_list.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/desktop_capture.h"
#include "native_mate/dictionary.h"
#include "third_party/webrtc/modules/desktop_capture/desktop_capture_options.h"
#include "third_party/webrtc/modules/desktop_capture/desktop_capturer.h"
#if defined(OS_WIN)
#include "third_party/webrtc/modules/desktop_capture/win/dxgi_duplicator_controller.h"
#include "third_party/webrtc/modules/desktop_capture/win/screen_capturer_win_directx.h"
#include "ui/display/win/display_info.h"
#endif // defined(OS_WIN)
#include "atom/common/node_includes.h"
namespace mate {
template <>
struct Converter<atom::api::DesktopCapturer::Source> {
static v8::Local<v8::Value> ToV8(
v8::Isolate* isolate,
const atom::api::DesktopCapturer::Source& source) {
template<>
struct Converter<DesktopMediaList::Source> {
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
const DesktopMediaList::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));
content::DesktopMediaID id = source.id;
dict.Set("name", base::UTF16ToUTF8(source.name));
dict.Set("id", id.ToString());
dict.Set("thumbnail",
atom::api::NativeImage::Create(
isolate, gfx::Image(source.media_list_source.thumbnail)));
dict.Set("display_id", source.display_id);
dict.Set(
"thumbnail",
atom::api::NativeImage::Create(isolate, gfx::Image(source.thumbnail)));
return ConvertToV8(isolate, dict);
}
};
} // namespace mate
namespace {
void EmitFinished(
const std::vector<atom::api::DesktopCapturer::Source>& sources,
atom::api::DesktopCapturer* cap) {
cap->Emit("finished", sources);
}
void StartHandlingTask(bool capture_window,
bool capture_screen,
const gfx::Size& thumbnail_size,
atom::api::DesktopCapturer* cap) {
#if defined(OS_WIN)
if (content::desktop_capture::CreateDesktopCaptureOptions()
.allow_directx_capturer()) {
// DxgiDuplicatorController should be alive in this scope according to
// screen_capturer_win.cc.
auto duplicator = webrtc::DxgiDuplicatorController::Instance();
cap->using_directx_capturer_ =
webrtc::ScreenCapturerWinDirectx::IsSupported();
}
#endif // defined(OS_WIN)
std::unique_ptr<webrtc::DesktopCapturer> screen_capturer(
capture_screen ? content::desktop_capture::CreateScreenCapturer()
: nullptr);
std::unique_ptr<webrtc::DesktopCapturer> window_capturer(
capture_window ? content::desktop_capture::CreateWindowCapturer()
: nullptr);
cap->media_list_.reset(new NativeDesktopMediaList(
std::move(screen_capturer), std::move(window_capturer)));
cap->media_list_->SetThumbnailSize(thumbnail_size);
cap->media_list_->StartUpdating(cap);
}
void OnRefreshFinishedTask(atom::api::DesktopCapturer* cap) {
const auto media_list_sources = cap->media_list_->GetSources();
std::vector<atom::api::DesktopCapturer::Source> sources;
for (const auto& media_list_source : media_list_sources) {
sources.emplace_back(
atom::api::DesktopCapturer::Source{media_list_source, std::string()});
}
#if defined(OS_WIN)
// Gather the same unique screen IDs used by the electron.screen API in order
// to provide an association between it and desktopCapturer/getUserMedia.
// This is only required when using the DirectX capturer, otherwise the IDs
// across the APIs already match.
if (cap->using_directx_capturer_) {
std::vector<std::string> device_names;
// Crucially, this list of device names will be in the same order as
// |media_list_sources|.
webrtc::DxgiDuplicatorController::Instance()->GetDeviceNames(&device_names);
int device_name_index = 0;
for (auto& source : sources) {
if (source.media_list_source.id.type ==
content::DesktopMediaID::TYPE_SCREEN) {
const auto& device_name = device_names[device_name_index++];
std::wstring wide_device_name;
base::UTF8ToWide(device_name.c_str(), device_name.size(),
&wide_device_name);
const int64_t device_id =
display::win::DisplayInfo::DeviceIdFromDeviceName(
wide_device_name.c_str());
source.display_id = base::Int64ToString(device_id);
}
}
}
#elif defined(OS_MACOSX)
// On Mac, the IDs across the APIs match.
for (auto& source : sources) {
if (source.media_list_source.id.type ==
content::DesktopMediaID::TYPE_SCREEN) {
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 only
// supports capturing the entire desktop on Linux. Revisit this if individual
// screen support is added.
content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
base::Bind(EmitFinished, sources, cap));
}
} // namespace
namespace atom {
namespace api {
DesktopCapturer::DesktopCapturer(v8::Isolate* isolate) {
Init(isolate);
capture_thread_ = base::CreateSequencedTaskRunnerWithTraits(
{base::WithBaseSyncPrimitives(), base::MayBlock(),
base::TaskPriority::USER_VISIBLE});
}
DesktopCapturer::~DesktopCapturer() {}
DesktopCapturer::~DesktopCapturer() {
}
void DesktopCapturer::StartHandling(bool capture_window,
bool capture_screen,
const gfx::Size& thumbnail_size) {
capture_thread_->PostTask(
FROM_HERE, base::BindOnce(StartHandlingTask, capture_window,
capture_screen, thumbnail_size, this));
webrtc::DesktopCaptureOptions options =
webrtc::DesktopCaptureOptions::CreateDefault();
#if defined(OS_WIN)
// On windows, desktop effects (e.g. Aero) will be disabled when the Desktop
// capture API is active by default.
// We keep the desktop effects in most times. Howerver, the screen still
// fickers when the API is capturing the window due to limitation of current
// implemetation. This is a known and wontFix issue in webrtc (see:
// http://code.google.com/p/webrtc/issues/detail?id=3373)
options.set_disable_effects(false);
#endif
std::unique_ptr<webrtc::DesktopCapturer> screen_capturer(
capture_screen ? webrtc::DesktopCapturer::CreateScreenCapturer(options)
: nullptr);
std::unique_ptr<webrtc::DesktopCapturer> window_capturer(
capture_window ? webrtc::DesktopCapturer::CreateWindowCapturer(options)
: nullptr);
media_list_.reset(new NativeDesktopMediaList(
std::move(screen_capturer), std::move(window_capturer)));
media_list_->SetThumbnailSize(thumbnail_size);
media_list_->StartUpdating(this);
}
void DesktopCapturer::OnSourceAdded(int index) {}
void DesktopCapturer::OnSourceAdded(int index) {
}
void DesktopCapturer::OnSourceRemoved(int index) {}
void DesktopCapturer::OnSourceRemoved(int index) {
}
void DesktopCapturer::OnSourceMoved(int old_index, int new_index) {}
void DesktopCapturer::OnSourceMoved(int old_index, int new_index) {
}
void DesktopCapturer::OnSourceNameChanged(int index) {}
void DesktopCapturer::OnSourceNameChanged(int index) {
}
void DesktopCapturer::OnSourceThumbnailChanged(int index) {}
void DesktopCapturer::OnSourceThumbnailChanged(int index) {
}
bool DesktopCapturer::OnRefreshFinished() {
capture_thread_->PostTask(FROM_HERE,
base::BindOnce(OnRefreshFinishedTask, this));
Emit("finished", media_list_->GetSources());
return false;
}
@@ -180,8 +100,7 @@ mate::Handle<DesktopCapturer> DesktopCapturer::Create(v8::Isolate* isolate) {
// static
void DesktopCapturer::BuildPrototype(
v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype) {
v8::Isolate* isolate, v8::Local<v8::FunctionTemplate> prototype) {
prototype->SetClassName(mate::StringToV8(isolate, "DesktopCapturer"));
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
.SetMethod("startHandling", &DesktopCapturer::StartHandling);
@@ -193,10 +112,8 @@ void DesktopCapturer::BuildPrototype(
namespace {
void Initialize(v8::Local<v8::Object> exports,
v8::Local<v8::Value> unused,
v8::Local<v8::Context> context,
void* priv) {
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("desktopCapturer", atom::api::DesktopCapturer::Create(isolate));
@@ -204,4 +121,4 @@ void Initialize(v8::Local<v8::Object> exports,
} // namespace
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_desktop_capturer, Initialize);
NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_desktop_capturer, Initialize);

View File

@@ -5,8 +5,6 @@
#ifndef ATOM_BROWSER_API_ATOM_API_DESKTOP_CAPTURER_H_
#define ATOM_BROWSER_API_ATOM_API_DESKTOP_CAPTURER_H_
#include <string>
#include "atom/browser/api/event_emitter.h"
#include "chrome/browser/media/desktop_media_list_observer.h"
#include "chrome/browser/media/native_desktop_media_list.h"
@@ -16,15 +14,9 @@ namespace atom {
namespace api {
class DesktopCapturer : public mate::EventEmitter<DesktopCapturer>,
public DesktopMediaListObserver {
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;
};
static mate::Handle<DesktopCapturer> Create(v8::Isolate* isolate);
static void BuildPrototype(v8::Isolate* isolate,
@@ -34,11 +26,6 @@ class DesktopCapturer : public mate::EventEmitter<DesktopCapturer>,
bool capture_screen,
const gfx::Size& thumbnail_size);
std::unique_ptr<DesktopMediaList> media_list_;
#if defined(OS_WIN)
bool using_directx_capturer_ = false;
#endif // defined(OS_WIN)
protected:
explicit DesktopCapturer(v8::Isolate* isolate);
~DesktopCapturer() override;
@@ -52,7 +39,7 @@ class DesktopCapturer : public mate::EventEmitter<DesktopCapturer>,
bool OnRefreshFinished() override;
private:
scoped_refptr<base::SequencedTaskRunner> capture_thread_;
std::unique_ptr<DesktopMediaList> media_list_;
DISALLOW_COPY_AND_ASSIGN(DesktopCapturer);
};

View File

@@ -6,7 +6,7 @@
#include <utility>
#include <vector>
#include "atom/browser/api/atom_api_browser_window.h"
#include "atom/browser/api/atom_api_window.h"
#include "atom/browser/native_window.h"
#include "atom/browser/ui/certificate_trust.h"
#include "atom/browser/ui/file_dialog.h"
@@ -21,7 +21,7 @@
namespace mate {
template <>
template<>
struct Converter<file_dialog::Filter> {
static bool FromV8(v8::Isolate* isolate,
v8::Local<v8::Value> val,
@@ -37,7 +37,7 @@ struct Converter<file_dialog::Filter> {
}
};
template <>
template<>
struct Converter<file_dialog::DialogSettings> {
static bool FromV8(v8::Isolate* isolate,
v8::Local<v8::Value> val,
@@ -54,9 +54,6 @@ struct Converter<file_dialog::DialogSettings> {
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;
}
};
@@ -80,7 +77,8 @@ void ShowMessageBox(int type,
mate::Arguments* args) {
v8::Local<v8::Value> peek = args->PeekNext();
atom::MessageBoxCallback callback;
if (mate::Converter<atom::MessageBoxCallback>::FromV8(args->isolate(), peek,
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,
@@ -98,8 +96,9 @@ 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)) {
if (mate::Converter<file_dialog::OpenDialogCallback>::FromV8(args->isolate(),
peek,
&callback)) {
file_dialog::ShowOpenDialog(settings, callback);
} else {
std::vector<base::FilePath> paths;
@@ -112,8 +111,9 @@ 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)) {
if (mate::Converter<file_dialog::SaveDialogCallback>::FromV8(args->isolate(),
peek,
&callback)) {
file_dialog::ShowSaveDialog(settings, callback);
} else {
base::FilePath path;
@@ -122,10 +122,8 @@ void ShowSaveDialog(const file_dialog::DialogSettings& settings,
}
}
void Initialize(v8::Local<v8::Object> exports,
v8::Local<v8::Value> unused,
v8::Local<v8::Context> context,
void* priv) {
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);
@@ -139,4 +137,4 @@ void Initialize(v8::Local<v8::Object> exports,
} // namespace
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_dialog, Initialize)
NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_dialog, Initialize)

View File

@@ -19,23 +19,22 @@
namespace mate {
template <>
struct Converter<download::DownloadItem::DownloadState> {
static v8::Local<v8::Value> ToV8(
v8::Isolate* isolate,
download::DownloadItem::DownloadState state) {
template<>
struct Converter<content::DownloadItem::DownloadState> {
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
content::DownloadItem::DownloadState state) {
std::string download_state;
switch (state) {
case download::DownloadItem::IN_PROGRESS:
case content::DownloadItem::IN_PROGRESS:
download_state = "progressing";
break;
case download::DownloadItem::COMPLETE:
case content::DownloadItem::COMPLETE:
download_state = "completed";
break;
case download::DownloadItem::CANCELLED:
case content::DownloadItem::CANCELLED:
download_state = "cancelled";
break;
case download::DownloadItem::INTERRUPTED:
case content::DownloadItem::INTERRUPTED:
download_state = "interrupted";
break;
default:
@@ -58,7 +57,7 @@ std::map<uint32_t, v8::Global<v8::Object>> g_download_item_objects;
} // namespace
DownloadItem::DownloadItem(v8::Isolate* isolate,
download::DownloadItem* download_item)
content::DownloadItem* download_item)
: download_item_(download_item) {
download_item_->AddObserver(this);
Init(isolate);
@@ -76,18 +75,18 @@ DownloadItem::~DownloadItem() {
g_download_item_objects.erase(weak_map_id());
}
void DownloadItem::OnDownloadUpdated(download::DownloadItem* item) {
void DownloadItem::OnDownloadUpdated(content::DownloadItem* item) {
if (download_item_->IsDone()) {
Emit("done", item->GetState());
// Destroy the item once item is downloaded.
base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
GetDestroyClosure());
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, GetDestroyClosure());
} else {
Emit("updated", item->GetState());
}
}
void DownloadItem::OnDownloadDestroyed(download::DownloadItem* download_item) {
void DownloadItem::OnDownloadDestroyed(content::DownloadItem* download_item) {
download_item_ = nullptr;
// Destroy the native class immediately when downloadItem is destroyed.
delete this;
@@ -130,11 +129,12 @@ bool DownloadItem::HasUserGesture() const {
}
std::string DownloadItem::GetFilename() const {
return base::UTF16ToUTF8(
net::GenerateFileName(GetURL(), GetContentDisposition(), std::string(),
download_item_->GetSuggestedFilename(),
GetMimeType(), "download")
.LossyDisplayName());
return base::UTF16ToUTF8(net::GenerateFileName(GetURL(),
GetContentDisposition(),
std::string(),
download_item_->GetSuggestedFilename(),
GetMimeType(),
"download").LossyDisplayName());
}
std::string DownloadItem::GetContentDisposition() const {
@@ -149,7 +149,7 @@ const std::vector<GURL>& DownloadItem::GetURLChain() const {
return download_item_->GetUrlChain();
}
download::DownloadItem::DownloadState DownloadItem::GetState() const {
content::DownloadItem::DownloadState DownloadItem::GetState() const {
return download_item_->GetState();
}
@@ -206,9 +206,9 @@ void DownloadItem::BuildPrototype(v8::Isolate* isolate,
}
// static
mate::Handle<DownloadItem> DownloadItem::Create(v8::Isolate* isolate,
download::DownloadItem* item) {
auto* existing = TrackableObject::FromWrappedClass(isolate, item);
mate::Handle<DownloadItem> DownloadItem::Create(
v8::Isolate* isolate, content::DownloadItem* item) {
auto existing = TrackableObject::FromWrappedClass(isolate, item);
if (existing)
return mate::CreateHandle(isolate, static_cast<DownloadItem*>(existing));
@@ -226,10 +226,8 @@ mate::Handle<DownloadItem> DownloadItem::Create(v8::Isolate* isolate,
namespace {
void Initialize(v8::Local<v8::Object> exports,
v8::Local<v8::Value> unused,
v8::Local<v8::Context> context,
void* priv) {
void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
v8::Local<v8::Context> context, void* priv) {
v8::Isolate* isolate = context->GetIsolate();
mate::Dictionary(isolate, exports)
.Set("DownloadItem",
@@ -238,4 +236,4 @@ void Initialize(v8::Local<v8::Object> exports,
} // namespace
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_download_item, Initialize);
NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_download_item, Initialize);

View File

@@ -10,7 +10,7 @@
#include "atom/browser/api/trackable_object.h"
#include "base/files/file_path.h"
#include "components/download/public/common/download_item.h"
#include "content/public/browser/download_item.h"
#include "native_mate/handle.h"
#include "url/gurl.h"
@@ -19,10 +19,10 @@ namespace atom {
namespace api {
class DownloadItem : public mate::TrackableObject<DownloadItem>,
public download::DownloadItem::Observer {
public content::DownloadItem::Observer {
public:
static mate::Handle<DownloadItem> Create(v8::Isolate* isolate,
download::DownloadItem* item);
content::DownloadItem* item);
static void BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype);
@@ -40,7 +40,7 @@ class DownloadItem : public mate::TrackableObject<DownloadItem>,
std::string GetContentDisposition() const;
const GURL& GetURL() const;
const std::vector<GURL>& GetURLChain() const;
download::DownloadItem::DownloadState GetState() const;
content::DownloadItem::DownloadState GetState() const;
bool IsDone() const;
void SetSavePath(const base::FilePath& path);
base::FilePath GetSavePath() const;
@@ -49,16 +49,16 @@ class DownloadItem : public mate::TrackableObject<DownloadItem>,
double GetStartTime() const;
protected:
DownloadItem(v8::Isolate* isolate, download::DownloadItem* download_item);
~DownloadItem() override;
DownloadItem(v8::Isolate* isolate, content::DownloadItem* download_item);
~DownloadItem();
// Override download::DownloadItem::Observer methods
void OnDownloadUpdated(download::DownloadItem* download) override;
void OnDownloadDestroyed(download::DownloadItem* download) override;
// Override content::DownloadItem::Observer methods
void OnDownloadUpdated(content::DownloadItem* download) override;
void OnDownloadDestroyed(content::DownloadItem* download) override;
private:
base::FilePath save_path_;
download::DownloadItem* download_item_;
content::DownloadItem* download_item_;
DISALLOW_COPY_AND_ASSIGN(DownloadItem);
};

View File

@@ -40,8 +40,8 @@ void GlobalShortcut::OnKeyPressed(const ui::Accelerator& accelerator) {
bool GlobalShortcut::Register(const ui::Accelerator& accelerator,
const base::Closure& callback) {
if (!GlobalShortcutListener::GetInstance()->RegisterAccelerator(accelerator,
this)) {
if (!GlobalShortcutListener::GetInstance()->RegisterAccelerator(
accelerator, this)) {
return false;
}
@@ -54,8 +54,8 @@ void GlobalShortcut::Unregister(const ui::Accelerator& accelerator) {
return;
accelerator_callback_map_.erase(accelerator);
GlobalShortcutListener::GetInstance()->UnregisterAccelerator(accelerator,
this);
GlobalShortcutListener::GetInstance()->UnregisterAccelerator(
accelerator, this);
}
bool GlobalShortcut::IsRegistered(const ui::Accelerator& accelerator) {
@@ -73,8 +73,8 @@ mate::Handle<GlobalShortcut> GlobalShortcut::Create(v8::Isolate* isolate) {
}
// static
void GlobalShortcut::BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype) {
void GlobalShortcut::BuildPrototype(
v8::Isolate* isolate, v8::Local<v8::FunctionTemplate> prototype) {
prototype->SetClassName(mate::StringToV8(isolate, "GlobalShortcut"));
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
.SetMethod("register", &GlobalShortcut::Register)
@@ -89,10 +89,8 @@ void GlobalShortcut::BuildPrototype(v8::Isolate* isolate,
namespace {
void Initialize(v8::Local<v8::Object> exports,
v8::Local<v8::Value> unused,
v8::Local<v8::Context> context,
void* priv) {
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("globalShortcut", atom::api::GlobalShortcut::Create(isolate));
@@ -100,4 +98,4 @@ void Initialize(v8::Local<v8::Object> exports,
} // namespace
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_global_shortcut, Initialize)
NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_global_shortcut, Initialize)

View File

@@ -1,142 +0,0 @@
// Copyright (c) 2017 Amaplex Software, 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_in_app_purchase.h"
#include <string>
#include <utility>
#include <vector>
#include "atom/common/native_mate_converters/callback.h"
#include "native_mate/dictionary.h"
#include "atom/common/node_includes.h"
namespace mate {
template <>
struct Converter<in_app_purchase::Payment> {
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
const in_app_purchase::Payment& payment) {
mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate);
dict.SetHidden("simple", true);
dict.Set("productIdentifier", payment.productIdentifier);
dict.Set("quantity", payment.quantity);
return dict.GetHandle();
}
};
template <>
struct Converter<in_app_purchase::Transaction> {
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
const in_app_purchase::Transaction& val) {
mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate);
dict.SetHidden("simple", true);
dict.Set("transactionIdentifier", val.transactionIdentifier);
dict.Set("transactionDate", val.transactionDate);
dict.Set("originalTransactionIdentifier",
val.originalTransactionIdentifier);
dict.Set("transactionState", val.transactionState);
dict.Set("errorCode", val.errorCode);
dict.Set("errorMessage", val.errorMessage);
dict.Set("payment", val.payment);
return dict.GetHandle();
}
};
template <>
struct Converter<in_app_purchase::Product> {
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
const in_app_purchase::Product& val) {
mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate);
dict.SetHidden("simple", true);
dict.Set("productIdentifier", val.productIdentifier);
dict.Set("localizedDescription", val.localizedDescription);
dict.Set("localizedTitle", val.localizedTitle);
dict.Set("contentVersion", val.localizedTitle);
dict.Set("contentLengths", val.contentLengths);
// Pricing Information
dict.Set("price", val.price);
dict.Set("formattedPrice", val.formattedPrice);
// Downloadable Content Information
dict.Set("isDownloadable", val.downloadable);
return dict.GetHandle();
}
};
} // namespace mate
namespace atom {
namespace api {
#if defined(OS_MACOSX)
// static
mate::Handle<InAppPurchase> InAppPurchase::Create(v8::Isolate* isolate) {
return mate::CreateHandle(isolate, new InAppPurchase(isolate));
}
// static
void InAppPurchase::BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype) {
prototype->SetClassName(mate::StringToV8(isolate, "InAppPurchase"));
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
.SetMethod("canMakePayments", &in_app_purchase::CanMakePayments)
.SetMethod("getReceiptURL", &in_app_purchase::GetReceiptURL)
.SetMethod("purchaseProduct", &InAppPurchase::PurchaseProduct)
.SetMethod("finishAllTransactions",
&in_app_purchase::FinishAllTransactions)
.SetMethod("finishTransactionByDate",
&in_app_purchase::FinishTransactionByDate)
.SetMethod("getProducts", &in_app_purchase::GetProducts);
}
InAppPurchase::InAppPurchase(v8::Isolate* isolate) {
Init(isolate);
}
InAppPurchase::~InAppPurchase() {}
void InAppPurchase::PurchaseProduct(const std::string& product_id,
mate::Arguments* args) {
int quantity = 1;
in_app_purchase::InAppPurchaseCallback callback;
args->GetNext(&quantity);
args->GetNext(&callback);
in_app_purchase::PurchaseProduct(product_id, quantity, callback);
}
void InAppPurchase::OnTransactionsUpdated(
const std::vector<in_app_purchase::Transaction>& transactions) {
Emit("transactions-updated", transactions);
}
#endif
} // namespace api
} // namespace atom
namespace {
using atom::api::InAppPurchase;
void Initialize(v8::Local<v8::Object> exports,
v8::Local<v8::Value> unused,
v8::Local<v8::Context> context,
void* priv) {
#if defined(OS_MACOSX)
v8::Isolate* isolate = context->GetIsolate();
mate::Dictionary dict(isolate, exports);
dict.Set("inAppPurchase", InAppPurchase::Create(isolate));
dict.Set("InAppPurchase",
InAppPurchase::GetConstructor(isolate)->GetFunction());
#endif
}
} // namespace
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_in_app_purchase, Initialize)

View File

@@ -1,47 +0,0 @@
// Copyright (c) 2017 Amaplex Software, 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_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"
namespace atom {
namespace api {
class InAppPurchase : public mate::EventEmitter<InAppPurchase>,
public in_app_purchase::TransactionObserver {
public:
static mate::Handle<InAppPurchase> Create(v8::Isolate* isolate);
static void BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype);
protected:
explicit InAppPurchase(v8::Isolate* isolate);
~InAppPurchase() override;
void PurchaseProduct(const std::string& product_id, mate::Arguments* args);
// TransactionObserver:
void OnTransactionsUpdated(
const std::vector<in_app_purchase::Transaction>& transactions) override;
private:
DISALLOW_COPY_AND_ASSIGN(InAppPurchase);
};
} // namespace api
} // namespace atom
#endif // ATOM_BROWSER_API_ATOM_API_IN_APP_PURCHASE_H_

View File

@@ -1,58 +0,0 @@
// Copyright (c) 2018 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/browser/api/atom_api_label_button.h"
#include "atom/common/api/constructor.h"
#include "base/strings/utf_string_conversions.h"
#include "native_mate/dictionary.h"
#include "ui/views/controls/button/label_button.h"
#include "atom/common/node_includes.h"
namespace atom {
namespace api {
LabelButton::LabelButton(const std::string& text)
: Button(new views::LabelButton(this, base::UTF8ToUTF16(text))) {}
LabelButton::~LabelButton() {}
// static
mate::WrappableBase* LabelButton::New(mate::Arguments* args,
const std::string& text) {
// Constructor call.
auto* view = new LabelButton(text);
view->InitWith(args->isolate(), args->GetThis());
return view;
}
// static
void LabelButton::BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype) {
prototype->SetClassName(mate::StringToV8(isolate, "LabelButton"));
}
} // namespace api
} // namespace atom
namespace {
using atom::api::LabelButton;
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("LabelButton", mate::CreateConstructor<LabelButton>(
isolate, base::Bind(&LabelButton::New)));
}
} // namespace
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_label_button, Initialize)

View File

@@ -1,36 +0,0 @@
// Copyright (c) 2018 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef ATOM_BROWSER_API_ATOM_API_LABEL_BUTTON_H_
#define ATOM_BROWSER_API_ATOM_API_LABEL_BUTTON_H_
#include <string>
#include "atom/browser/api/atom_api_button.h"
namespace atom {
namespace api {
class LabelButton : public Button {
public:
static mate::WrappableBase* New(mate::Arguments* args,
const std::string& text);
static void BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype);
protected:
explicit LabelButton(const std::string& text);
~LabelButton() override;
private:
DISALLOW_COPY_AND_ASSIGN(LabelButton);
};
} // namespace api
} // namespace atom
#endif // ATOM_BROWSER_API_ATOM_API_LABEL_BUTTON_H_

View File

@@ -1,63 +0,0 @@
// Copyright (c) 2018 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/browser/api/atom_api_layout_manager.h"
#include "atom/common/api/constructor.h"
#include "native_mate/dictionary.h"
#include "atom/common/node_includes.h"
namespace atom {
namespace api {
LayoutManager::LayoutManager(views::LayoutManager* layout_manager)
: layout_manager_(layout_manager) {
DCHECK(layout_manager_);
}
LayoutManager::~LayoutManager() {
if (managed_by_us_)
delete layout_manager_;
}
std::unique_ptr<views::LayoutManager> LayoutManager::TakeOver() {
if (!managed_by_us_) // already taken over.
return nullptr;
managed_by_us_ = false;
return std::unique_ptr<views::LayoutManager>(layout_manager_);
}
// static
mate::WrappableBase* LayoutManager::New(mate::Arguments* args) {
args->ThrowError("LayoutManager can not be created directly");
return nullptr;
}
// static
void LayoutManager::BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype) {}
} // namespace api
} // namespace atom
namespace {
using atom::api::LayoutManager;
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("LayoutManager", mate::CreateConstructor<LayoutManager>(
isolate, base::Bind(&LayoutManager::New)));
}
} // namespace
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_layout_manager, Initialize)

View File

@@ -1,44 +0,0 @@
// Copyright (c) 2018 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef ATOM_BROWSER_API_ATOM_API_LAYOUT_MANAGER_H_
#define ATOM_BROWSER_API_ATOM_API_LAYOUT_MANAGER_H_
#include <memory>
#include "atom/browser/api/trackable_object.h"
#include "ui/views/layout/layout_manager.h"
namespace atom {
namespace api {
class LayoutManager : public mate::TrackableObject<LayoutManager> {
public:
static mate::WrappableBase* New(mate::Arguments* args);
static void BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype);
// Take over the ownership of the LayoutManager, and leave weak ref here.
std::unique_ptr<views::LayoutManager> TakeOver();
views::LayoutManager* layout_manager() const { return layout_manager_; }
protected:
explicit LayoutManager(views::LayoutManager* layout_manager);
~LayoutManager() override;
private:
bool managed_by_us_ = true;
views::LayoutManager* layout_manager_;
DISALLOW_COPY_AND_ASSIGN(LayoutManager);
};
} // namespace api
} // namespace atom
#endif // ATOM_BROWSER_API_ATOM_API_LAYOUT_MANAGER_H_

View File

@@ -20,15 +20,12 @@ namespace atom {
namespace api {
Menu::Menu(v8::Isolate* isolate, v8::Local<v8::Object> wrapper)
: model_(new AtomMenuModel(this)) {
: model_(new AtomMenuModel(this)),
parent_(nullptr) {
InitWith(isolate, wrapper);
model_->AddObserver(this);
}
Menu::~Menu() {
if (model_) {
model_->RemoveObserver(this);
}
}
void Menu::AfterInit(v8::Isolate* isolate) {
@@ -46,21 +43,15 @@ void Menu::AfterInit(v8::Isolate* isolate) {
}
bool Menu::IsCommandIdChecked(int command_id) const {
v8::Locker locker(isolate());
v8::HandleScope handle_scope(isolate());
return is_checked_.Run(GetWrapper(), command_id);
return is_checked_.Run(command_id);
}
bool Menu::IsCommandIdEnabled(int command_id) const {
v8::Locker locker(isolate());
v8::HandleScope handle_scope(isolate());
return is_enabled_.Run(GetWrapper(), command_id);
return is_enabled_.Run(command_id);
}
bool Menu::IsCommandIdVisible(int command_id) const {
v8::Locker locker(isolate());
v8::HandleScope handle_scope(isolate());
return is_visible_.Run(GetWrapper(), command_id);
return is_visible_.Run(command_id);
}
bool Menu::GetAcceleratorForCommandIdWithParams(
@@ -69,28 +60,23 @@ bool Menu::GetAcceleratorForCommandIdWithParams(
ui::Accelerator* accelerator) const {
v8::Locker locker(isolate());
v8::HandleScope handle_scope(isolate());
v8::Local<v8::Value> val =
get_accelerator_.Run(GetWrapper(), command_id, use_default_accelerator);
v8::Local<v8::Value> val = get_accelerator_.Run(
command_id, use_default_accelerator);
return mate::ConvertFromV8(isolate(), val, accelerator);
}
void Menu::ExecuteCommand(int command_id, int flags) {
v8::Locker locker(isolate());
v8::HandleScope handle_scope(isolate());
execute_command_.Run(GetWrapper(),
mate::internal::CreateEventFromFlags(isolate(), flags),
command_id);
execute_command_.Run(
mate::internal::CreateEventFromFlags(isolate(), flags),
command_id);
}
void Menu::MenuWillShow(ui::SimpleMenuModel* source) {
v8::Locker locker(isolate());
v8::HandleScope handle_scope(isolate());
menu_will_show_.Run(GetWrapper());
menu_will_show_.Run();
}
void Menu::InsertItemAt(int index,
int command_id,
const base::string16& label) {
void Menu::InsertItemAt(
int index, int command_id, const base::string16& label) {
model_->InsertItemAt(index, command_id, label);
}
@@ -167,14 +153,6 @@ bool Menu::IsVisibleAt(int index) const {
return model_->IsVisibleAt(index);
}
void Menu::OnMenuWillClose() {
Emit("menu-will-close");
}
void Menu::OnMenuWillShow() {
Emit("menu-will-show");
}
// static
void Menu::BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype) {
@@ -206,14 +184,13 @@ void Menu::BuildPrototype(v8::Isolate* isolate,
} // namespace atom
namespace {
using atom::api::Menu;
void Initialize(v8::Local<v8::Object> exports,
v8::Local<v8::Value> unused,
v8::Local<v8::Context> context,
void* priv) {
void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
v8::Local<v8::Context> context, void* priv) {
v8::Isolate* isolate = context->GetIsolate();
Menu::SetConstructor(isolate, base::Bind(&Menu::New));
@@ -228,4 +205,4 @@ void Initialize(v8::Local<v8::Object> exports,
} // namespace
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_menu, Initialize)
NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_menu, Initialize)

View File

@@ -8,7 +8,7 @@
#include <memory>
#include <string>
#include "atom/browser/api/atom_api_top_level_window.h"
#include "atom/browser/api/atom_api_window.h"
#include "atom/browser/api/trackable_object.h"
#include "atom/browser/ui/atom_menu_model.h"
#include "base/callback.h"
@@ -18,8 +18,7 @@ namespace atom {
namespace api {
class Menu : public mate::TrackableObject<Menu>,
public AtomMenuModel::Delegate,
public AtomMenuModel::Observer {
public AtomMenuModel::Delegate {
public:
static mate::WrappableBase* New(mate::Arguments* args);
@@ -54,19 +53,12 @@ class Menu : public mate::TrackableObject<Menu>,
void ExecuteCommand(int command_id, int event_flags) override;
void MenuWillShow(ui::SimpleMenuModel* source) override;
virtual void PopupAt(TopLevelWindow* window,
int x,
int y,
int positioning_item,
const base::Closure& callback) = 0;
virtual void PopupAt(
Window* window, int x, int y, int positioning_item, bool async) = 0;
virtual void ClosePopupAt(int32_t window_id) = 0;
std::unique_ptr<AtomMenuModel> model_;
Menu* parent_ = nullptr;
// Observable:
void OnMenuWillClose() override;
void OnMenuWillShow() override;
Menu* parent_;
private:
void InsertItemAt(int index, int command_id, const base::string16& label);
@@ -96,14 +88,12 @@ class Menu : public mate::TrackableObject<Menu>,
bool IsVisibleAt(int index) const;
// Stored delegate methods.
base::Callback<bool(v8::Local<v8::Value>, int)> is_checked_;
base::Callback<bool(v8::Local<v8::Value>, int)> is_enabled_;
base::Callback<bool(v8::Local<v8::Value>, int)> is_visible_;
base::Callback<v8::Local<v8::Value>(v8::Local<v8::Value>, int, bool)>
get_accelerator_;
base::Callback<void(v8::Local<v8::Value>, v8::Local<v8::Value>, int)>
execute_command_;
base::Callback<void(v8::Local<v8::Value>)> menu_will_show_;
base::Callback<bool(int)> is_checked_;
base::Callback<bool(int)> is_enabled_;
base::Callback<bool(int)> is_visible_;
base::Callback<v8::Local<v8::Value>(int, bool)> get_accelerator_;
base::Callback<void(v8::Local<v8::Value>, int)> execute_command_;
base::Callback<void()> menu_will_show_;
DISALLOW_COPY_AND_ASSIGN(Menu);
};
@@ -112,12 +102,12 @@ class Menu : public mate::TrackableObject<Menu>,
} // namespace atom
namespace mate {
template <>
template<>
struct Converter<atom::AtomMenuModel*> {
static bool FromV8(v8::Isolate* isolate,
v8::Local<v8::Value> val,
static bool FromV8(v8::Isolate* isolate, v8::Local<v8::Value> val,
atom::AtomMenuModel** out) {
// null would be tranfered to NULL.
if (val->IsNull()) {

View File

@@ -21,25 +21,18 @@ namespace api {
class MenuMac : public Menu {
protected:
MenuMac(v8::Isolate* isolate, v8::Local<v8::Object> wrapper);
~MenuMac() override;
void PopupAt(TopLevelWindow* window,
int x,
int y,
int positioning_item,
const base::Closure& callback) override;
void PopupAt(
Window* window, int x, int y, int positioning_item, bool async) override;
void PopupOnUI(const base::WeakPtr<NativeWindow>& native_window,
int32_t window_id,
int x,
int y,
int positioning_item,
base::Closure callback);
int32_t window_id, int x, int y, int positioning_item,
bool async);
void ClosePopupAt(int32_t window_id) override;
private:
friend class Menu;
void OnClosed(int32_t window_id, base::Closure callback);
static void SendActionToFirstResponder(const std::string& action);
scoped_nsobject<AtomMenuController> menu_controller_;

View File

@@ -9,6 +9,8 @@
#include "base/mac/scoped_sending_event.h"
#include "base/message_loop/message_loop.h"
#include "base/strings/sys_string_conversions.h"
#include "brightray/browser/inspectable_web_contents.h"
#include "brightray/browser/inspectable_web_contents_view.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/web_contents.h"
@@ -16,53 +18,47 @@
using content::BrowserThread;
namespace {
static scoped_nsobject<NSMenu> applicationMenu_;
} // namespace
namespace atom {
namespace api {
MenuMac::MenuMac(v8::Isolate* isolate, v8::Local<v8::Object> wrapper)
: Menu(isolate, wrapper), weak_factory_(this) {}
: Menu(isolate, wrapper),
weak_factory_(this) {
}
MenuMac::~MenuMac() = default;
void MenuMac::PopupAt(TopLevelWindow* window,
int x,
int y,
int positioning_item,
const base::Closure& callback) {
void MenuMac::PopupAt(
Window* window, int x, int y, int positioning_item, bool async) {
NativeWindow* native_window = window->window();
if (!native_window)
return;
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);
native_window->GetWeakPtr(), window->ID(), x, y,
positioning_item, async);
if (async)
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, popup);
else
popup.Run();
}
void MenuMac::PopupOnUI(const base::WeakPtr<NativeWindow>& native_window,
int32_t window_id,
int x,
int y,
int positioning_item,
base::Closure callback) {
int32_t window_id, int x, int y, int positioning_item,
bool async) {
if (!native_window)
return;
NSWindow* nswindow = native_window->GetNativeWindow();
brightray::InspectableWebContents* web_contents =
native_window->inspectable_web_contents();
if (!web_contents)
return;
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]);
auto close_callback = base::Bind(&MenuMac::ClosePopupAt,
weak_factory_.GetWeakPtr(), window_id);
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];
NSView* view = web_contents->GetView()->GetNativeView();
// Which menu item to show.
NSMenuItem* item = nil;
@@ -72,6 +68,7 @@ void MenuMac::PopupOnUI(const base::WeakPtr<NativeWindow>& native_window,
// (-1, -1) means showing on mouse location.
NSPoint position;
if (x == -1 || y == -1) {
NSWindow* nswindow = native_window->GetNativeWindow();
position = [view convertPoint:[nswindow mouseLocationOutsideOfEventStream]
fromView:nil];
} else {
@@ -95,61 +92,42 @@ void MenuMac::PopupOnUI(const base::WeakPtr<NativeWindow>& native_window,
if (rightmostMenuPoint > screenRight)
position.x = position.x - [menu size].width;
[popup_controllers_[window_id] setCloseCallback:close_callback];
// Make sure events can be pumped while the menu is up.
base::MessageLoop::ScopedNestableTaskAllower allow(
base::MessageLoop::current());
// One of the events that could be pumped is |window.close()|.
// User-initiated event-tracking loops protect against this by
// setting flags in -[CrApplication sendEvent:], but since
// web-content menus are initiated by IPC message the setup has to
// be done manually.
base::mac::ScopedSendingEvent sendingEventScoper;
if (async) {
[popup_controllers_[window_id] setCloseCallback:close_callback];
// Make sure events can be pumped while the menu is up.
base::MessageLoop::ScopedNestableTaskAllower allow(
base::MessageLoop::current());
// Don't emit unresponsive event when showing menu.
atom::UnresponsiveSuppressor suppressor;
[menu popUpMenuPositioningItem:item atLocation:position inView:view];
}
// One of the events that could be pumped is |window.close()|.
// User-initiated event-tracking loops protect against this by
// setting flags in -[CrApplication sendEvent:], but since
// web-content menus are initiated by IPC message the setup has to
// be done manually.
base::mac::ScopedSendingEvent sendingEventScoper;
void MenuMac::ClosePopupAt(int32_t window_id) {
auto controller = popup_controllers_.find(window_id);
if (controller != popup_controllers_.end()) {
// Close the controller for the window.
[controller->second cancel];
} else if (window_id == -1) {
// Or just close all opened controllers.
for (auto it = popup_controllers_.begin();
it != popup_controllers_.end();) {
// The iterator is invalidated after the call.
[(it++)->second cancel];
}
// Don't emit unresponsive event when showing menu.
atom::UnresponsiveSuppressor suppressor;
[menu popUpMenuPositioningItem:item atLocation:position inView:view];
} else {
// Don't emit unresponsive event when showing menu.
atom::UnresponsiveSuppressor suppressor;
[menu popUpMenuPositioningItem:item atLocation:position inView:view];
close_callback.Run();
}
}
void MenuMac::OnClosed(int32_t window_id, base::Closure callback) {
void MenuMac::ClosePopupAt(int32_t window_id) {
popup_controllers_.erase(window_id);
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]);
NSRunLoop* currentRunLoop = [NSRunLoop currentRunLoop];
[currentRunLoop cancelPerformSelector:@selector(setMainMenu:)
target:NSApp
argument:applicationMenu_];
applicationMenu_.reset([[menu_controller menu] retain]);
[[NSRunLoop currentRunLoop]
performSelector:@selector(setMainMenu:)
target:NSApp
argument:applicationMenu_
order:0
modes:[NSArray arrayWithObject:NSDefaultRunLoopMode]];
base::scoped_nsobject<AtomMenuController> menu_controller(
[[AtomMenuController alloc] initWithModel:menu->model_.get()
useDefaultAccelerator:YES]);
[NSApp setMainMenu:[menu_controller menu]];
// Ensure the menu_controller_ is destroyed after main menu is set.
menu_controller.swap(menu->menu_controller_);

View File

@@ -6,6 +6,7 @@
#include "atom/browser/native_window_views.h"
#include "atom/browser/unresponsive_suppressor.h"
#include "content/public/browser/render_widget_host_view.h"
#include "ui/display/screen.h"
using views::MenuRunner;
@@ -15,61 +16,54 @@ namespace atom {
namespace api {
MenuViews::MenuViews(v8::Isolate* isolate, v8::Local<v8::Object> wrapper)
: Menu(isolate, wrapper), weak_factory_(this) {}
: Menu(isolate, wrapper),
weak_factory_(this) {
}
MenuViews::~MenuViews() = default;
void MenuViews::PopupAt(TopLevelWindow* window,
int x,
int y,
int positioning_item,
const base::Closure& callback) {
auto* native_window = static_cast<NativeWindowViews*>(window->window());
void MenuViews::PopupAt(
Window* window, int x, int y, int positioning_item, bool async) {
NativeWindow* native_window = static_cast<NativeWindow*>(window->window());
if (!native_window)
return;
content::WebContents* web_contents = native_window->web_contents();
if (!web_contents)
return;
content::RenderWidgetHostView* view = web_contents->GetRenderWidgetHostView();
if (!view)
return;
// (-1, -1) means showing on mouse location.
gfx::Point location;
if (x == -1 || y == -1) {
location = display::Screen::GetScreen()->GetCursorScreenPoint();
} else {
gfx::Point origin = native_window->GetContentBounds().origin();
gfx::Point origin = view->GetViewBounds().origin();
location = gfx::Point(origin.x() + x, origin.y() + y);
}
int flags = MenuRunner::CONTEXT_MENU | MenuRunner::HAS_MNEMONICS;
if (async)
flags |= MenuRunner::ASYNC;
// Don't emit unresponsive event when showing menu.
atom::UnresponsiveSuppressor suppressor;
// Show the menu.
int32_t window_id = window->weak_map_id();
int32_t window_id = window->ID();
auto close_callback = base::Bind(
&MenuViews::OnClosed, weak_factory_.GetWeakPtr(), window_id, callback);
menu_runners_[window_id] =
std::make_unique<MenuRunner>(model(), flags, close_callback);
menu_runners_[window_id]->RunMenuAt(
native_window->widget(), NULL, gfx::Rect(location, gfx::Size()),
views::MENU_ANCHOR_TOPLEFT, ui::MENU_SOURCE_MOUSE);
&MenuViews::ClosePopupAt, weak_factory_.GetWeakPtr(), window_id);
menu_runners_[window_id] = std::unique_ptr<MenuRunner>(new MenuRunner(
model(), flags, close_callback));
ignore_result(menu_runners_[window_id]->RunMenuAt(
static_cast<NativeWindowViews*>(window->window())->widget(),
NULL,
gfx::Rect(location, gfx::Size()),
views::MENU_ANCHOR_TOPLEFT,
ui::MENU_SOURCE_MOUSE));
}
void MenuViews::ClosePopupAt(int32_t window_id) {
auto runner = menu_runners_.find(window_id);
if (runner != menu_runners_.end()) {
// Close the runner for the window.
runner->second->Cancel();
} else if (window_id == -1) {
// Or just close all opened runners.
for (auto it = menu_runners_.begin(); it != menu_runners_.end();) {
// The iterator is invalidated after the call.
(it++)->second->Cancel();
}
}
}
void MenuViews::OnClosed(int32_t window_id, base::Closure callback) {
menu_runners_.erase(window_id);
callback.Run();
}
// static

View File

@@ -19,19 +19,13 @@ namespace api {
class MenuViews : public Menu {
public:
MenuViews(v8::Isolate* isolate, v8::Local<v8::Object> wrapper);
~MenuViews() override;
protected:
void PopupAt(TopLevelWindow* window,
int x,
int y,
int positioning_item,
const base::Closure& callback) override;
void PopupAt(
Window* window, int x, int y, int positioning_item, bool async) override;
void ClosePopupAt(int32_t window_id) override;
private:
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_;

View File

@@ -58,4 +58,4 @@ void Initialize(v8::Local<v8::Object> exports,
} // namespace
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_net, Initialize)
NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_net, Initialize)

View File

@@ -1,90 +0,0 @@
// Copyright (c) 2018 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/browser/api/atom_api_net_log.h"
#include "atom/browser/atom_browser_client.h"
#include "atom/common/native_mate_converters/callback.h"
#include "atom/common/native_mate_converters/file_path_converter.h"
#include "base/callback.h"
#include "content/public/common/content_switches.h"
#include "native_mate/dictionary.h"
#include "native_mate/handle.h"
#include "atom/common/node_includes.h"
namespace atom {
namespace api {
NetLog::NetLog(v8::Isolate* isolate) {
Init(isolate);
net_log_ = atom::AtomBrowserClient::Get()->GetNetLog();
}
NetLog::~NetLog() {}
// static
v8::Local<v8::Value> NetLog::Create(v8::Isolate* isolate) {
return mate::CreateHandle(isolate, new NetLog(isolate)).ToV8();
}
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;
}
net_log_->StartDynamicLogging(log_path);
}
bool NetLog::IsCurrentlyLogging() {
return net_log_->IsDynamicLogging();
}
base::FilePath::StringType NetLog::GetCurrentlyLoggingPath() {
return net_log_->GetDynamicLoggingPath().value();
}
void NetLog::StopLogging(mate::Arguments* args) {
base::OnceClosure callback;
args->GetNext(&callback);
net_log_->StopDynamicLogging(std::move(callback));
}
// 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
namespace {
using atom::api::NetLog;
void Initialize(v8::Local<v8::Object> exports,
v8::Local<v8::Value> unused,
v8::Local<v8::Context> context,
void* priv) {
v8::Isolate* isolate = context->GetIsolate();
mate::Dictionary dict(isolate, exports);
dict.Set("netLog", NetLog::Create(isolate));
dict.Set("NetLog", NetLog::GetConstructor(isolate)->GetFunction());
}
} // namespace
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_net_log, Initialize)

View File

@@ -1,42 +0,0 @@
// Copyright (c) 2018 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef ATOM_BROWSER_API_ATOM_API_NET_LOG_H_
#define ATOM_BROWSER_API_ATOM_API_NET_LOG_H_
#include <string>
#include "brightray/browser/net_log.h"
#include "native_mate/wrappable.h"
namespace atom {
namespace api {
class NetLog : public mate::Wrappable<NetLog> {
public:
static v8::Local<v8::Value> Create(v8::Isolate* isolate);
static void BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype);
void StartLogging(mate::Arguments* args);
bool IsCurrentlyLogging();
base::FilePath::StringType GetCurrentlyLoggingPath();
void StopLogging(mate::Arguments* args);
protected:
explicit NetLog(v8::Isolate* isolate);
~NetLog() override;
private:
brightray::NetLog* net_log_;
DISALLOW_COPY_AND_ASSIGN(NetLog);
};
} // namespace api
} // namespace atom
#endif // ATOM_BROWSER_API_ATOM_API_NET_LOG_H_

View File

@@ -1,272 +0,0 @@
// Copyright (c) 2014 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#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 "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<brightray::NotificationAction> {
static bool FromV8(v8::Isolate* isolate,
v8::Local<v8::Value> val,
brightray::NotificationAction* out) {
mate::Dictionary dict;
if (!ConvertFromV8(isolate, val, &dict))
return false;
if (!dict.Get("type", &(out->type))) {
return false;
}
dict.Get("text", &(out->text));
return true;
}
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
brightray::NotificationAction val) {
mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate);
dict.Set("text", val.text);
dict.Set("type", val.type);
return dict.GetHandle();
}
};
} // namespace mate
namespace atom {
namespace api {
Notification::Notification(v8::Isolate* isolate,
v8::Local<v8::Object> wrapper,
mate::Arguments* args) {
InitWith(isolate, wrapper);
presenter_ = brightray::BrowserClient::Get()->GetNotificationPresenter();
mate::Dictionary opts;
if (args->GetNext(&opts)) {
opts.Get("title", &title_);
opts.Get("subtitle", &subtitle_);
opts.Get("body", &body_);
has_icon_ = opts.Get("icon", &icon_);
if (has_icon_) {
opts.Get("icon", &icon_path_);
}
opts.Get("silent", &silent_);
opts.Get("replyPlaceholder", &reply_placeholder_);
opts.Get("hasReply", &has_reply_);
opts.Get("actions", &actions_);
opts.Get("sound", &sound_);
opts.Get("closeButtonText", &close_button_text_);
}
}
Notification::~Notification() {
if (notification_)
notification_->set_delegate(nullptr);
}
// static
mate::WrappableBase* Notification::New(mate::Arguments* args) {
if (!Browser::Get()->is_ready()) {
args->ThrowError("Cannot create Notification before app is ready");
return nullptr;
}
return new Notification(args->isolate(), args->GetThis(), args);
}
// Getters
base::string16 Notification::GetTitle() const {
return title_;
}
base::string16 Notification::GetSubtitle() const {
return subtitle_;
}
base::string16 Notification::GetBody() const {
return body_;
}
bool Notification::GetSilent() const {
return silent_;
}
bool Notification::GetHasReply() const {
return has_reply_;
}
base::string16 Notification::GetReplyPlaceholder() const {
return reply_placeholder_;
}
base::string16 Notification::GetSound() const {
return sound_;
}
std::vector<brightray::NotificationAction> Notification::GetActions() const {
return actions_;
}
base::string16 Notification::GetCloseButtonText() const {
return close_button_text_;
}
// Setters
void Notification::SetTitle(const base::string16& new_title) {
title_ = new_title;
}
void Notification::SetSubtitle(const base::string16& new_subtitle) {
subtitle_ = new_subtitle;
}
void Notification::SetBody(const base::string16& new_body) {
body_ = new_body;
}
void Notification::SetSilent(bool new_silent) {
silent_ = new_silent;
}
void Notification::SetHasReply(bool new_has_reply) {
has_reply_ = new_has_reply;
}
void Notification::SetReplyPlaceholder(const base::string16& new_placeholder) {
reply_placeholder_ = new_placeholder;
}
void Notification::SetSound(const base::string16& new_sound) {
sound_ = new_sound;
}
void Notification::SetActions(
const std::vector<brightray::NotificationAction>& actions) {
actions_ = actions;
}
void Notification::SetCloseButtonText(const base::string16& text) {
close_button_text_ = text;
}
void Notification::NotificationAction(int index) {
Emit("action", index);
}
void Notification::NotificationClick() {
Emit("click");
}
void Notification::NotificationReplied(const std::string& reply) {
Emit("reply", reply);
}
void Notification::NotificationDisplayed() {
Emit("show");
}
void Notification::NotificationDestroyed() {}
void Notification::NotificationClosed() {
Emit("close");
}
void Notification::Close() {
if (notification_) {
notification_->Dismiss();
notification_.reset();
}
}
// Showing notifications
void Notification::Show() {
Close();
if (presenter_) {
notification_ = presenter_->CreateNotification(this, base::GenerateGUID());
if (notification_) {
brightray::NotificationOptions options;
options.title = title_;
options.subtitle = subtitle_;
options.msg = body_;
options.icon_url = GURL();
options.icon = icon_.AsBitmap();
options.silent = silent_;
options.has_reply = has_reply_;
options.reply_placeholder = reply_placeholder_;
options.actions = actions_;
options.sound = sound_;
options.close_button_text = close_button_text_;
notification_->Show(options);
}
}
}
bool Notification::IsSupported() {
return !!brightray::BrowserClient::Get()->GetNotificationPresenter();
}
// static
void Notification::BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype) {
prototype->SetClassName(mate::StringToV8(isolate, "Notification"));
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
.MakeDestroyable()
.SetMethod("show", &Notification::Show)
.SetMethod("close", &Notification::Close)
.SetProperty("title", &Notification::GetTitle, &Notification::SetTitle)
.SetProperty("subtitle", &Notification::GetSubtitle,
&Notification::SetSubtitle)
.SetProperty("body", &Notification::GetBody, &Notification::SetBody)
.SetProperty("silent", &Notification::GetSilent, &Notification::SetSilent)
.SetProperty("hasReply", &Notification::GetHasReply,
&Notification::SetHasReply)
.SetProperty("replyPlaceholder", &Notification::GetReplyPlaceholder,
&Notification::SetReplyPlaceholder)
.SetProperty("sound", &Notification::GetSound, &Notification::SetSound)
.SetProperty("actions", &Notification::GetActions,
&Notification::SetActions)
.SetProperty("closeButtonText", &Notification::GetCloseButtonText,
&Notification::SetCloseButtonText);
}
} // namespace api
} // namespace atom
namespace {
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::Bind(&Notification::New));
mate::Dictionary dict(isolate, exports);
dict.Set("Notification",
Notification::GetConstructor(isolate)->GetFunction());
dict.SetMethod("isSupported", &Notification::IsSupported);
}
} // namespace
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_common_notification, Initialize)

View File

@@ -1,97 +0,0 @@
// Copyright (c) 2014 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef ATOM_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 "ui/gfx/image/image.h"
namespace atom {
namespace api {
class Notification : public mate::TrackableObject<Notification>,
public brightray::NotificationDelegate {
public:
static mate::WrappableBase* New(mate::Arguments* args);
static bool IsSupported();
static void BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype);
// NotificationDelegate:
void NotificationAction(int index) override;
void NotificationClick() override;
void NotificationReplied(const std::string& reply) override;
void NotificationDisplayed() override;
void NotificationDestroyed() override;
void NotificationClosed() override;
protected:
Notification(v8::Isolate* isolate,
v8::Local<v8::Object> wrapper,
mate::Arguments* args);
~Notification() override;
void Show();
void Close();
// Prop Getters
base::string16 GetTitle() const;
base::string16 GetSubtitle() const;
base::string16 GetBody() const;
bool GetSilent() const;
bool GetHasReply() const;
base::string16 GetReplyPlaceholder() const;
base::string16 GetSound() const;
std::vector<brightray::NotificationAction> GetActions() const;
base::string16 GetCloseButtonText() const;
// Prop Setters
void SetTitle(const base::string16& new_title);
void SetSubtitle(const base::string16& new_subtitle);
void SetBody(const base::string16& new_body);
void SetSilent(bool new_silent);
void SetHasReply(bool new_has_reply);
void SetReplyPlaceholder(const base::string16& new_reply_placeholder);
void SetSound(const base::string16& sound);
void SetActions(const std::vector<brightray::NotificationAction>& actions);
void SetCloseButtonText(const base::string16& text);
private:
base::string16 title_;
base::string16 subtitle_;
base::string16 body_;
gfx::Image icon_;
base::string16 icon_path_;
bool has_icon_ = false;
bool silent_ = false;
bool has_reply_ = false;
base::string16 reply_placeholder_;
base::string16 sound_;
std::vector<brightray::NotificationAction> actions_;
base::string16 close_button_text_;
brightray::NotificationPresenter* presenter_;
base::WeakPtr<brightray::Notification> notification_;
DISALLOW_COPY_AND_ASSIGN(Notification);
};
} // namespace api
} // namespace atom
#endif // ATOM_BROWSER_API_ATOM_API_NOTIFICATION_H_

View File

@@ -5,70 +5,25 @@
#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 "atom/common/node_includes.h"
namespace mate {
template <>
struct Converter<ui::IdleState> {
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
const ui::IdleState& in) {
switch (in) {
case ui::IDLE_STATE_ACTIVE:
return mate::StringToV8(isolate, "active");
case ui::IDLE_STATE_IDLE:
return mate::StringToV8(isolate, "idle");
case ui::IDLE_STATE_LOCKED:
return mate::StringToV8(isolate, "locked");
case ui::IDLE_STATE_UNKNOWN:
default:
return mate::StringToV8(isolate, "unknown");
}
}
};
} // namespace mate
namespace atom {
namespace api {
PowerMonitor::PowerMonitor(v8::Isolate* isolate) {
#if defined(OS_LINUX)
SetShutdownHandler(
base::Bind(&PowerMonitor::ShouldShutdown, base::Unretained(this)));
#elif defined(OS_MACOSX)
Browser::Get()->SetShutdownHandler(
base::Bind(&PowerMonitor::ShouldShutdown, base::Unretained(this)));
#endif
base::PowerMonitor::Get()->AddObserver(this);
Init(isolate);
#if defined(OS_MACOSX) || defined(OS_WIN)
InitPlatformSpecificMonitors();
#endif
}
PowerMonitor::~PowerMonitor() {
base::PowerMonitor::Get()->RemoveObserver(this);
}
bool PowerMonitor::ShouldShutdown() {
return !Emit("shutdown");
}
#if defined(OS_LINUX)
void PowerMonitor::BlockShutdown() {
PowerObserverLinux::BlockShutdown();
}
void PowerMonitor::UnblockShutdown() {
PowerObserverLinux::UnblockShutdown();
}
#endif
void PowerMonitor::OnPowerStateChange(bool on_battery_power) {
if (on_battery_power)
Emit("on-battery");
@@ -84,21 +39,6 @@ void PowerMonitor::OnResume() {
Emit("resume");
}
void PowerMonitor::QuerySystemIdleState(v8::Isolate* isolate,
int idle_threshold,
const ui::IdleCallback& callback) {
if (idle_threshold > 0) {
ui::CalculateIdleState(idle_threshold, callback);
} else {
isolate->ThrowException(v8::Exception::TypeError(mate::StringToV8(
isolate, "Invalid idle threshold, must be greater than 0")));
}
}
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()) {
@@ -112,32 +52,26 @@ v8::Local<v8::Value> PowerMonitor::Create(v8::Isolate* isolate) {
}
// static
void PowerMonitor::BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype) {
void PowerMonitor::BuildPrototype(
v8::Isolate* isolate, v8::Local<v8::FunctionTemplate> prototype) {
prototype->SetClassName(mate::StringToV8(isolate, "PowerMonitor"));
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
.MakeDestroyable()
#if defined(OS_LINUX)
.SetMethod("blockShutdown", &PowerMonitor::BlockShutdown)
.SetMethod("unblockShutdown", &PowerMonitor::UnblockShutdown)
#endif
.SetMethod("querySystemIdleState", &PowerMonitor::QuerySystemIdleState)
.SetMethod("querySystemIdleTime", &PowerMonitor::QuerySystemIdleTime);
}
} // namespace api
} // namespace atom
namespace {
using atom::api::PowerMonitor;
void Initialize(v8::Local<v8::Object> exports,
v8::Local<v8::Value> unused,
v8::Local<v8::Context> context,
void* priv) {
void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
v8::Local<v8::Context> context, void* priv) {
#if defined(OS_MACOSX)
base::PowerMonitorDeviceSource::AllocateSystemIOPorts();
#endif
v8::Isolate* isolate = context->GetIsolate();
mate::Dictionary dict(isolate, exports);
dict.Set("powerMonitor", PowerMonitor::Create(isolate));
@@ -147,4 +81,4 @@ void Initialize(v8::Local<v8::Object> exports,
} // namespace
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_power_monitor, Initialize)
NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_power_monitor, Initialize)

View File

@@ -6,17 +6,16 @@
#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 "base/power_monitor/power_observer.h"
#include "native_mate/handle.h"
#include "ui/base/idle/idle.h"
namespace atom {
namespace api {
class PowerMonitor : public mate::TrackableObject<PowerMonitor>,
public PowerObserver {
public base::PowerObserver {
public:
static v8::Local<v8::Value> Create(v8::Isolate* isolate);
@@ -27,52 +26,12 @@ class PowerMonitor : public mate::TrackableObject<PowerMonitor>,
explicit PowerMonitor(v8::Isolate* isolate);
~PowerMonitor() override;
// Called by native calles.
bool ShouldShutdown();
#if defined(OS_LINUX)
// Private JS APIs.
void BlockShutdown();
void UnblockShutdown();
#endif
#if defined(OS_MACOSX) || defined(OS_WIN)
void InitPlatformSpecificMonitors();
#endif
// base::PowerObserver implementations:
void OnPowerStateChange(bool on_battery_power) override;
void OnSuspend() override;
void OnResume() override;
private:
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.
static LRESULT CALLBACK WndProcStatic(HWND hwnd,
UINT message,
WPARAM wparam,
LPARAM lparam);
LRESULT CALLBACK WndProc(HWND hwnd,
UINT message,
WPARAM wparam,
LPARAM lparam);
// The window class of |window_|.
ATOM atom_;
// The handle of the module that contains the window procedure of |window_|.
HMODULE instance_;
// The window used for processing events.
HWND window_;
#endif
DISALLOW_COPY_AND_ASSIGN(PowerMonitor);
};

View File

@@ -1,74 +0,0 @@
// Copyright (c) 2013 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/browser/api/atom_api_power_monitor.h"
#include <ApplicationServices/ApplicationServices.h>
#import <Cocoa/Cocoa.h>
@interface MacLockMonitor : NSObject {
@private
std::vector<atom::api::PowerMonitor*> emitters;
}
- (void)addEmitter:(atom::api::PowerMonitor*)monitor_;
@end
@implementation MacLockMonitor
- (id)init {
if ((self = [super init])) {
NSDistributedNotificationCenter* distCenter =
[NSDistributedNotificationCenter defaultCenter];
[distCenter addObserver:self
selector:@selector(onScreenLocked:)
name:@"com.apple.screenIsLocked"
object:nil];
[distCenter addObserver:self
selector:@selector(onScreenUnlocked:)
name:@"com.apple.screenIsUnlocked"
object:nil];
}
return self;
}
- (void)dealloc {
[[NSDistributedNotificationCenter defaultCenter] removeObserver:self];
[super dealloc];
}
- (void)addEmitter:(atom::api::PowerMonitor*)monitor_ {
self->emitters.push_back(monitor_);
}
- (void)onScreenLocked:(NSNotification*)notification {
for (auto*& emitter : self->emitters) {
emitter->Emit("lock-screen");
}
}
- (void)onScreenUnlocked:(NSNotification*)notification {
for (auto*& emitter : self->emitters) {
emitter->Emit("unlock-screen");
}
}
@end
namespace atom {
namespace api {
static MacLockMonitor* g_lock_monitor = nil;
void PowerMonitor::InitPlatformSpecificMonitors() {
if (!g_lock_monitor)
g_lock_monitor = [[MacLockMonitor alloc] init];
[g_lock_monitor addEmitter:this];
}
} // namespace api
} // namespace atom

View File

@@ -1,71 +0,0 @@
// Copyright (c) 2013 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/browser/api/atom_api_power_monitor.h"
#include "base/win/wrapped_window_proc.h"
#include "ui/base/win/shell.h"
#include "ui/gfx/win/hwnd_util.h"
#include "Wtsapi32.h"
namespace atom {
namespace {
const wchar_t kPowerMonitorWindowClass[] =
L"Electron_PowerMonitorHostWindow";
} // namespace
namespace api {
void PowerMonitor::InitPlatformSpecificMonitors() {
WNDCLASSEX window_class;
base::win::InitializeWindowClass(
kPowerMonitorWindowClass,
&base::win::WrappedWindowProc<PowerMonitor::WndProcStatic>, 0, 0, 0,
NULL, NULL, NULL, NULL, NULL, &window_class);
instance_ = window_class.hInstance;
atom_ = RegisterClassEx(&window_class);
// Create an offscreen window for receiving broadcast messages for the
// session lock and unlock events.
window_ = CreateWindow(MAKEINTATOM(atom_), 0, 0, 0, 0, 0, 0, HWND_MESSAGE, 0,
instance_, 0);
gfx::CheckWindowCreated(window_);
gfx::SetWindowUserData(window_, this);
// Tel windows we want to be notified with session events
WTSRegisterSessionNotification(window_, NOTIFY_FOR_THIS_SESSION);
}
LRESULT CALLBACK PowerMonitor::WndProcStatic(HWND hwnd,
UINT message,
WPARAM wparam,
LPARAM lparam) {
PowerMonitor* msg_wnd = reinterpret_cast<PowerMonitor*>(
GetWindowLongPtr(hwnd, GWLP_USERDATA));
if (msg_wnd)
return msg_wnd->WndProc(hwnd, message, wparam, lparam);
else
return ::DefWindowProc(hwnd, message, wparam, lparam);
}
LRESULT CALLBACK PowerMonitor::WndProc(HWND hwnd,
UINT message,
WPARAM wparam,
LPARAM lparam) {
if (message == WM_WTSSESSION_CHANGE) {
if (wparam == WTS_SESSION_LOCK) {
Emit("lock-screen");
} else if (wparam == WTS_SESSION_UNLOCK) {
Emit("unlock-screen");
}
}
return ::DefWindowProc(hwnd, message, wparam, lparam);
}
} // namespace api
} // namespace atom

View File

@@ -6,26 +6,28 @@
#include <string>
#include "base/task_scheduler/post_task.h"
#include "base/threading/thread_task_runner_handle.h"
#include "content/public/browser/browser_thread.h"
#include "native_mate/dictionary.h"
#include "atom/common/node_includes.h"
using content::BrowserThread;
namespace mate {
template <>
struct Converter<device::mojom::WakeLockType> {
template<>
struct Converter<device::PowerSaveBlocker::PowerSaveBlockerType> {
static bool FromV8(v8::Isolate* isolate,
v8::Local<v8::Value> val,
device::mojom::WakeLockType* out) {
device::PowerSaveBlocker::PowerSaveBlockerType* out) {
using device::PowerSaveBlocker;
std::string type;
if (!ConvertFromV8(isolate, val, &type))
return false;
if (type == "prevent-app-suspension")
*out = device::mojom::WakeLockType::kPreventAppSuspension;
*out = PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension;
else if (type == "prevent-display-sleep")
*out = device::mojom::WakeLockType::kPreventDisplaySleep;
*out = PowerSaveBlocker::kPowerSaveBlockPreventDisplaySleep;
else
return false;
return true;
@@ -40,11 +42,12 @@ namespace api {
PowerSaveBlocker::PowerSaveBlocker(v8::Isolate* isolate)
: current_blocker_type_(
device::mojom::WakeLockType::kPreventAppSuspension) {
device::PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension) {
Init(isolate);
}
PowerSaveBlocker::~PowerSaveBlocker() {}
PowerSaveBlocker::~PowerSaveBlocker() {
}
void PowerSaveBlocker::UpdatePowerSaveBlocker() {
if (power_save_blocker_types_.empty()) {
@@ -52,39 +55,38 @@ void PowerSaveBlocker::UpdatePowerSaveBlocker() {
return;
}
// |WakeLockType::kPreventAppSuspension| keeps system active, but allows
// |kPowerSaveBlockPreventAppSuspension| 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|.
// |kPowerSaveBlockPreventDisplaySleep| keeps system and screen active, has a
// higher precedence level than |kPowerSaveBlockPreventAppSuspension|.
//
// Only the highest-precedence blocker type takes effect.
device::mojom::WakeLockType new_blocker_type =
device::mojom::WakeLockType::kPreventAppSuspension;
device::PowerSaveBlocker::PowerSaveBlockerType new_blocker_type =
device::PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension;
for (const auto& element : power_save_blocker_types_) {
if (element.second ==
device::mojom::WakeLockType::kPreventDisplaySleep) {
device::PowerSaveBlocker::kPowerSaveBlockPreventDisplaySleep) {
new_blocker_type =
device::mojom::WakeLockType::kPreventDisplaySleep;
device::PowerSaveBlocker::kPowerSaveBlockPreventDisplaySleep;
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}));
std::unique_ptr<device::PowerSaveBlocker> new_blocker(
new device::PowerSaveBlocker(
new_blocker_type,
device::PowerSaveBlocker::kReasonOther,
ATOM_PRODUCT_NAME,
BrowserThread::GetTaskRunnerForThread(BrowserThread::UI),
BrowserThread::GetTaskRunnerForThread(BrowserThread::FILE)));
power_save_blocker_.swap(new_blocker);
current_blocker_type_ = new_blocker_type;
}
}
int PowerSaveBlocker::Start(device::mojom::WakeLockType type) {
int PowerSaveBlocker::Start(
device::PowerSaveBlocker::PowerSaveBlockerType type) {
static int count = 0;
power_save_blocker_types_[count] = type;
UpdatePowerSaveBlocker();
@@ -108,8 +110,7 @@ mate::Handle<PowerSaveBlocker> PowerSaveBlocker::Create(v8::Isolate* isolate) {
// static
void PowerSaveBlocker::BuildPrototype(
v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype) {
v8::Isolate* isolate, v8::Local<v8::FunctionTemplate> prototype) {
prototype->SetClassName(mate::StringToV8(isolate, "PowerSaveBlocker"));
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
.SetMethod("start", &PowerSaveBlocker::Start)
@@ -123,10 +124,8 @@ void PowerSaveBlocker::BuildPrototype(
namespace {
void Initialize(v8::Local<v8::Object> exports,
v8::Local<v8::Value> unused,
v8::Local<v8::Context> context,
void* priv) {
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));
@@ -134,4 +133,4 @@ void Initialize(v8::Local<v8::Object> exports,
} // namespace
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_power_save_blocker, Initialize);
NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_power_save_blocker, Initialize);

View File

@@ -9,8 +9,8 @@
#include <memory>
#include "atom/browser/api/trackable_object.h"
#include "device/power_save_blocker/power_save_blocker.h"
#include "native_mate/handle.h"
#include "services/device/wake_lock/power_save_blocker/power_save_blocker.h"
namespace mate {
class Dictionary;
@@ -33,18 +33,19 @@ class PowerSaveBlocker : public mate::TrackableObject<PowerSaveBlocker> {
private:
void UpdatePowerSaveBlocker();
int Start(device::mojom::WakeLockType type);
int Start(device::PowerSaveBlocker::PowerSaveBlockerType 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_;
// Currnet blocker type used by |power_save_blocker_|
device::PowerSaveBlocker::PowerSaveBlockerType 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_;
using PowerSaveBlockerTypeMap =
std::map<int, device::PowerSaveBlocker::PowerSaveBlockerType>;
PowerSaveBlockerTypeMap power_save_blocker_types_;
DISALLOW_COPY_AND_ASSIGN(PowerSaveBlocker);
};

View File

@@ -10,7 +10,6 @@
#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"
@@ -33,6 +32,14 @@ namespace {
// List of registered custom standard schemes.
std::vector<std::string> g_standard_schemes;
// Clear protocol handlers in IO thread.
void ClearJobFactoryInIO(
scoped_refptr<brightray::URLRequestContextGetter> request_context_getter) {
auto job_factory = static_cast<AtomURLRequestJobFactory*>(
request_context_getter->job_factory());
job_factory->Clear();
}
} // namespace
std::vector<std::string> GetStandardSchemes() {
@@ -43,59 +50,59 @@ 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_WITHOUT_PORT);
if (secure) {
url::AddSecureScheme(scheme.c_str());
}
policy->RegisterWebSafeScheme(scheme);
}
// Add the schemes to command line switches, so child processes can also
// register them.
// add switches to register as standard
base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
atom::switches::kStandardSchemes, base::JoinString(schemes, ","));
if (secure) {
mate::Dictionary opts;
bool secure = false;
if (args->GetNext(&opts) && opts.Get("secure", &secure) && secure) {
// add switches to register as secure
base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
atom::switches::kSecureSchemes, base::JoinString(schemes, ","));
atom::switches::kSecureSchemes, base::JoinString(schemes, ","));
}
}
Protocol::Protocol(v8::Isolate* isolate, AtomBrowserContext* browser_context)
: browser_context_(browser_context), weak_factory_(this) {
: request_context_getter_(browser_context->GetRequestContext()),
weak_factory_(this) {
Init(isolate);
}
Protocol::~Protocol() {}
Protocol::~Protocol() {
content::BrowserThread::PostTask(
content::BrowserThread::IO, FROM_HERE,
base::Bind(ClearJobFactoryInIO, request_context_getter_));
}
void Protocol::RegisterServiceWorkerSchemes(
const std::vector<std::string>& schemes) {
atom::AtomBrowserClient::SetCustomServiceWorkerSchemes(schemes);
}
void Protocol::UnregisterProtocol(const std::string& scheme,
mate::Arguments* args) {
void Protocol::UnregisterProtocol(
const std::string& scheme, mate::Arguments* args) {
CompletionCallback callback;
args->GetNext(&callback);
auto* getter = 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));
base::Bind(&Protocol::UnregisterProtocolInIO,
request_context_getter_, scheme),
base::Bind(&Protocol::OnIOCompleted,
GetWeakPtr(), callback));
}
// static
Protocol::ProtocolError Protocol::UnregisterProtocolInIO(
scoped_refptr<brightray::URLRequestContextGetter> request_context_getter,
const std::string& scheme) {
auto* job_factory = static_cast<AtomURLRequestJobFactory*>(
auto job_factory = static_cast<AtomURLRequestJobFactory*>(
request_context_getter->job_factory());
if (!job_factory->HasProtocolHandler(scheme))
return PROTOCOL_NOT_REGISTERED;
@@ -105,11 +112,10 @@ Protocol::ProtocolError Protocol::UnregisterProtocolInIO(
void Protocol::IsProtocolHandled(const std::string& scheme,
const BooleanCallback& callback) {
auto* getter = browser_context_->GetRequestContext();
content::BrowserThread::PostTaskAndReplyWithResult(
content::BrowserThread::IO, FROM_HERE,
base::Bind(&Protocol::IsProtocolHandledInIO, base::RetainedRef(getter),
scheme),
base::Bind(&Protocol::IsProtocolHandledInIO,
request_context_getter_, scheme),
callback);
}
@@ -120,16 +126,16 @@ bool Protocol::IsProtocolHandledInIO(
return request_context_getter->job_factory()->IsHandledProtocol(scheme);
}
void Protocol::UninterceptProtocol(const std::string& scheme,
mate::Arguments* args) {
void Protocol::UninterceptProtocol(
const std::string& scheme, mate::Arguments* args) {
CompletionCallback callback;
args->GetNext(&callback);
auto* getter = 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));
base::Bind(&Protocol::UninterceptProtocolInIO,
request_context_getter_, scheme),
base::Bind(&Protocol::OnIOCompleted,
GetWeakPtr(), callback));
}
// static
@@ -137,14 +143,12 @@ Protocol::ProtocolError Protocol::UninterceptProtocolInIO(
scoped_refptr<brightray::URLRequestContextGetter> request_context_getter,
const std::string& scheme) {
return static_cast<AtomURLRequestJobFactory*>(
request_context_getter->job_factory())
->UninterceptProtocol(scheme)
? PROTOCOL_OK
: PROTOCOL_NOT_INTERCEPTED;
request_context_getter->job_factory())->UninterceptProtocol(scheme) ?
PROTOCOL_OK : PROTOCOL_NOT_INTERCEPTED;
}
void Protocol::OnIOCompleted(const CompletionCallback& callback,
ProtocolError error) {
void Protocol::OnIOCompleted(
const CompletionCallback& callback, ProtocolError error) {
// The completion callback is optional.
if (callback.is_null())
return;
@@ -162,30 +166,31 @@ void Protocol::OnIOCompleted(const CompletionCallback& callback,
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";
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";
}
}
AtomURLRequestJobFactory* Protocol::GetJobFactoryInIO() const {
request_context_getter_->GetURLRequestContext(); // Force init.
return static_cast<AtomURLRequestJobFactory*>(
static_cast<brightray::URLRequestContextGetter*>(
request_context_getter_.get())->job_factory());
}
// static
mate::Handle<Protocol> Protocol::Create(v8::Isolate* isolate,
AtomBrowserContext* browser_context) {
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) {
void Protocol::BuildPrototype(
v8::Isolate* isolate, v8::Local<v8::FunctionTemplate> prototype) {
prototype->SetClassName(mate::StringToV8(isolate, "Protocol"));
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
.SetMethod("registerServiceWorkerSchemes",
@@ -198,8 +203,6 @@ void Protocol::BuildPrototype(v8::Isolate* isolate,
&Protocol::RegisterProtocol<URLRequestAsyncAsarJob>)
.SetMethod("registerHttpProtocol",
&Protocol::RegisterProtocol<URLRequestFetchJob>)
.SetMethod("registerStreamProtocol",
&Protocol::RegisterProtocol<URLRequestStreamJob>)
.SetMethod("unregisterProtocol", &Protocol::UnregisterProtocol)
.SetMethod("isProtocolHandled", &Protocol::IsProtocolHandled)
.SetMethod("interceptStringProtocol",
@@ -210,8 +213,6 @@ void Protocol::BuildPrototype(v8::Isolate* isolate,
&Protocol::InterceptProtocol<URLRequestAsyncAsarJob>)
.SetMethod("interceptHttpProtocol",
&Protocol::InterceptProtocol<URLRequestFetchJob>)
.SetMethod("interceptStreamProtocol",
&Protocol::InterceptProtocol<URLRequestStreamJob>)
.SetMethod("uninterceptProtocol", &Protocol::UninterceptProtocol);
}
@@ -221,22 +222,19 @@ void Protocol::BuildPrototype(v8::Isolate* isolate,
namespace {
void RegisterStandardSchemes(const std::vector<std::string>& schemes,
mate::Arguments* args) {
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");
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) {
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);
@@ -245,4 +243,4 @@ void Initialize(v8::Local<v8::Object> exports,
} // namespace
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_protocol, Initialize)
NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_protocol, Initialize)

View File

@@ -39,20 +39,20 @@ class Protocol : public mate::TrackableObject<Protocol> {
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 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;
~Protocol();
private:
// Possible errors.
enum ProtocolError {
PROTOCOL_OK, // no error
PROTOCOL_OK, // no error
PROTOCOL_FAIL, // operation failed, should never occur
PROTOCOL_REGISTERED,
PROTOCOL_NOT_REGISTERED,
@@ -62,13 +62,14 @@ class Protocol : public mate::TrackableObject<Protocol> {
// The protocol handler that will create a protocol handler for certain
// request job.
template <typename RequestJob>
template<typename RequestJob>
class CustomProtocolHandler
: public net::URLRequestJobFactory::ProtocolHandler {
public:
CustomProtocolHandler(v8::Isolate* isolate,
net::URLRequestContextGetter* request_context,
const Handler& handler)
CustomProtocolHandler(
v8::Isolate* isolate,
net::URLRequestContextGetter* request_context,
const Handler& handler)
: isolate_(isolate),
request_context_(request_context),
handler_(handler) {}
@@ -78,13 +79,13 @@ class Protocol : public mate::TrackableObject<Protocol> {
net::URLRequest* request,
net::NetworkDelegate* network_delegate) const override {
RequestJob* request_job = new RequestJob(request, network_delegate);
request_job->SetHandlerInfo(isolate_, request_context_, handler_);
request_job->SetHandlerInfo(isolate_, request_context_.get(), handler_);
return request_job;
}
private:
v8::Isolate* isolate_;
net::URLRequestContextGetter* request_context_;
scoped_refptr<net::URLRequestContextGetter> request_context_;
Protocol::Handler handler_;
DISALLOW_COPY_AND_ASSIGN(CustomProtocolHandler);
@@ -94,31 +95,32 @@ class Protocol : public mate::TrackableObject<Protocol> {
void RegisterServiceWorkerSchemes(const std::vector<std::string>& schemes);
// Register the protocol with certain request job.
template <typename RequestJob>
template<typename RequestJob>
void RegisterProtocol(const std::string& scheme,
const Handler& handler,
mate::Arguments* args) {
CompletionCallback callback;
args->GetNext(&callback);
auto* getter = 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));
base::Bind(&Protocol::RegisterProtocolInIO<RequestJob>,
request_context_getter_, isolate(), scheme, handler),
base::Bind(&Protocol::OnIOCompleted,
GetWeakPtr(), callback));
}
template <typename RequestJob>
template<typename RequestJob>
static ProtocolError RegisterProtocolInIO(
scoped_refptr<brightray::URLRequestContextGetter> request_context_getter,
v8::Isolate* isolate,
const std::string& scheme,
const Handler& handler) {
auto* job_factory = static_cast<AtomURLRequestJobFactory*>(
auto job_factory = static_cast<AtomURLRequestJobFactory*>(
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);
std::unique_ptr<CustomProtocolHandler<RequestJob>> protocol_handler(
new CustomProtocolHandler<RequestJob>(
isolate, request_context_getter.get(), handler));
if (job_factory->SetProtocolHandler(scheme, std::move(protocol_handler)))
return PROTOCOL_OK;
else
@@ -139,34 +141,35 @@ class Protocol : public mate::TrackableObject<Protocol> {
const std::string& scheme);
// Replace the protocol handler with a new one.
template <typename RequestJob>
template<typename RequestJob>
void InterceptProtocol(const std::string& scheme,
const Handler& handler,
mate::Arguments* args) {
CompletionCallback callback;
args->GetNext(&callback);
auto* getter = 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));
base::Bind(&Protocol::InterceptProtocolInIO<RequestJob>,
request_context_getter_, isolate(), scheme, handler),
base::Bind(&Protocol::OnIOCompleted,
GetWeakPtr(), callback));
}
template <typename RequestJob>
template<typename RequestJob>
static ProtocolError InterceptProtocolInIO(
scoped_refptr<brightray::URLRequestContextGetter> request_context_getter,
v8::Isolate* isolate,
const std::string& scheme,
const Handler& handler) {
auto* job_factory = static_cast<AtomURLRequestJobFactory*>(
auto job_factory = static_cast<AtomURLRequestJobFactory*>(
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);
std::unique_ptr<CustomProtocolHandler<RequestJob>> protocol_handler(
new CustomProtocolHandler<RequestJob>(
isolate, request_context_getter.get(), handler));
if (!job_factory->InterceptProtocol(scheme, std::move(protocol_handler)))
return PROTOCOL_INTERCEPTED;
return PROTOCOL_OK;
@@ -184,9 +187,13 @@ class Protocol : public mate::TrackableObject<Protocol> {
// Convert error code to string.
std::string ErrorCodeToString(ProtocolError error);
base::WeakPtr<Protocol> GetWeakPtr() { return weak_factory_.GetWeakPtr(); }
AtomURLRequestJobFactory* GetJobFactoryInIO() const;
scoped_refptr<AtomBrowserContext> browser_context_;
base::WeakPtr<Protocol> GetWeakPtr() {
return weak_factory_.GetWeakPtr();
}
scoped_refptr<brightray::URLRequestContextGetter> request_context_getter_;
base::WeakPtrFactory<Protocol> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(Protocol);

View File

@@ -21,8 +21,8 @@ namespace {
bool IsWebContents(v8::Isolate* isolate, content::RenderProcessHost* process) {
content::WebContents* web_contents =
static_cast<AtomBrowserClient*>(AtomBrowserClient::Get())
->GetWebContentsFromProcessID(process->GetID());
static_cast<AtomBrowserClient*>(AtomBrowserClient::Get())->
GetWebContentsFromProcessID(process->GetID());
if (!web_contents)
return false;
@@ -41,7 +41,8 @@ RenderProcessPreferences::RenderProcessPreferences(
Init(isolate);
}
RenderProcessPreferences::~RenderProcessPreferences() {}
RenderProcessPreferences::~RenderProcessPreferences() {
}
int RenderProcessPreferences::AddEntry(const base::DictionaryValue& entry) {
return preferences_.AddEntry(entry);
@@ -53,8 +54,7 @@ void RenderProcessPreferences::RemoveEntry(int id) {
// static
void RenderProcessPreferences::BuildPrototype(
v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype) {
v8::Isolate* isolate, v8::Local<v8::FunctionTemplate> prototype) {
prototype->SetClassName(
mate::StringToV8(isolate, "RenderProcessPreferences"));
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
@@ -65,9 +65,10 @@ void RenderProcessPreferences::BuildPrototype(
// static
mate::Handle<RenderProcessPreferences>
RenderProcessPreferences::ForAllWebContents(v8::Isolate* isolate) {
return mate::CreateHandle(isolate,
new RenderProcessPreferences(
isolate, base::Bind(&IsWebContents, isolate)));
return mate::CreateHandle(
isolate,
new RenderProcessPreferences(isolate,
base::Bind(&IsWebContents, isolate)));
}
} // namespace api
@@ -76,10 +77,8 @@ RenderProcessPreferences::ForAllWebContents(v8::Isolate* isolate) {
namespace {
void Initialize(v8::Local<v8::Object> exports,
v8::Local<v8::Value> unused,
v8::Local<v8::Context> context,
void* priv) {
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);
@@ -87,5 +86,5 @@ void Initialize(v8::Local<v8::Object> exports,
} // namespace
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_render_process_preferences,
NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_render_process_preferences,
Initialize)

View File

@@ -16,8 +16,8 @@ namespace api {
class RenderProcessPreferences
: public mate::Wrappable<RenderProcessPreferences> {
public:
static mate::Handle<RenderProcessPreferences> ForAllWebContents(
v8::Isolate* isolate);
static mate::Handle<RenderProcessPreferences>
ForAllWebContents(v8::Isolate* isolate);
static void BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype);

View File

@@ -7,7 +7,6 @@
#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"
@@ -17,10 +16,6 @@
#include "ui/display/screen.h"
#include "ui/gfx/geometry/point.h"
#if defined(OS_WIN)
#include "ui/display/win/screen_win.h"
#endif
#include "atom/common/node_includes.h"
namespace atom {
@@ -30,9 +25,9 @@ namespace api {
namespace {
// Find an item in container according to its ID.
template <class T>
template<class T>
typename T::iterator FindById(T* container, int id) {
auto predicate = [id](const typename T::value_type& item) -> bool {
auto predicate = [id] (const typename T::value_type& item) -> bool {
return item.id() == id;
};
return std::find_if(container->begin(), container->end(), predicate);
@@ -84,22 +79,6 @@ display::Display Screen::GetDisplayMatching(const gfx::Rect& match_rect) {
return screen_->GetDisplayMatching(match_rect);
}
#if defined(OS_WIN)
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(atom::NativeWindow* window,
const gfx::Rect& rect) {
HWND hwnd = window ? window->GetAcceleratedWidget() : nullptr;
return display::win::ScreenWin::DIPToScreenRect(hwnd, rect);
}
#endif
void Screen::OnDisplayAdded(const display::Display& new_display) {
Emit("display-added", new_display);
}
@@ -117,14 +96,15 @@ void Screen::OnDisplayMetricsChanged(const display::Display& display,
v8::Local<v8::Value> Screen::Create(v8::Isolate* isolate) {
if (!Browser::Get()->is_ready()) {
isolate->ThrowException(v8::Exception::Error(mate::StringToV8(
isolate, "Cannot require \"screen\" module before app is ready")));
isolate,
"Cannot require \"screen\" module before app is ready")));
return v8::Null(isolate);
}
display::Screen* screen = display::Screen::GetScreen();
if (!screen) {
isolate->ThrowException(v8::Exception::Error(
mate::StringToV8(isolate, "Failed to get screen information")));
isolate->ThrowException(v8::Exception::Error(mate::StringToV8(
isolate, "Failed to get screen information")));
return v8::Null(isolate);
}
@@ -132,20 +112,14 @@ v8::Local<v8::Value> Screen::Create(v8::Isolate* isolate) {
}
// static
void Screen::BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype) {
void Screen::BuildPrototype(
v8::Isolate* isolate, v8::Local<v8::FunctionTemplate> prototype) {
prototype->SetClassName(mate::StringToV8(isolate, "Screen"));
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
.SetMethod("getCursorScreenPoint", &Screen::GetCursorScreenPoint)
.SetMethod("getPrimaryDisplay", &Screen::GetPrimaryDisplay)
.SetMethod("getAllDisplays", &Screen::GetAllDisplays)
.SetMethod("getDisplayNearestPoint", &Screen::GetDisplayNearestPoint)
#if defined(OS_WIN)
.SetMethod("screenToDipPoint", &display::win::ScreenWin::ScreenToDIPPoint)
.SetMethod("dipToScreenPoint", &display::win::ScreenWin::DIPToScreenPoint)
.SetMethod("screenToDipRect", &ScreenToDIPRect)
.SetMethod("dipToScreenRect", &DIPToScreenRect)
#endif
.SetMethod("getDisplayMatching", &Screen::GetDisplayMatching);
}
@@ -157,10 +131,8 @@ namespace {
using atom::api::Screen;
void Initialize(v8::Local<v8::Object> exports,
v8::Local<v8::Value> unused,
v8::Local<v8::Context> context,
void* priv) {
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("screen", Screen::Create(isolate));
@@ -169,4 +141,4 @@ void Initialize(v8::Local<v8::Object> exports,
} // namespace
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_common_screen, Initialize)
NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_common_screen, Initialize)

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