Skip to content

Commit

Permalink
Merge pull request #1366 from smartdevicelink/feature/issue_1365_disa…
Browse files Browse the repository at this point in the history
…ble_dismiss_lockscreen_gesture

Add config option to disable lock screen dismiss gesture
  • Loading branch information
joeljfischer committed Aug 8, 2019
2 parents f43c7f4 + b49326f commit 91be08e
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 26 deletions.
11 changes: 8 additions & 3 deletions SmartDeviceLink/SDLLockScreenConfiguration.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ NS_ASSUME_NONNULL_BEGIN
@interface SDLLockScreenConfiguration : NSObject <NSCopying>

/**
* Whether or not the lock screen should be shown in the "lock screen optional" state. Defaults to false.
* Whether or not the lock screen should be shown in the "lock screen optional" state. Defaults to NO.
*
* @discussion In order for the "lock screen optional" state to occur, the following must be true:
* In order for the "lock screen optional" state to occur, the following must be true:
* 1. The app should have received at least 1 driver distraction notification (i.e. a `OnDriverDistraction` notification) from SDL Core. Older versions of Core did not send a notification immediately on connection.
* 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`.
Expand All @@ -25,7 +25,12 @@ NS_ASSUME_NONNULL_BEGIN
@property (assign, nonatomic) BOOL showInOptionalState;

/**
* 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.
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.
*/
@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.
*/
@property (assign, nonatomic, readonly) BOOL enableAutomaticLockScreen;

Expand Down
17 changes: 7 additions & 10 deletions SmartDeviceLink/SDLLockScreenConfiguration.m
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,15 @@ @implementation SDLLockScreenConfiguration

#pragma mark - Lifecycle

