feat: expose system preferences to utility process (#42600)

* chore: expose  system preferences to utility process

* chore: add tests, doc changes and module-list update

* relative link

* use @

* fix test

* chore: disable linux test

* kick

* noop on windows utility process

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: George Xu <33054982+georgexu99@users.noreply.github.com>
This commit is contained in:
trop[bot] 2024-06-20 16:32:34 -04:00 committed by GitHub
parent 9c293834f1
commit 5dd6c0a51d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 29 additions and 5 deletions

View file

@ -2,7 +2,7 @@
> Get system preferences. > Get system preferences.
Process: [Main](../glossary.md#main-process) Process: [Main](../glossary.md#main-process), [Utility](../glossary.md#utility-process)
```js ```js
const { systemPreferences } = require('electron') const { systemPreferences } = require('electron')

View file

@ -350,6 +350,7 @@ auto_filenames = {
utility_bundle_deps = [ utility_bundle_deps = [
"lib/browser/api/net-fetch.ts", "lib/browser/api/net-fetch.ts",
"lib/browser/api/system-preferences.ts",
"lib/browser/message-port-main.ts", "lib/browser/message-port-main.ts",
"lib/common/api/net-client-request.ts", "lib/common/api/net-client-request.ts",
"lib/common/define-properties.ts", "lib/common/define-properties.ts",

View file

@ -1,4 +1,5 @@
// Utility side modules, please sort alphabetically. // Utility side modules, please sort alphabetically.
export const utilityNodeModuleList: ElectronInternal.ModuleEntry[] = [ export const utilityNodeModuleList: ElectronInternal.ModuleEntry[] = [
{ name: 'net', loader: () => require('./net') } { name: 'net', loader: () => require('./net') },
{ name: 'systemPreferences', loader: () => require('@electron/internal/browser/api/system-preferences') }
]; ];

View file

@ -159,6 +159,8 @@ std::string SystemPreferences::GetMediaAccessStatus(
} }
void SystemPreferences::InitializeWindow() { void SystemPreferences::InitializeWindow() {
if (electron::IsUtilityProcess())
return;
// Wait until app is ready before creating sys color listener // Wait until app is ready before creating sys color listener
// Creating this listener before the app is ready causes global shortcuts // Creating this listener before the app is ready causes global shortcuts
// to not fire // to not fire

View file

@ -100,9 +100,10 @@
V(electron_renderer_ipc) \ V(electron_renderer_ipc) \
V(electron_renderer_web_frame) V(electron_renderer_web_frame)
#define ELECTRON_UTILITY_BINDINGS(V) \ #define ELECTRON_UTILITY_BINDINGS(V) \
V(electron_browser_event_emitter) \ V(electron_browser_event_emitter) \
V(electron_common_net) \ V(electron_browser_system_preferences) \
V(electron_common_net) \
V(electron_utility_parent_port) V(electron_utility_parent_port)
#define ELECTRON_TESTING_BINDINGS(V) V(electron_common_testing) #define ELECTRON_TESTING_BINDINGS(V) V(electron_common_testing)

View file

@ -7,6 +7,7 @@ import { closeWindow } from './lib/window-helpers';
import { once } from 'node:events'; import { once } from 'node:events';
import { pathToFileURL } from 'node:url'; import { pathToFileURL } from 'node:url';
import { setImmediate } from 'node:timers/promises'; import { setImmediate } from 'node:timers/promises';
import { systemPreferences } from 'electron';
const fixturesPath = path.resolve(__dirname, 'fixtures', 'api', 'utility-process'); const fixturesPath = path.resolve(__dirname, 'fixtures', 'api', 'utility-process');
const isWindowsOnArm = process.platform === 'win32' && process.arch === 'arm64'; const isWindowsOnArm = process.platform === 'win32' && process.arch === 'arm64';
@ -386,6 +387,18 @@ describe('utilityProcess module', () => {
expect(output).to.include(result); expect(output).to.include(result);
}); });
ifit(process.platform !== 'linux')('can access exposed main process modules from the utility process', async () => {
const message = 'Message from utility process';
const child = utilityProcess.fork(path.join(fixturesPath, 'expose-main-process-module.js'));
await once(child, 'spawn');
child.postMessage(message);
const [data] = await once(child, 'message');
expect(data).to.equal(systemPreferences.getMediaAccessStatus('screen'));
const exit = once(child, 'exit');
expect(child.kill()).to.be.true();
await exit;
});
it('can establish communication channel with sandboxed renderer', async () => { it('can establish communication channel with sandboxed renderer', async () => {
const result = 'Message from sandboxed renderer'; const result = 'Message from sandboxed renderer';
const w = new BrowserWindow({ const w = new BrowserWindow({

View file

@ -0,0 +1,6 @@
const { systemPreferences } = require('electron');
const status = systemPreferences.getMediaAccessStatus('screen');
process.parentPort.on('message', () => {
process.parentPort.postMessage(status);
});