Skip to content

Commit

Permalink
Merge pull request #2066 from smartdevicelink/bugfix/issue-2063-locks…
Browse files Browse the repository at this point in the history
…creen-race-conditions

Fix potential lock screen race condition
  • Loading branch information
joeljfischer authored Jan 6, 2022
2 parents c5442d2 + 0b534d8 commit c182283
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 31 deletions.
19 changes: 14 additions & 5 deletions SmartDeviceLink/private/SDLLockScreenManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#import "SDLNotificationDispatcher.h"
#import "SDLLockScreenStatusInfo.h"
#import "SDLOnDriverDistraction.h"
#import "SDLOnHMIStatus.h"
#import "SDLRPCNotificationNotification.h"
#import "SDLViewControllerPresentable.h"

Expand Down Expand Up @@ -52,7 +53,8 @@ - (instancetype)initWithConfiguration:(SDLLockScreenConfiguration *)config notif
_presenter = presenter;
_lockScreenDismissedByUser = NO;
_statusManager = [[SDLLockScreenStatusManager alloc] initWithNotificationDispatcher:dispatcher];


[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(sdl_hmiStatusDidChange:) name:SDLDidChangeHMIStatusNotification object:dispatcher];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(sdl_lockScreenStatusDidChange:) name:SDLDidChangeLockScreenStatusNotification object:dispatcher];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(sdl_lockScreenIconReceived:) name:SDLDidReceiveLockScreenIcon object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(sdl_appDidBecomeActive:) name:UIApplicationDidBecomeActiveNotification object:nil];
Expand Down Expand Up @@ -131,7 +133,6 @@ - (void)sdl_lockScreenStatusDidChange:(SDLRPCNotificationNotification *)notifica
if (lockScreenStatus == nil) { return; }

self.lastLockNotification = lockScreenStatus;

[self sdl_checkLockScreen];
}

Expand Down Expand Up @@ -161,18 +162,26 @@ - (void)sdl_appDidBecomeActive:(NSNotification *)notification {
});
}

- (void)sdl_hmiStatusDidChange:(SDLRPCNotificationNotification *)notification {
if (![notification isNotificationMemberOfClass:[SDLOnHMIStatus class]]) { return; }

[self.statusManager updateHMIStatus:notification.notification];
}

- (void)sdl_driverDistractionStateDidChange:(SDLRPCNotificationNotification *)notification {
if (![notification isNotificationMemberOfClass:[SDLOnDriverDistraction class]]) {
return;
}
if (![notification isNotificationMemberOfClass:[SDLOnDriverDistraction class]]) { return; }

// When an `OnDriverDistraction` notification is sent with a `lockScreenDismissalEnabled` value, keep track of said value if subsequent `OnDriverDistraction`s are missing the `lockScreenDismissalEnabled` value. This is done because the `lockScreenDismissalEnabled` state is assumed to be the same value until a new `lockScreenDismissalEnabled` value is received.
SDLOnDriverDistraction *currentDriverDistraction = notification.notification;
if (currentDriverDistraction.lockScreenDismissalEnabled == nil && self.lastDriverDistractionNotification.lockScreenDismissalEnabled != nil){
currentDriverDistraction.lockScreenDismissalEnabled = self.lastDriverDistractionNotification.lockScreenDismissalEnabled;
currentDriverDistraction.lockScreenDismissalWarning = self.lastDriverDistractionNotification.lockScreenDismissalWarning;
}
self.lastDriverDistractionNotification = currentDriverDistraction;

// Update dismissible state, then update the lock screen status itself
[self sdl_updateLockScreenDismissable];
[self.statusManager updateDriverDistractionState:currentDriverDistraction];
}

#pragma mark - Private Helpers
Expand Down
10 changes: 9 additions & 1 deletion SmartDeviceLink/private/SDLLockScreenStatusInfo.m
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,15 @@ - (instancetype)initWithDriverDistractionStatus:(nullable NSNumber<SDLBool> *)dr
}

- (NSString *)description {
return [NSString stringWithFormat:@"driverDistractionStatus: %@, userSelected: %@, lockScreenStatus: %lu, hmiLevel: %@", self.driverDistractionStatus, self.userSelected, (unsigned long)self.lockScreenStatus, self.hmiLevel];
return [NSString stringWithFormat:@"driverDistractionStatus: %@, userSelected: %@, lockScreenStatus: %@, hmiLevel: %@", (self.driverDistractionStatus ? @"ON" : @"OFF"), (self.userSelected ? @"YES" : @"NO"), [self descriptionForStatus:self.lockScreenStatus], self.hmiLevel];
}

- (NSString *)descriptionForStatus:(SDLLockScreenStatus)status {
switch (status) {
case SDLLockScreenStatusOff: return @"Off";
case SDLLockScreenStatusOptional: return @"Optional";
case SDLLockScreenStatusRequired: return @"Required";
}
}

