Skip to content

Commit a49cfbc

Browse files
committed
android,ios: disallow changing cameras through apply constraints
1 parent 0c70bee commit a49cfbc

File tree

2 files changed

+49
-41
lines changed

2 files changed

+49
-41
lines changed

android/src/main/java/com/oney/WebRTCModule/CameraCaptureController.java

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import android.content.Context;
44
import android.hardware.camera2.CameraManager;
55
import android.util.Log;
6-
import android.util.Pair;
6+
77
import androidx.annotation.Nullable;
88
import androidx.core.util.Consumer;
99

@@ -31,6 +31,7 @@ public class CameraCaptureController extends AbstractVideoCaptureController {
3131

3232
private boolean isFrontFacing;
3333

34+
3435
/**
3536
* Equivalent to the camera index as a String
3637
*/
@@ -39,6 +40,9 @@ public class CameraCaptureController extends AbstractVideoCaptureController {
3940

4041
private final Context context;
4142
private final CameraEnumerator cameraEnumerator;
43+
44+
private final String constraintDeviceId;
45+
private final String constraintFacingMode;
4246
private ReadableMap constraints;
4347

4448
/**
@@ -62,6 +66,9 @@ public CameraCaptureController(Context context, CameraEnumerator cameraEnumerato
6266
this.context = context;
6367
this.cameraEnumerator = cameraEnumerator;
6468
this.constraints = constraints;
69+
70+
this.constraintDeviceId = ReactBridgeUtil.getMapStrValue(this.constraints, "deviceId");
71+
this.constraintFacingMode = ReactBridgeUtil.getMapStrValue(this.constraints, "facingMode");
6572
}
6673

6774
@Nullable
@@ -113,8 +120,10 @@ public void applyConstraints(ReadableMap constraints, @Nullable Consumer<Excepti
113120

114121
// Find target camera to switch to.
115122
String[] deviceNames = cameraEnumerator.getDeviceNames();
116-
final String deviceId = ReactBridgeUtil.getMapStrValue(constraints, "deviceId");
117-
final String facingMode = ReactBridgeUtil.getMapStrValue(constraints, "facingMode");
123+
124+
// Use the initial deviceId/facingMode. It is a constraint violation to change these through applyConstraints.
125+
final String deviceId = constraintDeviceId;
126+
final String facingMode = constraintFacingMode;
118127
int cameraIndex = -1;
119128
String cameraName = null;
120129

@@ -144,11 +153,12 @@ public void applyConstraints(ReadableMap constraints, @Nullable Consumer<Excepti
144153

145154
if (cameraName == null) {
146155
if (onFinishedCallback != null) {
147-
onFinishedCallback.accept(new Exception("OverconstrainedError: could not find camera with deviceId: " + deviceId + " or facingMode: " + facingMode));
156+
onFinishedCallback.accept(new Exception(
157+
"OverconstrainedError: could not find camera with deviceId: " + deviceId + " or facingMode: " + facingMode));
148158
}
149159
return;
150160
}
151-
161+
152162
// For lambda reference
153163
final int finalCameraIndex = cameraIndex;
154164
final String finalCameraName = cameraName;
@@ -200,11 +210,8 @@ public void onCameraSwitchError(String s) {
200210

201211
@Override
202212
protected VideoCapturer createVideoCapturer() {
203-
String deviceId = ReactBridgeUtil.getMapStrValue(this.constraints, "deviceId");
204-
String facingMode = ReactBridgeUtil.getMapStrValue(this.constraints, "facingMode");
205-
206-
CreateCapturerResult result = createVideoCapturer(deviceId, facingMode);
207-
if(result == null) {
213+
CreateCapturerResult result = createVideoCapturer(constraintDeviceId, constraintFacingMode);
214+
if (result == null) {
208215
return null;
209216
}
210217

@@ -233,12 +240,12 @@ private void updateActualSize(int cameraIndex, String cameraName, VideoCapturer
233240
* Constructs a new {@code VideoCapturer} instance attempting to satisfy
234241
* specific constraints.
235242
*
236-
* @param deviceId the ID of the requested video device. If not
237-
* {@code null} and a {@code VideoCapturer} can be created for it, then
238-
* {@code facingMode} is ignored.
243+
* @param deviceId the ID of the requested video device. If not
244+
* {@code null} and a {@code VideoCapturer} can be created for it, then
245+
* {@code facingMode} is ignored.
239246
* @param facingMode the facing of the requested video source such as
240-
* {@code user} and {@code environment}. If {@code null}, "user" is
241-
* presumed.
247+
* {@code user} and {@code environment}. If {@code null}, "user" is
248+
* presumed.
242249
* @return a pair containing the deviceId and {@code VideoCapturer} satisfying the {@code facingMode} or
243250
* {@code deviceId} constraint, or null.
244251
*/
@@ -325,7 +332,7 @@ private static class CreateCapturerResult {
325332
public final int cameraIndex;
326333
public final String cameraName;
327334
public final VideoCapturer videoCapturer;
328-
335+
329336
public CreateCapturerResult(int cameraIndex, String cameraName, VideoCapturer videoCapturer) {
330337
this.cameraIndex = cameraIndex;
331338
this.cameraName = cameraName;

ios/RCTWebRTC/VideoCaptureController.m

Lines changed: 26 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ - (instancetype)initWithCapturer:(RTCCameraVideoCapturer *)capturer andConstrain
2424
if (self) {
2525
self.capturer = capturer;
2626
self.running = NO;
27+
[self determineDevice:constraints];
2728
[self applyConstraints:constraints error:nil];
2829
}
2930

@@ -117,32 +118,10 @@ - (void)stopCapture {
117118
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
118119
}
119120

120-
- (void)applyConstraints:(NSDictionary *)constraints error:(NSError **)outError {
121+
- (void)determineDevice:(NSDictionary *)constraints {
121122
// Clear device to prepare for starting camera with new constraints.
122123
self.device = nil;
123-
124-
BOOL hasChanged = NO;
125-
126124
NSString *deviceId = constraints[@"deviceId"];
127-
int width = [constraints[@"width"] intValue];
128-
int height = [constraints[@"height"] intValue];
129-
int frameRate = [constraints[@"frameRate"] intValue];
130-
131-
if (self.width != width) {
132-
hasChanged = YES;
133-
self.width = width;
134-
}
135-
136-
if (self.height != height) {
137-
hasChanged = YES;
138-
self.height = height;
139-
}
140-
141-
if (self.frameRate != frameRate) {
142-
hasChanged = YES;
143-
self.frameRate = frameRate;
144-
}
145-
146125
id facingMode = constraints[@"facingMode"];
147126

148127
if (!facingMode && !deviceId) {
@@ -164,7 +143,6 @@ - (void)applyConstraints:(NSDictionary *)constraints error:(NSError **)outError
164143

165144
BOOL usingFrontCamera = position == AVCaptureDevicePositionFront;
166145
if (self.usingFrontCamera != usingFrontCamera) {
167-
hasChanged = YES;
168146
self.usingFrontCamera = usingFrontCamera;
169147
}
170148
}
@@ -176,12 +154,35 @@ - (void)applyConstraints:(NSDictionary *)constraints error:(NSError **)outError
176154
}
177155

178156
if (self.deviceId != deviceId && ![self.deviceId isEqualToString:deviceId]) {
179-
hasChanged = YES;
180157
self.deviceId = deviceId;
181158
}
159+
}
160+
161+
- (void)applyConstraints:(NSDictionary *)constraints error:(NSError **)outError {
162+
163+
BOOL hasChanged = NO;
164+
165+
int width = [constraints[@"width"] intValue];
166+
int height = [constraints[@"height"] intValue];
167+
int frameRate = [constraints[@"frameRate"] intValue];
182168

169+
if (self.width != width) {
170+
hasChanged = YES;
171+
self.width = width;
172+
}
173+
174+
if (self.height != height) {
175+
hasChanged = YES;
176+
self.height = height;
177+
}
178+
179+
if (self.frameRate != frameRate) {
180+
hasChanged = YES;
181+
self.frameRate = frameRate;
182+
}
183183

184184
if (self.running && hasChanged) {
185+
[self stopCapture];
185186
[self startCapture];
186187
}
187188
}

0 commit comments

Comments
 (0)