- (instancetype)initWithAutoLockScreen:(BOOL)enableAutomatic enableInOptional:(BOOL)enableOptional backgroundColor:(UIColor *)backgroundColor appIcon:(nullable UIImage *)appIcon viewController:(nullable UIViewController *)customViewController {
- (instancetype)initWithAutoLockScreen:(BOOL)enableAutomatic enableInOptional:(BOOL)enableOptional 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;
_enableDismissGesture = enableDismissGesture;
_backgroundColor = backgroundColor;
_appIcon = appIcon;
_customViewController = customViewController;
Expand All @@ -36,23 +37,23 @@ - (instancetype)initWithAutoLockScreen:(BOOL)enableAutomatic enableInOptional:(B
}

+ (instancetype)disabledConfiguration {
return [[self alloc] initWithAutoLockScreen:NO enableInOptional:NO backgroundColor:[self sdl_defaultBackgroundColor] appIcon:nil viewController:nil];
return [[self alloc] initWithAutoLockScreen:NO enableInOptional:NO enableDismissGesture:NO backgroundColor:[self sdl_defaultBackgroundColor] appIcon:nil viewController:nil];
}

+ (instancetype)enabledConfiguration {
return [[self alloc] initWithAutoLockScreen:YES enableInOptional:NO backgroundColor:[self sdl_defaultBackgroundColor] appIcon:nil viewController:nil];
return [[self alloc] initWithAutoLockScreen:YES enableInOptional:NO enableDismissGesture:YES backgroundColor:[self sdl_defaultBackgroundColor] appIcon:nil viewController:nil];
}

+ (instancetype)enabledConfigurationWithAppIcon:(UIImage *)lockScreenAppIcon backgroundColor:(nullable UIColor *)lockScreenBackgroundColor {
if (lockScreenBackgroundColor == nil) {
lockScreenBackgroundColor = [self.class sdl_defaultBackgroundColor];
}

return [[self alloc] initWithAutoLockScreen:YES enableInOptional:NO backgroundColor:lockScreenBackgroundColor appIcon:lockScreenAppIcon viewController:nil];
return [[self alloc] initWithAutoLockScreen:YES enableInOptional:NO enableDismissGesture:YES backgroundColor:lockScreenBackgroundColor appIcon:lockScreenAppIcon viewController:nil];
}

+ (instancetype)enabledConfigurationWithViewController:(UIViewController *)viewController {
return [[self alloc] initWithAutoLockScreen:YES enableInOptional:NO backgroundColor:[self.class sdl_defaultBackgroundColor] appIcon:nil viewController:viewController];
return [[self alloc] initWithAutoLockScreen:YES enableInOptional:NO enableDismissGesture:YES backgroundColor:[self.class sdl_defaultBackgroundColor] appIcon:nil viewController:viewController];
}


Expand All @@ -66,11 +67,7 @@ + (UIColor *)sdl_defaultBackgroundColor {
#pragma mark - NSCopying

- (id)copyWithZone:(nullable NSZone *)zone {
SDLLockScreenConfiguration *new = [[SDLLockScreenConfiguration allocWithZone:zone] initWithAutoLockScreen : _enableAutomaticLockScreen
enableInOptional : _showInOptionalState
backgroundColor : _backgroundColor
appIcon : _appIcon
viewController : _customViewController];
SDLLockScreenConfiguration *new = [[SDLLockScreenConfiguration allocWithZone:zone] initWithAutoLockScreen:_enableAutomaticLockScreen enableInOptional:_showInOptionalState enableDismissGesture:_enableDismissGesture backgroundColor:_backgroundColor appIcon:_appIcon viewController:_customViewController];

return new;
}
Expand Down
3 changes: 2 additions & 1 deletion SmartDeviceLink/SDLLockScreenManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,8 @@ - (void)sdl_checkLockScreen {
- (void)sdl_updateLockScreenDismissable {
if (self.lastDriverDistractionNotification == nil ||
self.lastDriverDistractionNotification.lockScreenDismissalEnabled == nil ||
!self.lastDriverDistractionNotification.lockScreenDismissalEnabled.boolValue) {
!self.lastDriverDistractionNotification.lockScreenDismissalEnabled.boolValue ||
!self.config.enableDismissGesture) {
self.lockScreenDismissable = NO;
} else {
self.lockScreenDismissable = YES;
Expand Down
20 changes: 12 additions & 8 deletions SmartDeviceLinkTests/DevAPISpecs/SDLLockScreenConfigurationSpec.m
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@
});

it(@"should properly set properties", ^{
expect(@(testConfig.enableAutomaticLockScreen)).to(beFalsy());
expect(@(testConfig.showInOptionalState)).to(beFalsy());
expect(testConfig.enableAutomaticLockScreen).to(beFalse());
expect(testConfig.showInOptionalState).to(beFalse());
expect(testConfig.enableDismissGesture).to(beFalse());
expect(testConfig.backgroundColor).to(equal([UIColor colorWithRed:(57.0/255.0) green:(78.0/255.0) blue:(96.0/255.0) alpha:1.0]));
expect(testConfig.appIcon).to(beNil());
expect(testConfig.customViewController).to(beNil());
Expand All @@ -28,8 +29,9 @@
});

it(@"should properly set properties", ^{
expect(@(testConfig.enableAutomaticLockScreen)).to(beTruthy());
expect(@(testConfig.showInOptionalState)).to(beFalsy());
expect(testConfig.enableAutomaticLockScreen).to(beTrue());
expect(testConfig.showInOptionalState).to(beFalse());
expect(testConfig.enableDismissGesture).to(beTrue());
expect(testConfig.backgroundColor).to(equal([UIColor colorWithRed:(57.0/255.0) green:(78.0/255.0) blue:(96.0/255.0) alpha:1.0]));
expect(testConfig.appIcon).to(beNil());
expect(testConfig.customViewController).to(beNil());
Expand All @@ -48,8 +50,9 @@
});

it(@"should properly set properties", ^{
expect(@(testConfig.enableAutomaticLockScreen)).to(beTruthy());
expect(@(testConfig.showInOptionalState)).to(beFalsy());
expect(testConfig.enableAutomaticLockScreen).to(beTrue());
expect(testConfig.showInOptionalState).to(beFalse());
expect(testConfig.enableDismissGesture).to(beTrue());
expect(testConfig.backgroundColor).to(equal([UIColor blueColor]));
expect(testConfig.appIcon).to(equal(testImage));
expect(testConfig.customViewController).to(beNil());
Expand All @@ -66,8 +69,9 @@
});

it(@"should properly set properties", ^{
expect(@(testConfig.enableAutomaticLockScreen)).to(beTruthy());
expect(@(testConfig.showInOptionalState)).to(beFalsy());
expect(testConfig.enableAutomaticLockScreen).to(beTrue());
expect(testConfig.showInOptionalState).to(beFalse());
expect(testConfig.enableDismissGesture).to(beTrue());
expect(testConfig.backgroundColor).to(equal([UIColor colorWithRed:(57.0/255.0) green:(78.0/255.0) blue:(96.0/255.0) alpha:1.0]));
expect(testConfig.appIcon).to(beNil());
expect(testConfig.customViewController).to(equal(testVC));
Expand Down
57 changes: 53 additions & 4 deletions SmartDeviceLinkTests/DevAPISpecs/SDLLockScreenManagerSpec.m
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,22 @@
#import "SDLOnDriverDistraction.h"
#import "SDLRPCNotificationNotification.h"

@interface SDLLockScreenManager ()

@property (assign, nonatomic) BOOL canPresent;
@property (strong, nonatomic, readwrite) SDLLockScreenConfiguration *config;
@property (strong, nonatomic) id<SDLViewControllerPresentable> presenter;

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
@property (strong, nonatomic, nullable) SDLOnLockScreenStatus *lastLockNotification;
#pragma clang diagnostic pop

@property (strong, nonatomic, nullable) SDLOnDriverDistraction *lastDriverDistractionNotification;
@property (assign, nonatomic, readwrite, getter=isLockScreenDismissable) BOOL lockScreenDismissable;
@property (assign, nonatomic) BOOL lockScreenDismissedByUser;

@end

QuickSpecBegin(SDLLockScreenManagerSpec)

Expand All @@ -32,7 +48,7 @@

it(@"should set properties correctly", ^{
// Note: We can't check the "lockScreenPresented" flag on the Lock Screen Manager because it's a computer property checking the window
expect(@(fakePresenter.presented)).to(beFalsy());
expect(fakePresenter.presented).to(beFalse());
expect(testManager.lockScreenViewController).to(beNil());
});

Expand Down Expand Up @@ -110,7 +126,7 @@
});

it(@"should have presented the lock screen", ^{
expect(@(fakePresenter.presented)).to(beTruthy());
expect(fakePresenter.presented).to(beTrue());
});

it(@"should not have a vehicle icon", ^{
Expand Down Expand Up @@ -146,10 +162,9 @@
it(@"should be able to be dismissed", ^{
expect(testManager.isLockScreenDismissable).toEventually(equal(YES));
});

});

describe(@"when a driver distraction notification is posted with lockScreenDismissableEnabled 0 bit", ^{
describe(@"when a driver distraction notification is posted with lockScreenDismissableEnabled as false", ^{
__block SDLRPCNotificationNotification *testDriverDistractionNotification = nil;

beforeEach(^{
Expand Down Expand Up @@ -277,6 +292,40 @@
});
});

context(@"with a dismissable false configuration", ^{
beforeEach(^{
SDLLockScreenConfiguration *config = [SDLLockScreenConfiguration enabledConfiguration];
config.enableDismissGesture = NO;

testManager = [[SDLLockScreenManager alloc] initWithConfiguration:config notificationDispatcher:nil presenter:fakePresenter];
[testManager start];
});

describe(@"when a driver distraction notification is posted with lockScreenDismissableEnabled as true", ^{
__block SDLRPCNotificationNotification *testDriverDistractionNotification = nil;

beforeEach(^{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
SDLOnLockScreenStatus *status = [[SDLOnLockScreenStatus alloc] init];
#pragma clang diagnostic pop
status.lockScreenStatus = SDLLockScreenStatusRequired;
testManager.lastLockNotification = status;

SDLOnDriverDistraction *testDriverDistraction = [[SDLOnDriverDistraction alloc] init];
testDriverDistraction.lockScreenDismissalEnabled = @YES;

testDriverDistractionNotification = [[SDLRPCNotificationNotification alloc] initWithName:SDLDidChangeDriverDistractionStateNotification object:nil rpcNotification:testDriverDistraction];

[[NSNotificationCenter defaultCenter] postNotification:testDriverDistractionNotification];
});

it(@"should not be able to be dismissed", ^{
expect(testManager.isLockScreenDismissable).toEventually(equal(NO));
});
});
});

describe(@"A lock screen status of OPTIONAL", ^{
__block SDLLockScreenManager *testLockScreenManager = nil;
__block SDLLockScreenConfiguration *testLockScreenConfig = nil;
Expand Down

0 comments on commit 91be08e

Please sign in to comment.