@end
Expand Down
7 changes: 6 additions & 1 deletion SmartDeviceLink/private/SDLLockScreenStatusManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@
#import "SDLHMILevel.h"
#import "SDLLockScreenConstants.h"

@class SDLNotificationDispatcher;
@class SDLLockScreenStatusInfo;
@class SDLNotificationDispatcher;
@class SDLOnDriverDistraction;
@class SDLOnHMIStatus;

NS_ASSUME_NONNULL_BEGIN

Expand All @@ -27,6 +29,9 @@ static NSString *const SDLDidChangeLockScreenStatusNotification = @"com.sdl.noti
- (instancetype)init NS_UNAVAILABLE;
- (instancetype)initWithNotificationDispatcher:(SDLNotificationDispatcher *)dispatcher;

- (void)updateHMIStatus:(SDLOnHMIStatus *)hmiStatus;
- (void)updateDriverDistractionState:(SDLOnDriverDistraction *)driverDistraction;

@end

NS_ASSUME_NONNULL_END
32 changes: 12 additions & 20 deletions SmartDeviceLink/private/SDLLockScreenStatusManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -31,17 +31,25 @@ - (instancetype)initWithNotificationDispatcher:(SDLNotificationDispatcher *)disp
self = [super init];
if (!self) { return nil; }

_notificationDispatcher = dispatcher;
_userSelected = NO;
_driverDistracted = NO;
_haveDriverDistractionStatus = NO;
_notificationDispatcher = dispatcher;

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(sdl_hmiStatusDidUpdate:) name:SDLDidChangeHMIStatusNotification object:dispatcher];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(sdl_driverDistractionDidUpdate:) name:SDLDidChangeDriverDistractionStateNotification object:dispatcher];

return self;
}

#pragma mark - Component Updates

- (void)updateHMIStatus:(SDLOnHMIStatus *)hmiStatus {
self.hmiLevel = hmiStatus.hmiLevel;
[self sdl_postLockScreenStatus:self.lockScreenStatusNotification];
}

- (void)updateDriverDistractionState:(SDLOnDriverDistraction *)driverDistraction {
self.driverDistracted = [driverDistraction.state isEqualToEnum:SDLDriverDistractionStateOn];
[self sdl_postLockScreenStatus:self.lockScreenStatusNotification];
}

#pragma mark - Getters / Setters
#pragma mark Custom setters
Expand Down Expand Up @@ -112,22 +120,6 @@ - (void)sdl_postLockScreenStatus:(SDLLockScreenStatusInfo *)statusNotification {
[self.notificationDispatcher postNotificationName:SDLDidChangeLockScreenStatusNotification infoObject:statusNotification];
}

#pragma mark - Observers

- (void)sdl_hmiStatusDidUpdate:(SDLRPCNotificationNotification *)notification {
SDLOnHMIStatus *hmiStatus = notification.notification;

self.hmiLevel = hmiStatus.hmiLevel;
[self sdl_postLockScreenStatus:self.lockScreenStatusNotification];
}

- (void)sdl_driverDistractionDidUpdate:(SDLRPCNotificationNotification *)notification {
SDLOnDriverDistraction *driverDistraction = notification.notification;

self.driverDistracted = [driverDistraction.state isEqualToEnum:SDLDriverDistractionStateOn];
[self sdl_postLockScreenStatus:self.lockScreenStatusNotification];
}

@end

NS_ASSUME_NONNULL_END
Original file line number Diff line number Diff line change
Expand Up @@ -270,8 +270,7 @@
}]]);

SDLOnHMIStatus *hmiStatus = [[SDLOnHMIStatus alloc] initWithHMILevel:SDLHMILevelFull systemContext:SDLSystemContextMain audioStreamingState:SDLAudioStreamingStateAudible videoStreamingState:nil windowID:nil];
SDLRPCNotificationNotification *hmiStatusNotification = [[SDLRPCNotificationNotification alloc] initWithName:SDLDidChangeHMIStatusNotification object:mockDispatcher rpcNotification:hmiStatus];
[[NSNotificationCenter defaultCenter] postNotification:hmiStatusNotification];
[testManager updateHMIStatus:hmiStatus];
});

it(@"should update the driver distraction status and send a notification", ^{
Expand All @@ -290,8 +289,7 @@

SDLOnDriverDistraction *driverDistraction = [[SDLOnDriverDistraction alloc] init];
driverDistraction.state = SDLDriverDistractionStateOn;
SDLRPCNotificationNotification *driverDistractionStateNotification = [[SDLRPCNotificationNotification alloc] initWithName:SDLDidChangeDriverDistractionStateNotification object:mockDispatcher rpcNotification:driverDistraction];
[[NSNotificationCenter defaultCenter] postNotification:driverDistractionStateNotification];
[testManager updateDriverDistractionState:driverDistraction];
});

it(@"should update the driver distraction status and send a notification", ^{
Expand Down

0 comments on commit c182283

Please # to comment.