Commit 745d926a authored by Peter K. Lee's avatar Peter K. Lee Committed by Commit Bot

Handle classes/externs that are not available on iOS 10.0

UI*FeedbackGenerator and AVCaptureDevice* classes are claimed to be
available for iOS 10+, but they are not really available at runtime on
iOS 10.0. iOS 10.1+ appears to be OK. Use workarounds for unavailable
symbols.

Bug: 824941
Cq-Include-Trybots: master.tryserver.chromium.mac:ios-simulator-cronet;master.tryserver.chromium.mac:ios-simulator-full-configs
Change-Id: Idb9e42e6f72cbd96ff81e99f3ec455c03e09f8ce
Reviewed-on: https://chromium-review.googlesource.com/976945
Commit-Queue: Peter Lee <pkl@chromium.org>
Reviewed-by: default avatarEugene But <eugenebut@chromium.org>
Cr-Commit-Position: refs/heads/master@{#546240}
parent 1cc3eead
......@@ -52,6 +52,19 @@ source_set("coordinator") {
]
}
source_set("unit_tests") {
configs += [ "//build/config/compiler:enable_arc" ]
testonly = true
sources = [
"camera_controller_unittest.mm",
]
deps = [
":qr_scanner",
"//base",
"//testing/gtest:gtest",
]
}
source_set("eg_tests") {
configs += [ "//build/config/compiler:enable_arc" ]
testonly = true
......
......@@ -183,15 +183,28 @@
// Get the back camera.
NSArray* videoCaptureDevices = nil;
if (@available(iOS 10, *)) {
// Although Apple documentation claims that
// AVCaptureDeviceDiscoverySession etc. is available on iOS 10+, they are
// not really available on an app whose deployment target is iOS 10.0
// (iOS 10.1+ are okay) and Chrome will fail at dynamic link time and
// instantly crash. NSClassFromString() checks if Objective-C run-time
// has the classes before using them.
Class discoverSessionClass =
NSClassFromString(@"AVCaptureDeviceDiscoverySession");
if (discoverSessionClass) {
// Hardcoded value of AVCaptureDeviceTypeBuiltInWideAngleCamera here.
// When this @available(iOS 10, *) is deprecated, the unit test
// CameraControllerTest.TestAVCaptureDeviceValue can be removed.
// See https://crbug.com/826011
NSString* cameraType = @"AVCaptureDeviceTypeBuiltInWideAngleCamera";
AVCaptureDeviceDiscoverySession* discoverySession =
[AVCaptureDeviceDiscoverySession
discoverySessionWithDeviceTypes:@[
AVCaptureDeviceTypeBuiltInWideAngleCamera
]
[discoverSessionClass
discoverySessionWithDeviceTypes:@[ cameraType ]
mediaType:AVMediaTypeVideo
position:AVCaptureDevicePositionBack];
videoCaptureDevices = [discoverySession devices];
}
}
#if !defined(__IPHONE_10_0) || __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_10_0
else {
videoCaptureDevices =
......
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#import "ios/chrome/browser/ui/qr_scanner/camera_controller.h"
#include "testing/gtest_mac.h"
#include "testing/platform_test.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
using CameraControllerTest = PlatformTest;
TEST_F(CameraControllerTest, TestAVCaptureDeviceValue) {
// Although Apple documentation claims that AVCaptureDeviceDiscoverySession
// etc. is available on iOS 10+, they are not really available on an app
// whose deployment target is iOS 10.0 (iOS 10.1+ are okay) and Chrome will
// fail at dynamic link time and instantly crash. To make this work, the
// actual value for the global variable
// |AVCaptureDeviceTypeBuiltInWideAngleCamera| is used literally in
// camera_controller.mm. This unit test detects if a newer iOS version
// changes this value. If this unit test fails, check the implementation
// of -loadCaptureSession: in camera_controller.mm.
//
// The following use of AVCaptureDeviceTypeBuiltInWideAngleCamera
// will cause unit tests to be not runnable on iOS 10.0 devices due to
// failure at dynamic link (dyld) time.
// TODO(crbug.com/826011): Remove this when iOS 10.0 support is deprecated.
EXPECT_NSEQ(AVCaptureDeviceTypeBuiltInWideAngleCamera,
@"AVCaptureDeviceTypeBuiltInWideAngleCamera");
}
......@@ -581,30 +581,56 @@ UIResponder* GetFirstResponder() {
// action. This is a no-op for devices that do not support it.
void TriggerHapticFeedbackForAction() {
if (@available(iOS 10, *)) {
UIImpactFeedbackGenerator* generator =
[[UIImpactFeedbackGenerator alloc] init];
// Although Apple documentation claims that UIFeedbackGenerator and its
// concrete subclasses are available on iOS 10+, they are not really
// available on an app whose deployment target is iOS 10.0 (iOS 10.1+ are
// okay) and Chrome will fail at dynamic link time and instantly crash.
// NSClassFromString() checks if Objective-C run-time has the class before
// using it.
Class generatorClass = NSClassFromString(@"UIImpactFeedbackGenerator");
if (generatorClass) {
UIImpactFeedbackGenerator* generator = [[generatorClass alloc] init];
[generator impactOccurred];
}
}
}
// On iOS10 and above, trigger a haptic vibration for the change in selection.
// This is a no-op for devices that do not support it.
void TriggerHapticFeedbackForSelectionChange() {
if (@available(iOS 10, *)) {
UISelectionFeedbackGenerator* generator =
[[UISelectionFeedbackGenerator alloc] init];
// Although Apple documentation claims that UIFeedbackGenerator and its
// concrete subclasses are available on iOS 10+, they are not really
// available on an app whose deployment target is iOS 10.0 (iOS 10.1+ are
// okay) and Chrome will fail at dynamic link time and instantly crash.
// NSClassFromString() checks if Objective-C run-time has the class before
// using it.
Class generatorClass = NSClassFromString(@"UISelectionFeedbackGenerator");
if (generatorClass) {
UISelectionFeedbackGenerator* generator = [[generatorClass alloc] init];
[generator selectionChanged];
}
}
}
// On iOS10 and above, trigger a haptic vibration for a notification.
// This is a no-op for devices that do not support it.
void TriggerHapticFeedbackForNotification(UINotificationFeedbackType type) {
if (@available(iOS 10, *)) {
// Although Apple documentation claims that UIFeedbackGenerator and its
// concrete subclasses are available on iOS 10+, they are not really
// available on an app whose deployment target is iOS 10.0 (iOS 10.1+ are
// okay) and Chrome will fail at dynamic link time and instantly crash.
// NSClassFromString() checks if Objective-C run-time has the class before
// using it.
Class generatorClass =
NSClassFromString(@"UINotificationFeedbackGenerator");
if (generatorClass) {
UINotificationFeedbackGenerator* generator =
[[UINotificationFeedbackGenerator alloc] init];
[[generatorClass alloc] init];
[generator notificationOccurred:type];
}
}
}
UIEdgeInsets SafeAreaInsetsForView(UIView* view) {
......
......@@ -213,6 +213,7 @@ test("ios_chrome_unittests") {
"//ios/chrome/browser/ui/popup_menu:unit_tests",
"//ios/chrome/browser/ui/presenters:unit_tests",
"//ios/chrome/browser/ui/promos:unit_tests",
"//ios/chrome/browser/ui/qr_scanner:unit_tests",
"//ios/chrome/browser/ui/reading_list:unit_tests",
"//ios/chrome/browser/ui/safe_mode:unit_tests",
"//ios/chrome/browser/ui/settings:unit_tests",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment