@cometchat/calls-sdk-react-native 4.4.1 → 5.0.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +85 -19
- package/android/.gradle/8.9/checksums/checksums.lock +0 -0
- package/android/.gradle/8.9/dependencies-accessors/gc.properties +0 -0
- package/android/.gradle/8.9/fileChanges/last-build.bin +0 -0
- package/android/.gradle/8.9/fileHashes/fileHashes.lock +0 -0
- package/android/.gradle/8.9/gc.properties +0 -0
- package/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock +0 -0
- package/android/.gradle/buildOutputCleanup/cache.properties +2 -0
- package/android/.gradle/vcs-1/gc.properties +0 -0
- package/android/build.gradle +13 -12
- package/android/src/main/AndroidManifest.xml +15 -6
- package/android/src/main/java/com/callingv5/AudioDeviceHandlerConnectionService.java +185 -0
- package/android/src/main/java/com/callingv5/AudioDeviceHandlerGeneric.java +254 -0
- package/android/src/main/java/com/{CometChatCalls → callingv5}/AudioModeModule.java +93 -56
- package/android/src/main/java/com/callingv5/ConnectionService.java +451 -0
- package/android/src/main/java/com/callingv5/KeepAwakeModule.java +53 -0
- package/android/src/main/java/com/callingv5/MyAppPackage.java +35 -0
- package/android/src/main/java/com/callingv5/RNConnectionService.java +244 -0
- package/android/src/main/java/com/callingv5/ToastModule.java +29 -0
- package/android/src/main/java/com/callingv5/utils/CometChatLogger.java +88 -0
- package/dist/index.d.mts +3940 -0
- package/dist/index.d.ts +3940 -9
- package/dist/index.js +10990 -127
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +10959 -0
- package/dist/index.mjs.map +1 -0
- package/dist/polyfills/RTCPeerConnection.js +19 -0
- package/dist/polyfills/Storage.js +192 -0
- package/dist/polyfills/browser.js +337 -0
- package/dist/polyfills/index.js +1 -0
- package/dist/polyfills/ipv6utils.js +197 -0
- package/dist/polyfills/webrtc.js +11 -0
- package/package.json +18 -110
- package/LICENSE.md +0 -3
- package/android/src/main/java/com/CometChatCalls/AudioDeviceHandlerGeneric.java +0 -213
- package/android/src/main/java/com/CometChatCalls/AudioDeviceHandlerLegacy.java +0 -213
- package/android/src/main/java/com/CometChatCalls/BluetoothHeadsetMonitor.java +0 -187
- package/android/src/main/java/com/CometChatCalls/CallNotificationService.java +0 -93
- package/android/src/main/java/com/CometChatCalls/CallNotificationServiceModule.java +0 -48
- package/android/src/main/java/com/CometChatCalls/CometChatCallsPackage.java +0 -56
- package/android/src/main/java/com/CometChatCalls/CometChatCommonModule.java +0 -48
- package/android/src/main/java/com/CometChatCalls/PictureInPictureModule.java +0 -133
- package/android/src/main/res/drawable-mdpi/callingcomponent_icons_headphones_pluged.png +0 -0
- package/cometchat-calls-sdk-react-native.podspec +0 -21
- package/dist/CometChatErrorConstants.d.ts +0 -124
- package/dist/Constants.d.ts +0 -724
- package/dist/Helper copy.d.ts +0 -1
- package/dist/Helper.d.ts +0 -7
- package/dist/api/APIHandler.d.ts +0 -42
- package/dist/api/endpoints.d.ts +0 -7
- package/dist/api/helper.d.ts +0 -69
- package/dist/api/index.d.ts +0 -2
- package/dist/constants/CallConstants.d.ts +0 -136
- package/dist/constants/index.d.ts +0 -1
- package/dist/defaultCallsettings.d.ts +0 -2
- package/dist/models/CallAppSettings.d.ts +0 -42
- package/dist/models/CallGroup.d.ts +0 -14
- package/dist/models/CallLog.d.ts +0 -276
- package/dist/models/CallLogFilterParams.d.ts +0 -97
- package/dist/models/CallSettings.d.ts +0 -330
- package/dist/models/CallUser.d.ts +0 -14
- package/dist/models/CometChatCallLogs.d.ts +0 -193
- package/dist/models/CometChatCalls.d.ts +0 -110
- package/dist/models/CometChatCallsComponent.d.ts +0 -13
- package/dist/models/CometChatCallsComponentCore.d.ts +0 -18
- package/dist/models/CometChatCallsException.d.ts +0 -7
- package/dist/models/CometChatPresenterComponent.d.ts +0 -13
- package/dist/models/ErrorModel.d.ts +0 -11
- package/dist/models/Listner.d.ts +0 -69
- package/dist/models/ListnerHandler.d.ts +0 -10
- package/dist/models/MessageComponent.d.ts +0 -7
- package/dist/models/Participant.d.ts +0 -184
- package/dist/models/PresenterSettings.d.ts +0 -208
- package/dist/models/RTCUser.d.ts +0 -18
- package/dist/models/Recording.d.ts +0 -86
- package/dist/models/index.d.ts +0 -9
- package/dist/types/ICallAppSettings.d.ts +0 -6
- package/dist/types/ICallSettings.d.ts +0 -61
- package/dist/types/RTCUser.d.ts +0 -6
- package/dist/types/callEvents.d.ts +0 -54
- package/dist/types/common.d.ts +0 -18
- package/dist/types/index.d.ts +0 -2
- package/ios/AudioMode.h +0 -11
- package/ios/AudioMode.m +0 -418
- package/ios/CometChatCommonModule.h +0 -6
- package/ios/CometChatCommonModule.m +0 -29
- package/ios/JitsiAudioSession+Private.h +0 -25
- package/ios/JitsiAudioSession.h +0 -17
- package/ios/JitsiAudioSession.m +0 -34
- package/ios/LogUtils.h +0 -23
- package/ios/react-native-calls2.xcodeproj/project.pbxproj +0 -269
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
import { NativeModules } from 'react-native';
|
|
2
|
+
import { RTCSessionDescription } from 'react-native-webrtc';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Synthesizes IPv6 addresses on iOS in order to support IPv6 NAT64 networks.
|
|
6
|
+
*
|
|
7
|
+
* @param {RTCSessionDescription} sdp - The RTCSessionDescription which
|
|
8
|
+
* specifies the configuration of the remote end of the connection.
|
|
9
|
+
* @private
|
|
10
|
+
* @returns {Promise}
|
|
11
|
+
*/
|
|
12
|
+
export function synthesizeIPv6Addresses(sdp) {
|
|
13
|
+
return (
|
|
14
|
+
new Promise(resolve => resolve(_synthesizeIPv6Addresses0(sdp)))
|
|
15
|
+
.then(({ ips, lines }) =>
|
|
16
|
+
Promise.all(Array.from(ips.values()))
|
|
17
|
+
.then(() => _synthesizeIPv6Addresses1(sdp, ips, lines))
|
|
18
|
+
));
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/* eslint-disable max-depth */
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Synthesizes an IPv6 address from a specific IPv4 address.
|
|
25
|
+
*
|
|
26
|
+
* @param {string} ipv4 - The IPv4 address from which an IPv6 address is to be
|
|
27
|
+
* synthesized.
|
|
28
|
+
* @returns {Promise<?string>} A {@code Promise} which gets resolved with the
|
|
29
|
+
* IPv6 address synthesized from the specified {@code ipv4} or a falsy value to
|
|
30
|
+
* be treated as inability to synthesize an IPv6 address from the specified
|
|
31
|
+
* {@code ipv4}.
|
|
32
|
+
*/
|
|
33
|
+
const _synthesizeIPv6FromIPv4Address = (function() {
|
|
34
|
+
// POSIX.getaddrinfo
|
|
35
|
+
const { POSIX } = NativeModules;
|
|
36
|
+
|
|
37
|
+
if (POSIX) {
|
|
38
|
+
const { getaddrinfo } = POSIX;
|
|
39
|
+
|
|
40
|
+
if (typeof getaddrinfo === 'function') {
|
|
41
|
+
return ipv4 =>
|
|
42
|
+
getaddrinfo(/* hostname */ ipv4, /* servname */ undefined)
|
|
43
|
+
.then(([ { ai_addr: ipv6 } ]) => ipv6);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// NAT64AddrInfo.getIPv6Address
|
|
48
|
+
const { NAT64AddrInfo } = NativeModules;
|
|
49
|
+
|
|
50
|
+
if (NAT64AddrInfo) {
|
|
51
|
+
const { getIPv6Address } = NAT64AddrInfo;
|
|
52
|
+
|
|
53
|
+
if (typeof getIPv6Address === 'function') {
|
|
54
|
+
return getIPv6Address;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// There's no POSIX.getaddrinfo or NAT64AddrInfo.getIPv6Address.
|
|
59
|
+
return ip => Promise.resolve(ip);
|
|
60
|
+
})();
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Begins the asynchronous synthesis of IPv6 addresses.
|
|
64
|
+
*
|
|
65
|
+
* @param {RTCSessionDescription} sessionDescription - The RTCSessionDescription
|
|
66
|
+
* for which IPv6 addresses will be synthesized.
|
|
67
|
+
* @private
|
|
68
|
+
* @returns {{
|
|
69
|
+
* ips: Map,
|
|
70
|
+
* lines: Array
|
|
71
|
+
* }}
|
|
72
|
+
*/
|
|
73
|
+
function _synthesizeIPv6Addresses0(sessionDescription) {
|
|
74
|
+
const sdp = sessionDescription.sdp;
|
|
75
|
+
let start = 0;
|
|
76
|
+
const lines = [];
|
|
77
|
+
const ips = new Map();
|
|
78
|
+
|
|
79
|
+
do {
|
|
80
|
+
const end = sdp.indexOf('\r\n', start);
|
|
81
|
+
let line;
|
|
82
|
+
|
|
83
|
+
if (end === -1) {
|
|
84
|
+
line = sdp.substring(start);
|
|
85
|
+
|
|
86
|
+
// Break out of the loop at the end of the iteration.
|
|
87
|
+
start = undefined;
|
|
88
|
+
} else {
|
|
89
|
+
line = sdp.substring(start, end);
|
|
90
|
+
start = end + 2;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if (line.startsWith('a=candidate:')) {
|
|
94
|
+
const candidate = line.split(' ');
|
|
95
|
+
|
|
96
|
+
if (candidate.length >= 10 && candidate[6] === 'typ') {
|
|
97
|
+
const ip4s = [ candidate[4] ];
|
|
98
|
+
let abort = false;
|
|
99
|
+
|
|
100
|
+
for (let i = 8; i < candidate.length; ++i) {
|
|
101
|
+
if (candidate[i] === 'raddr') {
|
|
102
|
+
ip4s.push(candidate[++i]);
|
|
103
|
+
break;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
for (const ip of ip4s) {
|
|
108
|
+
if (ip.indexOf(':') === -1) {
|
|
109
|
+
ips.has(ip)
|
|
110
|
+
|| ips.set(ip, new Promise((resolve, reject) => {
|
|
111
|
+
const v = ips.get(ip);
|
|
112
|
+
|
|
113
|
+
if (v && typeof v === 'string') {
|
|
114
|
+
resolve(v);
|
|
115
|
+
} else {
|
|
116
|
+
_synthesizeIPv6FromIPv4Address(ip).then(
|
|
117
|
+
value => {
|
|
118
|
+
if (!value
|
|
119
|
+
|| value.indexOf(':') === -1
|
|
120
|
+
|| value === ips.get(ip)) {
|
|
121
|
+
ips.delete(ip);
|
|
122
|
+
} else {
|
|
123
|
+
ips.set(ip, value);
|
|
124
|
+
}
|
|
125
|
+
resolve(value);
|
|
126
|
+
},
|
|
127
|
+
reject);
|
|
128
|
+
}
|
|
129
|
+
}));
|
|
130
|
+
} else {
|
|
131
|
+
abort = true;
|
|
132
|
+
break;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
if (abort) {
|
|
136
|
+
ips.clear();
|
|
137
|
+
break;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
line = candidate;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
lines.push(line);
|
|
145
|
+
} while (start);
|
|
146
|
+
|
|
147
|
+
return {
|
|
148
|
+
ips,
|
|
149
|
+
lines
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/* eslint-enable max-depth */
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Completes the asynchronous synthesis of IPv6 addresses.
|
|
157
|
+
*
|
|
158
|
+
* @param {RTCSessionDescription} sessionDescription - The RTCSessionDescription
|
|
159
|
+
* for which IPv6 addresses are being synthesized.
|
|
160
|
+
* @param {Map} ips - A Map of IPv4 addresses found in the specified
|
|
161
|
+
* sessionDescription to synthesized IPv6 addresses.
|
|
162
|
+
* @param {Array} lines - The lines of the specified sessionDescription.
|
|
163
|
+
* @private
|
|
164
|
+
* @returns {RTCSessionDescription} A RTCSessionDescription that represents the
|
|
165
|
+
* result of the synthesis of IPv6 addresses.
|
|
166
|
+
*/
|
|
167
|
+
function _synthesizeIPv6Addresses1(sessionDescription, ips, lines) {
|
|
168
|
+
if (ips.size === 0) {
|
|
169
|
+
return sessionDescription;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
for (let l = 0; l < lines.length; ++l) {
|
|
173
|
+
const candidate = lines[l];
|
|
174
|
+
|
|
175
|
+
if (typeof candidate !== 'string') {
|
|
176
|
+
let ip4 = candidate[4];
|
|
177
|
+
let ip6 = ips.get(ip4);
|
|
178
|
+
|
|
179
|
+
ip6 && (candidate[4] = ip6);
|
|
180
|
+
|
|
181
|
+
for (let i = 8; i < candidate.length; ++i) {
|
|
182
|
+
if (candidate[i] === 'raddr') {
|
|
183
|
+
ip4 = candidate[++i];
|
|
184
|
+
(ip6 = ips.get(ip4)) && (candidate[i] = ip6);
|
|
185
|
+
break;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
lines[l] = candidate.join(' ');
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
return new RTCSessionDescription({
|
|
194
|
+
sdp: lines.join('\r\n'),
|
|
195
|
+
type: sessionDescription.type
|
|
196
|
+
});
|
|
197
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { registerGlobals } from 'react-native-webrtc';
|
|
2
|
+
|
|
3
|
+
import RTCPeerConnection from './RTCPeerConnection';
|
|
4
|
+
|
|
5
|
+
registerGlobals();
|
|
6
|
+
|
|
7
|
+
(global => {
|
|
8
|
+
// Override with ours.
|
|
9
|
+
// TODO: consider dropping our override.
|
|
10
|
+
global.RTCPeerConnection = RTCPeerConnection;
|
|
11
|
+
})(global || window || this); // eslint-disable-line no-invalid-this
|
package/package.json
CHANGED
|
@@ -1,119 +1,27 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cometchat/calls-sdk-react-native",
|
|
3
|
-
"version": "
|
|
4
|
-
"
|
|
3
|
+
"version": "5.0.0-beta.1",
|
|
4
|
+
"private": false,
|
|
5
5
|
"main": "dist/index.js",
|
|
6
|
-
"module": "dist/index.
|
|
7
|
-
"types": "dist/index.d.
|
|
8
|
-
"scripts": {
|
|
9
|
-
"start": "webpack --mode development",
|
|
10
|
-
"build": "webpack --mode production",
|
|
11
|
-
"test": "jest",
|
|
12
|
-
"typescript": "tsc --noEmit",
|
|
13
|
-
"lint": "eslint \"**/*.{js,ts,tsx}\"",
|
|
14
|
-
"release": "release-it",
|
|
15
|
-
"example": "yarn --cwd example",
|
|
16
|
-
"pods": "cd example && pod-install --quiet",
|
|
17
|
-
"bootstrap": "yarn example && yarn && yarn pods",
|
|
18
|
-
"buildold": "rm -rf package && tsc && cp src/calling.js package/calling.js"
|
|
19
|
-
},
|
|
6
|
+
"module": "dist/index.mjs",
|
|
7
|
+
"types": "dist/index.d.mts",
|
|
20
8
|
"files": [
|
|
21
|
-
"
|
|
22
|
-
"android/build.gradle",
|
|
23
|
-
"dist/",
|
|
24
|
-
"ios/",
|
|
25
|
-
"cometchat-calls-sdk-react-native.podspec"
|
|
26
|
-
],
|
|
27
|
-
"keywords": [
|
|
28
|
-
"react-native",
|
|
29
|
-
"ios",
|
|
9
|
+
"dist",
|
|
30
10
|
"android"
|
|
31
11
|
],
|
|
32
|
-
"
|
|
33
|
-
"
|
|
34
|
-
"
|
|
35
|
-
"homepage": "https://www.cometchat.com/docs/sdk/react-native/calling-overview",
|
|
36
|
-
"publishConfig": {
|
|
37
|
-
"registry": "https://registry.npmjs.org/"
|
|
38
|
-
},
|
|
39
|
-
"devDependencies": {
|
|
40
|
-
"@types/react": "^17.0.53",
|
|
41
|
-
"babel-loader": "^8.0.4",
|
|
42
|
-
"esbuild-loader": "^2.19.0",
|
|
43
|
-
"react": "^17.0.2",
|
|
44
|
-
"react-native": "^0.66.5",
|
|
45
|
-
"ts-loader": "^9.4.2",
|
|
46
|
-
"typescript": "^4.9.5",
|
|
47
|
-
"typescript-declaration-webpack-plugin": "^0.2.2",
|
|
48
|
-
"webpack": "^5.75.0",
|
|
49
|
-
"webpack-cli": "^5.0.1"
|
|
50
|
-
},
|
|
12
|
+
"scripts": {},
|
|
13
|
+
"dependencies": {},
|
|
14
|
+
"devDependencies": {},
|
|
51
15
|
"peerDependencies": {
|
|
52
|
-
"
|
|
53
|
-
"
|
|
54
|
-
"
|
|
55
|
-
"
|
|
56
|
-
"
|
|
57
|
-
"
|
|
58
|
-
"
|
|
59
|
-
},
|
|
60
|
-
"
|
|
61
|
-
"
|
|
62
|
-
"modulePathIgnorePatterns": [
|
|
63
|
-
"<rootDir>/example/node_modules",
|
|
64
|
-
"<rootDir>/lib/"
|
|
65
|
-
]
|
|
66
|
-
},
|
|
67
|
-
"commitlint": {
|
|
68
|
-
"extends": [
|
|
69
|
-
"@commitlint/config-conventional"
|
|
70
|
-
]
|
|
71
|
-
},
|
|
72
|
-
"release-it": {
|
|
73
|
-
"git": {
|
|
74
|
-
"commitMessage": "chore: release ${version}",
|
|
75
|
-
"tagName": "v${version}"
|
|
76
|
-
},
|
|
77
|
-
"npm": {
|
|
78
|
-
"publish": true
|
|
79
|
-
},
|
|
80
|
-
"github": {
|
|
81
|
-
"release": true
|
|
82
|
-
},
|
|
83
|
-
"plugins": {
|
|
84
|
-
"@release-it/conventional-changelog": {
|
|
85
|
-
"preset": "angular"
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
},
|
|
89
|
-
"eslintConfig": {
|
|
90
|
-
"root": true,
|
|
91
|
-
"extends": [
|
|
92
|
-
"@react-native-community",
|
|
93
|
-
"prettier"
|
|
94
|
-
],
|
|
95
|
-
"rules": {
|
|
96
|
-
"prettier/prettier": [
|
|
97
|
-
"error",
|
|
98
|
-
{
|
|
99
|
-
"quoteProps": "consistent",
|
|
100
|
-
"singleQuote": true,
|
|
101
|
-
"tabWidth": 2,
|
|
102
|
-
"trailingComma": "es5",
|
|
103
|
-
"useTabs": false
|
|
104
|
-
}
|
|
105
|
-
]
|
|
106
|
-
}
|
|
107
|
-
},
|
|
108
|
-
"eslintIgnore": [
|
|
109
|
-
"node_modules/",
|
|
110
|
-
"lib/"
|
|
111
|
-
],
|
|
112
|
-
"prettier": {
|
|
113
|
-
"quoteProps": "consistent",
|
|
114
|
-
"singleQuote": true,
|
|
115
|
-
"tabWidth": 2,
|
|
116
|
-
"trailingComma": "es5",
|
|
117
|
-
"useTabs": false
|
|
16
|
+
"@xmldom/xmldom": "^0.8.11",
|
|
17
|
+
"abab": "^2.0.6",
|
|
18
|
+
"clsx": "^2.1.1",
|
|
19
|
+
"promise.allsettled": "^1.0.7",
|
|
20
|
+
"text-encoding": "^0.7.0",
|
|
21
|
+
"valibot": "^1.2.0",
|
|
22
|
+
"lib-jitsi-meet": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1790.0.0+311766e3/lib-jitsi-meet.tgz"
|
|
23
|
+
},
|
|
24
|
+
"engines": {
|
|
25
|
+
"node": ">=18"
|
|
118
26
|
}
|
|
119
27
|
}
|
package/LICENSE.md
DELETED
|
@@ -1,213 +0,0 @@
|
|
|
1
|
-
package com.CometChatCalls;
|
|
2
|
-
import android.annotation.TargetApi;
|
|
3
|
-
import android.media.AudioDeviceInfo;
|
|
4
|
-
import android.media.AudioManager;
|
|
5
|
-
import android.os.Build;
|
|
6
|
-
import android.util.Log;
|
|
7
|
-
|
|
8
|
-
import java.util.HashSet;
|
|
9
|
-
import java.util.Set;
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* {@link AudioModeModule.AudioDeviceHandlerInterface} module implementing device handling for
|
|
15
|
-
* all post-M Android versions. This handler can be used on any Android versions >= M, but by
|
|
16
|
-
* default it's only used on versions < O, since versions >= O use ConnectionService, but it
|
|
17
|
-
* can be disabled.
|
|
18
|
-
*/
|
|
19
|
-
@TargetApi(Build.VERSION_CODES.M)
|
|
20
|
-
class AudioDeviceHandlerGeneric implements
|
|
21
|
-
AudioModeModule.AudioDeviceHandlerInterface,
|
|
22
|
-
AudioManager.OnAudioFocusChangeListener {
|
|
23
|
-
|
|
24
|
-
private final static String TAG = AudioDeviceHandlerGeneric.class.getSimpleName();
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Reference to the main {@code AudioModeModule}.
|
|
28
|
-
*/
|
|
29
|
-
private AudioModeModule module;
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Constant defining a USB headset. Only available on API level >= 26.
|
|
33
|
-
* The value of: AudioDeviceInfo.TYPE_USB_HEADSET
|
|
34
|
-
*/
|
|
35
|
-
private static final int TYPE_USB_HEADSET = 22;
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Indicator that we have lost audio focus.
|
|
39
|
-
*/
|
|
40
|
-
private boolean audioFocusLost = false;
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* {@link AudioManager} instance used to interact with the Android audio
|
|
44
|
-
* subsystem.
|
|
45
|
-
*/
|
|
46
|
-
private AudioManager audioManager;
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* {@link Runnable} for running audio device detection the main thread.
|
|
50
|
-
* This is only used on Android >= M.
|
|
51
|
-
*/
|
|
52
|
-
private final Runnable onAudioDeviceChangeRunner = new Runnable() {
|
|
53
|
-
@Override
|
|
54
|
-
public void run() {
|
|
55
|
-
Set<String> devices = new HashSet<>();
|
|
56
|
-
AudioDeviceInfo[] deviceInfos = audioManager.getDevices(AudioManager.GET_DEVICES_OUTPUTS);
|
|
57
|
-
|
|
58
|
-
for (AudioDeviceInfo info: deviceInfos) {
|
|
59
|
-
switch (info.getType()) {
|
|
60
|
-
case AudioDeviceInfo.TYPE_BLUETOOTH_SCO:
|
|
61
|
-
devices.add(AudioModeModule.DEVICE_BLUETOOTH);
|
|
62
|
-
break;
|
|
63
|
-
case AudioDeviceInfo.TYPE_BUILTIN_EARPIECE:
|
|
64
|
-
devices.add(AudioModeModule.DEVICE_EARPIECE);
|
|
65
|
-
break;
|
|
66
|
-
case AudioDeviceInfo.TYPE_BUILTIN_SPEAKER:
|
|
67
|
-
devices.add(AudioModeModule.DEVICE_SPEAKER);
|
|
68
|
-
break;
|
|
69
|
-
case AudioDeviceInfo.TYPE_WIRED_HEADPHONES:
|
|
70
|
-
case AudioDeviceInfo.TYPE_WIRED_HEADSET:
|
|
71
|
-
case TYPE_USB_HEADSET:
|
|
72
|
-
devices.add(AudioModeModule.DEVICE_HEADPHONES);
|
|
73
|
-
break;
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
module.replaceDevices(devices);
|
|
78
|
-
|
|
79
|
-
Log.i(TAG , " Available audio devices: " + devices.toString());
|
|
80
|
-
|
|
81
|
-
module.updateAudioRoute();
|
|
82
|
-
}
|
|
83
|
-
};
|
|
84
|
-
|
|
85
|
-
private final android.media.AudioDeviceCallback audioDeviceCallback =
|
|
86
|
-
new android.media.AudioDeviceCallback() {
|
|
87
|
-
@Override
|
|
88
|
-
public void onAudioDevicesAdded(
|
|
89
|
-
AudioDeviceInfo[] addedDevices) {
|
|
90
|
-
Log.d(TAG , " Audio devices added");
|
|
91
|
-
onAudioDeviceChange();
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
@Override
|
|
95
|
-
public void onAudioDevicesRemoved(
|
|
96
|
-
AudioDeviceInfo[] removedDevices) {
|
|
97
|
-
Log.d(TAG , " Audio devices removed");
|
|
98
|
-
onAudioDeviceChange();
|
|
99
|
-
}
|
|
100
|
-
};
|
|
101
|
-
|
|
102
|
-
public AudioDeviceHandlerGeneric(AudioManager audioManager) {
|
|
103
|
-
this.audioManager = audioManager;
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
/**
|
|
107
|
-
* Helper method to trigger an audio route update when devices change. It
|
|
108
|
-
* makes sure the operation is performed on the audio thread.
|
|
109
|
-
*/
|
|
110
|
-
private void onAudioDeviceChange() {
|
|
111
|
-
module.runInAudioThread(onAudioDeviceChangeRunner);
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
/**
|
|
115
|
-
* {@link AudioManager.OnAudioFocusChangeListener} interface method. Called
|
|
116
|
-
* when the audio focus of the system is updated.
|
|
117
|
-
*
|
|
118
|
-
* @param focusChange - The type of focus change.
|
|
119
|
-
*/
|
|
120
|
-
@Override
|
|
121
|
-
public void onAudioFocusChange(final int focusChange) {
|
|
122
|
-
module.runInAudioThread(new Runnable() {
|
|
123
|
-
@Override
|
|
124
|
-
public void run() {
|
|
125
|
-
switch (focusChange) {
|
|
126
|
-
case AudioManager.AUDIOFOCUS_GAIN: {
|
|
127
|
-
Log.d(TAG , " Audio focus gained");
|
|
128
|
-
// Some other application potentially stole our audio focus
|
|
129
|
-
// temporarily. Restore our mode.
|
|
130
|
-
if (audioFocusLost) {
|
|
131
|
-
module.updateAudioRoute();
|
|
132
|
-
}
|
|
133
|
-
audioFocusLost = false;
|
|
134
|
-
break;
|
|
135
|
-
}
|
|
136
|
-
case AudioManager.AUDIOFOCUS_LOSS:
|
|
137
|
-
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
|
|
138
|
-
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK: {
|
|
139
|
-
Log.d(TAG , " Audio focus lost");
|
|
140
|
-
audioFocusLost = true;
|
|
141
|
-
break;
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
});
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
/**
|
|
149
|
-
* Helper method to set the output route to a Bluetooth device.
|
|
150
|
-
*
|
|
151
|
-
* @param enabled true if Bluetooth should use used, false otherwise.
|
|
152
|
-
*/
|
|
153
|
-
private void setBluetoothAudioRoute(boolean enabled) {
|
|
154
|
-
if (enabled) {
|
|
155
|
-
audioManager.startBluetoothSco();
|
|
156
|
-
audioManager.setBluetoothScoOn(true);
|
|
157
|
-
} else {
|
|
158
|
-
audioManager.setBluetoothScoOn(false);
|
|
159
|
-
audioManager.stopBluetoothSco();
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
@Override
|
|
164
|
-
public void start(AudioModeModule audioModeModule) {
|
|
165
|
-
Log.i("Using " , TAG + " as the audio device handler");
|
|
166
|
-
|
|
167
|
-
module = audioModeModule;
|
|
168
|
-
|
|
169
|
-
// Setup runtime device change detection.
|
|
170
|
-
audioManager.registerAudioDeviceCallback(audioDeviceCallback, null);
|
|
171
|
-
|
|
172
|
-
// Do an initial detection.
|
|
173
|
-
onAudioDeviceChange();
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
@Override
|
|
177
|
-
public void stop() {
|
|
178
|
-
audioManager.unregisterAudioDeviceCallback(audioDeviceCallback);
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
@Override
|
|
182
|
-
public void setAudioRoute(String device) {
|
|
183
|
-
// Turn speaker on / off
|
|
184
|
-
audioManager.setSpeakerphoneOn(device.equals(AudioModeModule.DEVICE_SPEAKER));
|
|
185
|
-
|
|
186
|
-
// Turn bluetooth on / off
|
|
187
|
-
setBluetoothAudioRoute(device.equals(AudioModeModule.DEVICE_BLUETOOTH));
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
@Override
|
|
191
|
-
public boolean setMode(int mode) {
|
|
192
|
-
if (mode == AudioModeModule.DEFAULT) {
|
|
193
|
-
audioFocusLost = false;
|
|
194
|
-
audioManager.setMode(AudioManager.MODE_NORMAL);
|
|
195
|
-
audioManager.abandonAudioFocus(this);
|
|
196
|
-
audioManager.setSpeakerphoneOn(false);
|
|
197
|
-
setBluetoothAudioRoute(false);
|
|
198
|
-
|
|
199
|
-
return true;
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
audioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
|
|
203
|
-
audioManager.setMicrophoneMute(false);
|
|
204
|
-
|
|
205
|
-
if (audioManager.requestAudioFocus(this, AudioManager.STREAM_VOICE_CALL, AudioManager.AUDIOFOCUS_GAIN)
|
|
206
|
-
== AudioManager.AUDIOFOCUS_REQUEST_FAILED) {
|
|
207
|
-
Log.w(TAG , " Audio focus request failed");
|
|
208
|
-
return false;
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
return true;
|
|
212
|
-
}
|
|
213
|
-
}
|