summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoel Fischer <joeljfischer@gmail.com>2019-08-08 16:44:01 -0400
committerJoel Fischer <joeljfischer@gmail.com>2019-08-08 16:44:01 -0400
commitab6e0fcaa80a1398e1c853a9e884e9e25492d1fa (patch)
tree25ebee56f15e4c7d185bc59264eeef536d239226
parent91be08ecabf722282c747bbc9f34ac92a81bd119 (diff)
downloadsdl_ios-ab6e0fcaa80a1398e1c853a9e884e9e25492d1fa.tar.gz
Add the ability to have the lock screen always display
-rw-r--r--SmartDeviceLink/SDLLockScreenConfiguration.h33
-rw-r--r--SmartDeviceLink/SDLLockScreenConfiguration.m49
-rw-r--r--SmartDeviceLink/SDLLockScreenManager.m12
-rw-r--r--SmartDeviceLinkTests/DevAPISpecs/SDLFakeViewControllerPresenter.m9
-rw-r--r--SmartDeviceLinkTests/DevAPISpecs/SDLLockScreenManagerSpec.m57
5 files changed, 140 insertions, 20 deletions
diff --git a/SmartDeviceLink/SDLLockScreenConfiguration.h b/SmartDeviceLink/SDLLockScreenConfiguration.h
index 854196520..ee8ac6bfc 100644
--- a/SmartDeviceLink/SDLLockScreenConfiguration.h
+++ b/SmartDeviceLink/SDLLockScreenConfiguration.h
@@ -11,9 +11,32 @@
NS_ASSUME_NONNULL_BEGIN
+/**
+ Describes when the lock screen should be shown.
+
+ - SDLLockScreenConfigurationModeNever: The lock screen should never be shown. This should almost always mean that you will build your own lock screen.
+ - SDLLockScreenConfigurationModeRequiredOnly: The lock screen should only be shown when it is required by the head unit.
+ - SDLLockScreenConfigurationModeOptionalOrRequired: The lock screen should be shown when required by the head unit or when the head unit says that its optional, but *not* in other cases, such as before the user has interacted with your app on the head unit.
+ - SDLLockScreenConfigurationModeAlways: The lock screen should always be shown after connection.
+ */
+typedef NS_ENUM(NSUInteger, SDLLockScreenConfigurationDisplayMode) {
+ SDLLockScreenConfigurationDisplayModeNever,
+ SDLLockScreenConfigurationDisplayModeRequiredOnly,
+ SDLLockScreenConfigurationDisplayModeOptionalOrRequired,
+ SDLLockScreenConfigurationDisplayModeAlways
+};
+
+/**
+ A configuration describing how the lock screen should be used by the internal SDL system for your application. This configuration is provided before SDL starts and will govern the entire SDL lifecycle of your application.
+ */
@interface SDLLockScreenConfiguration : NSObject <NSCopying>
/**
+ Describes when the lock screen will be displayed. Defaults to `SDLLockScreenConfigurationDisplayModeRequiredOnly`.
+ */
+@property (assign, nonatomic) SDLLockScreenConfigurationDisplayMode displayMode;
+
+/**
* Whether or not the lock screen should be shown in the "lock screen optional" state. Defaults to NO.
*
* In order for the "lock screen optional" state to occur, the following must be true:
@@ -21,8 +44,10 @@ NS_ASSUME_NONNULL_BEGIN
* 2. The driver is not distracted (i.e. the last `OnDriverDistraction` notification received was for a driver distraction state off).
* 3. The `hmiLevel` can not be `NONE`.
* 4. If the `hmiLevel` is currently `BACKGROUND` then the previous `hmiLevel` should have been `FULL` or `LIMITED` (i.e. the user should have interacted with app before it was backgrounded).
+
+ * Since this has been deprecated, setting this to true will set `displayMode` to `OptionalOrRequired` if `enableAutomaticLockScreen` is true, or will have no effect if it is false.
*/
-@property (assign, nonatomic) BOOL showInOptionalState;
+@property (assign, nonatomic) BOOL showInOptionalState __deprecated_msg("Use displayMode SDLLockScreenConfigurationDisplayModeOptionalOrRequired to replicate this being YES");
/**
If YES, then the lock screen can be dismissed with a downward swipe on compatible head units. Requires a connection of SDL 6.0+ and the head unit to enable the feature. Defaults to YES.
@@ -30,9 +55,11 @@ NS_ASSUME_NONNULL_BEGIN
@property (assign, nonatomic) BOOL enableDismissGesture;
/**
- * If YES, the lock screen should be managed by SDL and automatically engage when necessary. If NO, then the lock screen will never be engaged. Defaults to YES.
+ If YES, the lock screen should be managed by SDL and automatically engage when necessary. If NO, then the lock screen will never be engaged. Defaults to YES.
+
+ Since this has been deprecated, setting this to false will set `displayMode` to `Never`. Setting it back to true will set it to `RequiredOnly` if `showInOptionalState` is false, or `OptionalOrRequired` if it is true.
*/
-@property (assign, nonatomic, readonly) BOOL enableAutomaticLockScreen;
+@property (assign, nonatomic, readonly) BOOL enableAutomaticLockScreen __deprecated_msg("Use displayMode SDLLockScreenConfigurationDisplayModeNever to replicate this being NO");
/**
* The background color of the lock screen. This could be a branding color, or leave at the default for a dark blue-gray.
diff --git a/SmartDeviceLink/SDLLockScreenConfiguration.m b/SmartDeviceLink/SDLLockScreenConfiguration.m
index 4798cf9d4..5ee76e3fe 100644
--- a/SmartDeviceLink/SDLLockScreenConfiguration.m
+++ b/SmartDeviceLink/SDLLockScreenConfiguration.m
@@ -11,23 +11,20 @@
NS_ASSUME_NONNULL_BEGIN
-@interface SDLLockScreenConfiguration ()
-
-@end
-
-
@implementation SDLLockScreenConfiguration
#pragma mark - Lifecycle
-- (instancetype)initWithAutoLockScreen:(BOOL)enableAutomatic enableInOptional:(BOOL)enableOptional enableDismissGesture:(BOOL)enableDismissGesture backgroundColor:(UIColor *)backgroundColor appIcon:(nullable UIImage *)appIcon viewController:(nullable UIViewController *)customViewController {
+- (instancetype)initWithDisplayMode:(SDLLockScreenConfigurationDisplayMode)mode enableDismissGesture:(BOOL)enableDismissGesture backgroundColor:(UIColor *)backgroundColor appIcon:(nullable UIImage *)appIcon viewController:(nullable UIViewController *)customViewController {
self = [super init];
if (!self) {
return nil;
}
- _enableAutomaticLockScreen = enableAutomatic;
- _showInOptionalState = enableOptional;
+ _displayMode = mode;
+ _enableAutomaticLockScreen = (mode == SDLLockScreenConfigurationDisplayModeNever) ? NO : YES;
+ _showInOptionalState = (mode == SDLLockScreenConfigurationDisplayModeOptionalOrRequired) ? NO : YES;
+
_enableDismissGesture = enableDismissGesture;
_backgroundColor = backgroundColor;
_appIcon = appIcon;
@@ -37,11 +34,11 @@ NS_ASSUME_NONNULL_BEGIN
}
+ (instancetype)disabledConfiguration {
- return [[self alloc] initWithAutoLockScreen:NO enableInOptional:NO enableDismissGesture:NO backgroundColor:[self sdl_defaultBackgroundColor] appIcon:nil viewController:nil];
+ return [[self alloc] initWithDisplayMode:SDLLockScreenConfigurationDisplayModeNever enableDismissGesture:NO backgroundColor:[self sdl_defaultBackgroundColor] appIcon:nil viewController:nil];
}
+ (instancetype)enabledConfiguration {
- return [[self alloc] initWithAutoLockScreen:YES enableInOptional:NO enableDismissGesture:YES backgroundColor:[self sdl_defaultBackgroundColor] appIcon:nil viewController:nil];
+ return [[self alloc] initWithDisplayMode:SDLLockScreenConfigurationDisplayModeRequiredOnly enableDismissGesture:YES backgroundColor:[self sdl_defaultBackgroundColor] appIcon:nil viewController:nil];
}
+ (instancetype)enabledConfigurationWithAppIcon:(UIImage *)lockScreenAppIcon backgroundColor:(nullable UIColor *)lockScreenBackgroundColor {
@@ -49,11 +46,11 @@ NS_ASSUME_NONNULL_BEGIN
lockScreenBackgroundColor = [self.class sdl_defaultBackgroundColor];
}
- return [[self alloc] initWithAutoLockScreen:YES enableInOptional:NO enableDismissGesture:YES backgroundColor:lockScreenBackgroundColor appIcon:lockScreenAppIcon viewController:nil];
+ return [[self alloc] initWithDisplayMode:SDLLockScreenConfigurationDisplayModeRequiredOnly enableDismissGesture:YES backgroundColor:lockScreenBackgroundColor appIcon:lockScreenAppIcon viewController:nil];
}
+ (instancetype)enabledConfigurationWithViewController:(UIViewController *)viewController {
- return [[self alloc] initWithAutoLockScreen:YES enableInOptional:NO enableDismissGesture:YES backgroundColor:[self.class sdl_defaultBackgroundColor] appIcon:nil viewController:viewController];
+ return [[self alloc] initWithDisplayMode:SDLLockScreenConfigurationDisplayModeRequiredOnly enableDismissGesture:YES backgroundColor:[self.class sdl_defaultBackgroundColor] appIcon:nil viewController:viewController];
}
@@ -64,10 +61,36 @@ NS_ASSUME_NONNULL_BEGIN
}
+#pragma mark - Setters / Getters
+
+- (void)setEnableAutomaticLockScreen:(BOOL)enableAutomaticLockScreen {
+ _enableAutomaticLockScreen = enableAutomaticLockScreen;
+
+ if (!_enableAutomaticLockScreen) {
+ _displayMode = SDLLockScreenConfigurationDisplayModeNever;
+ } else if (_showInOptionalState) {
+ _displayMode = SDLLockScreenConfigurationDisplayModeOptionalOrRequired;
+ } else {
+ _displayMode = SDLLockScreenConfigurationDisplayModeRequiredOnly;
+ }
+}
+
+- (void)setShowInOptionalState:(BOOL)showInOptionalState {
+ _showInOptionalState = showInOptionalState;
+
+ if (!_enableAutomaticLockScreen) {
+ _displayMode = SDLLockScreenConfigurationDisplayModeNever;
+ } else if (_showInOptionalState) {
+ _displayMode = SDLLockScreenConfigurationDisplayModeOptionalOrRequired;
+ } else {
+ _displayMode = SDLLockScreenConfigurationDisplayModeRequiredOnly;
+ }
+}
+
#pragma mark - NSCopying
- (id)copyWithZone:(nullable NSZone *)zone {
- SDLLockScreenConfiguration *new = [[SDLLockScreenConfiguration allocWithZone:zone] initWithAutoLockScreen:_enableAutomaticLockScreen enableInOptional:_showInOptionalState enableDismissGesture:_enableDismissGesture backgroundColor:_backgroundColor appIcon:_appIcon viewController:_customViewController];
+ SDLLockScreenConfiguration *new = [[SDLLockScreenConfiguration allocWithZone:zone] initWithDisplayMode:_displayMode enableDismissGesture:_enableDismissGesture backgroundColor:_backgroundColor appIcon:_appIcon viewController:_customViewController];
return new;
}
diff --git a/SmartDeviceLink/SDLLockScreenManager.m b/SmartDeviceLink/SDLLockScreenManager.m
index 3d8ca341a..aa83a9805 100644
--- a/SmartDeviceLink/SDLLockScreenManager.m
+++ b/SmartDeviceLink/SDLLockScreenManager.m
@@ -67,7 +67,7 @@ NS_ASSUME_NONNULL_BEGIN
self.canPresent = NO;
// Create and initialize the lock screen controller depending on the configuration
- if (!self.config.enableAutomaticLockScreen) {
+ if (self.config.displayMode == SDLLockScreenConfigurationDisplayModeNever) {
self.presenter.lockViewController = nil;
return;
} else if (self.config.customViewController != nil) {
@@ -152,14 +152,18 @@ NS_ASSUME_NONNULL_BEGIN
}
// Present the VC depending on the lock screen status
- if ([self.lastLockNotification.lockScreenStatus isEqualToEnum:SDLLockScreenStatusRequired]) {
+ if (self.config.displayMode == SDLLockScreenConfigurationDisplayModeAlways) {
+ if (!self.presenter.presented && self.canPresent) {
+ [self.presenter present];
+ }
+ } else if ([self.lastLockNotification.lockScreenStatus isEqualToEnum:SDLLockScreenStatusRequired]) {
if (!self.presenter.presented && self.canPresent && !self.lockScreenDismissedByUser) {
[self.presenter present];
}
} else if ([self.lastLockNotification.lockScreenStatus isEqualToEnum:SDLLockScreenStatusOptional]) {
- if (self.config.showInOptionalState && !self.presenter.presented && self.canPresent && !self.lockScreenDismissedByUser) {
+ if (self.config.displayMode == SDLLockScreenConfigurationDisplayModeOptionalOrRequired && !self.presenter.presented && self.canPresent && !self.lockScreenDismissedByUser) {
[self.presenter present];
- } else if (!self.config.showInOptionalState && self.presenter.presented) {
+ } else if (self.config.displayMode != SDLLockScreenConfigurationDisplayModeOptionalOrRequired && self.presenter.presented) {
[self.presenter dismiss];
}
} else if ([self.lastLockNotification.lockScreenStatus isEqualToEnum:SDLLockScreenStatusOff]) {
diff --git a/SmartDeviceLinkTests/DevAPISpecs/SDLFakeViewControllerPresenter.m b/SmartDeviceLinkTests/DevAPISpecs/SDLFakeViewControllerPresenter.m
index 3e6230897..aa9fe7849 100644
--- a/SmartDeviceLinkTests/DevAPISpecs/SDLFakeViewControllerPresenter.m
+++ b/SmartDeviceLinkTests/DevAPISpecs/SDLFakeViewControllerPresenter.m
@@ -18,6 +18,15 @@
@implementation SDLFakeViewControllerPresenter
+- (instancetype)init {
+ self = [super init];
+ if (!self) { return nil; }
+
+ _presented = NO;
+
+ return self;
+}
+
- (void)present {
if (!self.lockViewController) { return; }
diff --git a/SmartDeviceLinkTests/DevAPISpecs/SDLLockScreenManagerSpec.m b/SmartDeviceLinkTests/DevAPISpecs/SDLLockScreenManagerSpec.m
index 596c863b1..694084e27 100644
--- a/SmartDeviceLinkTests/DevAPISpecs/SDLLockScreenManagerSpec.m
+++ b/SmartDeviceLinkTests/DevAPISpecs/SDLLockScreenManagerSpec.m
@@ -326,6 +326,57 @@ describe(@"a lock screen manager", ^{
});
});
+ describe(@"with an always enabled configuration", ^{
+ __block SDLFakeViewControllerPresenter *fakePresenter = nil;
+ __block SDLRPCNotificationNotification *testLockStatusNotification = nil;
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+ __block SDLOnLockScreenStatus *testStatus = nil;
+#pragma clang diagnostic pop
+
+ beforeEach(^{
+ fakePresenter = [[SDLFakeViewControllerPresenter alloc] init];
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+ testStatus = [[SDLOnLockScreenStatus alloc] init];
+#pragma clang diagnostic pop
+
+ SDLLockScreenConfiguration *config = [SDLLockScreenConfiguration enabledConfiguration];
+ config.displayMode = SDLLockScreenConfigurationDisplayModeAlways;
+
+ testManager = [[SDLLockScreenManager alloc] initWithConfiguration:config notificationDispatcher:nil presenter:fakePresenter];
+ [testManager start];
+ });
+
+ context(@"receiving a lock screen status of required", ^{
+ beforeEach(^{
+ testStatus.lockScreenStatus = SDLLockScreenStatusRequired;
+ testLockStatusNotification = [[SDLRPCNotificationNotification alloc] initWithName:SDLDidChangeLockScreenStatusNotification object:nil rpcNotification:testStatus];
+
+ [[NSNotificationCenter defaultCenter] postNotification:testLockStatusNotification];
+ });
+
+ it(@"should present the lock screen if not already presented", ^{
+ expect(fakePresenter.presented).to(beTrue());
+ });
+ });
+
+ context(@"receiving a lock screen status of off", ^{
+ beforeEach(^{
+ testStatus.lockScreenStatus = SDLLockScreenStatusOff;
+ testLockStatusNotification = [[SDLRPCNotificationNotification alloc] initWithName:SDLDidChangeLockScreenStatusNotification object:nil rpcNotification:testStatus];
+
+ [[NSNotificationCenter defaultCenter] postNotification:testLockStatusNotification];
+ });
+
+ it(@"should present the lock screen if not already presented", ^{
+ expect(fakePresenter.presented).to(beTrue());
+ });
+ });
+ });
+
describe(@"A lock screen status of OPTIONAL", ^{
__block SDLLockScreenManager *testLockScreenManager = nil;
__block SDLLockScreenConfiguration *testLockScreenConfig = nil;
@@ -346,7 +397,10 @@ describe(@"a lock screen manager", ^{
context(@"showInOptionalState is true", ^{
beforeEach(^{
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
testLockScreenConfig.showInOptionalState = true;
+#pragma clang diagnostic pop
testLockScreenManager = [[SDLLockScreenManager alloc] initWithConfiguration:testLockScreenConfig notificationDispatcher:nil presenter:mockViewControllerPresenter];
@@ -365,7 +419,10 @@ describe(@"a lock screen manager", ^{
context(@"showInOptionalState is false", ^{
beforeEach(^{
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
testLockScreenConfig.showInOptionalState = false;
+#pragma clang diagnostic pop
testLockScreenManager = [[SDLLockScreenManager alloc] initWithConfiguration:testLockScreenConfig notificationDispatcher:nil presenter:mockViewControllerPresenter];