Skip to content

Commit a5e876e

Browse files
Release build 10.10.0 [ci release]
1 parent 04b8764 commit a5e876e

File tree

19 files changed

+1326
-115
lines changed

19 files changed

+1326
-115
lines changed

CHANGELOG.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1-
- Change condition return signature (#1809)
1+
- Device enum support (#1806)
2+
- build(deps): bump esbuild from 0.25.4 to 0.25.6 (#1815)

Sources/ContentScopeScripts/dist/contentScope.js

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4285,6 +4285,7 @@
42854285
var MSG_PERMISSIONS_QUERY = "permissionsQuery";
42864286
var MSG_SCREEN_LOCK = "screenLock";
42874287
var MSG_SCREEN_UNLOCK = "screenUnlock";
4288+
var MSG_DEVICE_ENUMERATION = "deviceEnumeration";
42884289
function canShare(data) {
42894290
if (typeof data !== "object") return false;
42904291
if (!("url" in data) && !("title" in data) && !("text" in data)) return false;
@@ -4376,6 +4377,9 @@
43764377
if (this.getFeatureSettingEnabled("disableDeviceEnumeration") || this.getFeatureSettingEnabled("disableDeviceEnumerationFrames")) {
43774378
this.preventDeviceEnumeration();
43784379
}
4380+
if (this.getFeatureSettingEnabled("enumerateDevices")) {
4381+
this.deviceEnumerationFix();
4382+
}
43794383
}
43804384
/** Shim Web Share API in Android WebView */
43814385
shimWebShare() {
@@ -4902,6 +4906,9 @@
49024906
this.forceViewportTag(viewportTag, newContent.join(", "));
49034907
}
49044908
}
4909+
/**
4910+
* Prevents device enumeration by returning an empty array when enabled
4911+
*/
49054912
preventDeviceEnumeration() {
49064913
if (!window.MediaDevices) {
49074914
return;
@@ -4915,13 +4922,112 @@
49154922
}
49164923
if (disableDeviceEnumeration) {
49174924
const enumerateDevicesProxy = new DDGProxy(this, MediaDevices.prototype, "enumerateDevices", {
4925+
/**
4926+
* @returns {Promise<MediaDeviceInfo[]>}
4927+
*/
49184928
apply() {
49194929
return Promise.resolve([]);
49204930
}
49214931
});
49224932
enumerateDevicesProxy.overload();
49234933
}
49244934
}
4935+
/**
4936+
* Creates a valid MediaDeviceInfo or InputDeviceInfo object that passes instanceof checks
4937+
* @param {'videoinput' | 'audioinput' | 'audiooutput'} kind - The device kind
4938+
* @returns {MediaDeviceInfo | InputDeviceInfo}
4939+
*/
4940+
createMediaDeviceInfo(kind) {
4941+
let deviceInfo;
4942+
if (kind === "videoinput" || kind === "audioinput") {
4943+
if (typeof InputDeviceInfo !== "undefined" && InputDeviceInfo.prototype) {
4944+
deviceInfo = Object.create(InputDeviceInfo.prototype);
4945+
} else {
4946+
deviceInfo = Object.create(MediaDeviceInfo.prototype);
4947+
}
4948+
} else {
4949+
deviceInfo = Object.create(MediaDeviceInfo.prototype);
4950+
}
4951+
Object.defineProperties(deviceInfo, {
4952+
deviceId: {
4953+
value: "default",
4954+
writable: false,
4955+
configurable: false,
4956+
enumerable: true
4957+
},
4958+
kind: {
4959+
value: kind,
4960+
writable: false,
4961+
configurable: false,
4962+
enumerable: true
4963+
},
4964+
label: {
4965+
value: "",
4966+
writable: false,
4967+
configurable: false,
4968+
enumerable: true
4969+
},
4970+
groupId: {
4971+
value: "default-group",
4972+
writable: false,
4973+
configurable: false,
4974+
enumerable: true
4975+
},
4976+
toJSON: {
4977+
value: function() {
4978+
return {
4979+
deviceId: this.deviceId,
4980+
kind: this.kind,
4981+
label: this.label,
4982+
groupId: this.groupId
4983+
};
4984+
},
4985+
writable: false,
4986+
configurable: false,
4987+
enumerable: true
4988+
}
4989+
});
4990+
return deviceInfo;
4991+
}
4992+
/**
4993+
* Fixes device enumeration to handle permission prompts gracefully
4994+
*/
4995+
deviceEnumerationFix() {
4996+
if (!window.MediaDevices) {
4997+
return;
4998+
}
4999+
const enumerateDevicesProxy = new DDGProxy(this, MediaDevices.prototype, "enumerateDevices", {
5000+
/**
5001+
* @param {MediaDevices['enumerateDevices']} target
5002+
* @param {MediaDevices} thisArg
5003+
* @param {Parameters<MediaDevices['enumerateDevices']>} args
5004+
* @returns {Promise<MediaDeviceInfo[]>}
5005+
*/
5006+
apply: async (target, thisArg, args) => {
5007+
try {
5008+
const response = await this.messaging.request(MSG_DEVICE_ENUMERATION, {});
5009+
if (response.willPrompt) {
5010+
const devices = [];
5011+
if (response.videoInput) {
5012+
devices.push(this.createMediaDeviceInfo("videoinput"));
5013+
}
5014+
if (response.audioInput) {
5015+
devices.push(this.createMediaDeviceInfo("audioinput"));
5016+
}
5017+
if (response.audioOutput) {
5018+
devices.push(this.createMediaDeviceInfo("audiooutput"));
5019+
}
5020+
return Promise.resolve(devices);
5021+
} else {
5022+
return DDGReflect.apply(target, thisArg, args);
5023+
}
5024+
} catch (err) {
5025+
return DDGReflect.apply(target, thisArg, args);
5026+
}
5027+
}
5028+
});
5029+
enumerateDevicesProxy.overload();
5030+
}
49255031
};
49265032
_activeShareRequest = new WeakMap();
49275033
_activeScreenLockRequest = new WeakMap();

build/android/contentScope.js

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6275,6 +6275,7 @@
62756275
var MSG_PERMISSIONS_QUERY = "permissionsQuery";
62766276
var MSG_SCREEN_LOCK = "screenLock";
62776277
var MSG_SCREEN_UNLOCK = "screenUnlock";
6278+
var MSG_DEVICE_ENUMERATION = "deviceEnumeration";
62786279
function canShare(data) {
62796280
if (typeof data !== "object") return false;
62806281
if (!("url" in data) && !("title" in data) && !("text" in data)) return false;
@@ -6366,6 +6367,9 @@
63666367
if (this.getFeatureSettingEnabled("disableDeviceEnumeration") || this.getFeatureSettingEnabled("disableDeviceEnumerationFrames")) {
63676368
this.preventDeviceEnumeration();
63686369
}
6370+
if (this.getFeatureSettingEnabled("enumerateDevices")) {
6371+
this.deviceEnumerationFix();
6372+
}
63696373
}
63706374
/** Shim Web Share API in Android WebView */
63716375
shimWebShare() {
@@ -6892,6 +6896,9 @@
68926896
this.forceViewportTag(viewportTag, newContent.join(", "));
68936897
}
68946898
}
6899+
/**
6900+
* Prevents device enumeration by returning an empty array when enabled
6901+
*/
68956902
preventDeviceEnumeration() {
68966903
if (!window.MediaDevices) {
68976904
return;
@@ -6905,13 +6912,112 @@
69056912
}
69066913
if (disableDeviceEnumeration) {
69076914
const enumerateDevicesProxy = new DDGProxy(this, MediaDevices.prototype, "enumerateDevices", {
6915+
/**
6916+
* @returns {Promise<MediaDeviceInfo[]>}
6917+
*/
69086918
apply() {
69096919
return Promise.resolve([]);
69106920
}
69116921
});
69126922
enumerateDevicesProxy.overload();
69136923
}
69146924
}
6925+
/**
6926+
* Creates a valid MediaDeviceInfo or InputDeviceInfo object that passes instanceof checks
6927+
* @param {'videoinput' | 'audioinput' | 'audiooutput'} kind - The device kind
6928+
* @returns {MediaDeviceInfo | InputDeviceInfo}
6929+
*/
6930+
createMediaDeviceInfo(kind) {
6931+
let deviceInfo;
6932+
if (kind === "videoinput" || kind === "audioinput") {
6933+
if (typeof InputDeviceInfo !== "undefined" && InputDeviceInfo.prototype) {
6934+
deviceInfo = Object.create(InputDeviceInfo.prototype);
6935+
} else {
6936+
deviceInfo = Object.create(MediaDeviceInfo.prototype);
6937+
}
6938+
} else {
6939+
deviceInfo = Object.create(MediaDeviceInfo.prototype);
6940+
}
6941+
Object.defineProperties(deviceInfo, {
6942+
deviceId: {
6943+
value: "default",
6944+
writable: false,
6945+
configurable: false,
6946+
enumerable: true
6947+
},
6948+
kind: {
6949+
value: kind,
6950+
writable: false,
6951+
configurable: false,
6952+
enumerable: true
6953+
},
6954+
label: {
6955+
value: "",
6956+
writable: false,
6957+
configurable: false,
6958+
enumerable: true
6959+
},
6960+
groupId: {
6961+
value: "default-group",
6962+
writable: false,
6963+
configurable: false,
6964+
enumerable: true
6965+
},
6966+
toJSON: {
6967+
value: function() {
6968+
return {
6969+
deviceId: this.deviceId,
6970+
kind: this.kind,
6971+
label: this.label,
6972+
groupId: this.groupId
6973+
};
6974+
},
6975+
writable: false,
6976+
configurable: false,
6977+
enumerable: true
6978+
}
6979+
});
6980+
return deviceInfo;
6981+
}
6982+
/**
6983+
* Fixes device enumeration to handle permission prompts gracefully
6984+
*/
6985+
deviceEnumerationFix() {
6986+
if (!window.MediaDevices) {
6987+
return;
6988+
}
6989+
const enumerateDevicesProxy = new DDGProxy(this, MediaDevices.prototype, "enumerateDevices", {
6990+
/**
6991+
* @param {MediaDevices['enumerateDevices']} target
6992+
* @param {MediaDevices} thisArg
6993+
* @param {Parameters<MediaDevices['enumerateDevices']>} args
6994+
* @returns {Promise<MediaDeviceInfo[]>}
6995+
*/
6996+
apply: async (target, thisArg, args) => {
6997+
try {
6998+
const response = await this.messaging.request(MSG_DEVICE_ENUMERATION, {});
6999+
if (response.willPrompt) {
7000+
const devices = [];
7001+
if (response.videoInput) {
7002+
devices.push(this.createMediaDeviceInfo("videoinput"));
7003+
}
7004+
if (response.audioInput) {
7005+
devices.push(this.createMediaDeviceInfo("audioinput"));
7006+
}
7007+
if (response.audioOutput) {
7008+
devices.push(this.createMediaDeviceInfo("audiooutput"));
7009+
}
7010+
return Promise.resolve(devices);
7011+
} else {
7012+
return DDGReflect.apply(target, thisArg, args);
7013+
}
7014+
} catch (err) {
7015+
return DDGReflect.apply(target, thisArg, args);
7016+
}
7017+
}
7018+
});
7019+
enumerateDevicesProxy.overload();
7020+
}
69157021
};
69167022
_activeShareRequest = new WeakMap();
69177023
_activeScreenLockRequest = new WeakMap();

0 commit comments

Comments
 (0)