Skip to content

Commit bbfffdf

Browse files
mdouglassmichaelkirk
authored andcommitted
Scanning an invalid QR code shows an error dialog
* From the error dialog you are able to back out of scanning or try again. Adds English localization for this message. Adds an extra flag in OWSQRCodeScanningViewController to make sure that we don’t handle captureResults when capture is disabled (this was racing before because the call to [capture stop] is async and that was causing the cancel case to present the error dialog multiple times. Fixes Signal-iOS#1347 * Fixes appearance of race with starting capture Also marks the capture variable as atomic since it is accessed on multiple threads. // FREEBIE
1 parent 40d6550 commit bbfffdf

File tree

3 files changed

+59
-29
lines changed

3 files changed

+59
-29
lines changed

Signal/src/view controllers/OWSLinkDeviceViewController.m

Lines changed: 52 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -62,45 +62,70 @@ - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(nullable id)sender
6262
// pragma mark - OWSQRScannerDelegate
6363
- (void)controller:(OWSQRCodeScanningViewController *)controller didDetectQRCodeWithString:(NSString *)string
6464
{
65-
NSString *title
66-
= NSLocalizedString(@"LINK_DEVICE_PERMISSION_ALERT_TITLE", @"confirm the users intent to link a new device");
67-
NSString *linkingDescription
68-
= NSLocalizedString(@"LINK_DEVICE_PERMISSION_ALERT_BODY", @"confirm the users intent to link a new device");
69-
70-
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:title
71-
message:linkingDescription
72-
preferredStyle:UIAlertControllerStyleAlert];
73-
74-
UIAlertAction *cancelAction =
65+
OWSDeviceProvisioningURLParser *parser = [[OWSDeviceProvisioningURLParser alloc] initWithProvisioningURL:string];
66+
if (!parser.isValid) {
67+
DDLogError(@"Unable to parse provisioning params from QRCode: %@", string);
68+
69+
NSString* title = NSLocalizedString(@"LINK_DEVICE_INVALID_CODE_TITLE", @"report an invalid linking code");
70+
NSString* body = NSLocalizedString(@"LINK_DEVICE_INVALID_CODE_BODY", @"report an invalid linking code");
71+
72+
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:title
73+
message:body
74+
preferredStyle:UIAlertControllerStyleAlert];
75+
76+
UIAlertAction *cancelAction =
7577
[UIAlertAction actionWithTitle:NSLocalizedString(@"TXT_CANCEL_TITLE", nil)
7678
style:UIAlertActionStyleCancel
7779
handler:^(UIAlertAction *action) {
7880
dispatch_async(dispatch_get_main_queue(), ^{
7981
[self.navigationController popViewControllerAnimated:YES];
8082
});
8183
}];
82-
[alertController addAction:cancelAction];
83-
84-
UIAlertAction *proceedAction =
85-
[UIAlertAction actionWithTitle:NSLocalizedString(@"CONFIRM_LINK_NEW_DEVICE_ACTION", @"Button text")
84+
[alertController addAction:cancelAction];
85+
86+
UIAlertAction *proceedAction =
87+
[UIAlertAction actionWithTitle:NSLocalizedString(@"LINK_DEVICE_RESTART", @"attempt another linking")
8688
style:UIAlertActionStyleDefault
8789
handler:^(UIAlertAction *action) {
88-
[self provisionWithString:string];
90+
[self.qrScanningController startCapture];
8991
}];
90-
[alertController addAction:proceedAction];
91-
92-
[self presentViewController:alertController animated:YES completion:nil];
92+
[alertController addAction:proceedAction];
93+
94+
[self presentViewController:alertController animated:YES completion:nil];
95+
} else {
96+
NSString *title
97+
= NSLocalizedString(@"LINK_DEVICE_PERMISSION_ALERT_TITLE", @"confirm the users intent to link a new device");
98+
NSString *linkingDescription
99+
= NSLocalizedString(@"LINK_DEVICE_PERMISSION_ALERT_BODY", @"confirm the users intent to link a new device");
100+
101+
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:title
102+
message:linkingDescription
103+
preferredStyle:UIAlertControllerStyleAlert];
104+
105+
UIAlertAction *cancelAction =
106+
[UIAlertAction actionWithTitle:NSLocalizedString(@"TXT_CANCEL_TITLE", nil)
107+
style:UIAlertActionStyleCancel
108+
handler:^(UIAlertAction *action) {
109+
dispatch_async(dispatch_get_main_queue(), ^{
110+
[self.navigationController popViewControllerAnimated:YES];
111+
});
112+
}];
113+
[alertController addAction:cancelAction];
114+
115+
UIAlertAction *proceedAction =
116+
[UIAlertAction actionWithTitle:NSLocalizedString(@"CONFIRM_LINK_NEW_DEVICE_ACTION", @"Button text")
117+
style:UIAlertActionStyleDefault
118+
handler:^(UIAlertAction *action) {
119+
[self provisionWithParser:parser];
120+
}];
121+
[alertController addAction:proceedAction];
122+
123+
[self presentViewController:alertController animated:YES completion:nil];
124+
}
93125
}
94126

95-
- (void)provisionWithString:(NSString *)string
127+
- (void)provisionWithParser:(OWSDeviceProvisioningURLParser *)parser
96128
{
97-
OWSDeviceProvisioningURLParser *parser = [[OWSDeviceProvisioningURLParser alloc] initWithProvisioningURL:string];
98-
99-
if (!parser.isValid) {
100-
DDLogError(@"Unable to parse provisioning params from QRCode: %@", string);
101-
return;
102-
}
103-
104129
NSData *myPublicKey = [[TSStorageManager sharedManager] identityKeyPair].publicKey;
105130
NSData *myPrivateKey = [[TSStorageManager sharedManager] identityKeyPair].ows_privateKey;
106131
NSString *accountIdentifier = [TSStorageManager localNumber];
@@ -123,7 +148,7 @@ - (void)provisionWithString:(NSString *)string
123148
dispatch_async(dispatch_get_main_queue(), ^{
124149
[self presentViewController:[self retryAlertControllerWithError:error
125150
retryBlock:^{
126-
[self provisionWithString:string];
151+
[self provisionWithParser:parser];
127152
}]
128153
animated:YES
129154
completion:nil];

Signal/src/view controllers/OWSQRCodeScanningViewController.m

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
@interface OWSQRCodeScanningViewController ()
99

1010
@property (nonatomic) BOOL captureEnabled;
11-
@property (nonatomic, strong) ZXCapture *capture;
11+
@property (atomic, strong) ZXCapture *capture;
1212
@property UIView *maskingView;
1313
@property CALayer *maskingLayer;
1414

@@ -97,14 +97,17 @@ - (void)startCapture
9797
dispatch_async(dispatch_get_main_queue(), ^{
9898
[self.view.layer addSublayer:self.capture.layer];
9999
[self.view bringSubviewToFront:self.maskingView];
100+
[self.capture start];
100101
});
101102
});
103+
} else {
104+
[self.capture start];
102105
}
103-
[self.capture start];
104106
}
105107

106108
- (void)stopCapture
107109
{
110+
self.captureEnabled = NO;
108111
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
109112
[self.capture stop];
110113
});
@@ -137,6 +140,8 @@ - (CAShapeLayer *)buildCircularMaskingLayer
137140

138141
- (void)captureResult:(ZXCapture *)capture result:(ZXResult *)result
139142
{
143+
if (!self.captureEnabled)
144+
return;
140145
[self stopCapture];
141146

142147
// TODO bounding rectangle
690 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)