diff options
| author | Justin Gluck <justin.gluck@livio.io> | 2019-07-23 16:48:14 -0400 |
|---|---|---|
| committer | Justin Gluck <justin.gluck@livio.io> | 2019-07-23 16:48:14 -0400 |
| commit | 65d75f0310b82e12fc875a872bad6c66505f7888 (patch) | |
| tree | 188d96f1b0eb3bf5b02e5e427d3904bfbf42b3a4 /SmartDeviceLink | |
| parent | 4288fcaad0f9c61c69e5eb42e9f26710bb32ebf3 (diff) | |
| parent | 5f0190a9a7dd1196c0206fbccdc55a97b566bcaa (diff) | |
| download | sdl_ios-bugfix/issue-1352-Align-SDLSyncVersion.tar.gz | |
Merge branch 'develop' into bugfix/issue-1352-Align-SDLSyncVersionbugfix/issue-1352-Align-SDLSyncVersion
# Conflicts:
# SmartDeviceLink/SDLLifecycleManager.m
Diffstat (limited to 'SmartDeviceLink')
36 files changed, 369 insertions, 305 deletions
diff --git a/SmartDeviceLink/CVPixelBufferRef+SDLUtil.m b/SmartDeviceLink/CVPixelBufferRef+SDLUtil.m index 4234f76f1..1a62ece10 100644 --- a/SmartDeviceLink/CVPixelBufferRef+SDLUtil.m +++ b/SmartDeviceLink/CVPixelBufferRef+SDLUtil.m @@ -28,7 +28,7 @@ UIFont * _Nullable sdl_findFontSizeToFitText(CGSize size, NSString *text) { break; } - fontSize -= 1.0; + fontSize -= (CGFloat)1.0; } while (fontSize > 0.0); return (fontSize > 0) ? [UIFont systemFontOfSize:fontSize] : nil; diff --git a/SmartDeviceLink/Info.plist b/SmartDeviceLink/Info.plist index 8761e930d..0e0ef8021 100644 --- a/SmartDeviceLink/Info.plist +++ b/SmartDeviceLink/Info.plist @@ -15,7 +15,7 @@ <key>CFBundlePackageType</key> <string>FMWK</string> <key>CFBundleShortVersionString</key> - <string>6.3.0</string> + <string>6.3.1</string> <key>CFBundleSignature</key> <string>????</string> <key>CFBundleVersion</key> diff --git a/SmartDeviceLink/SDLAsynchronousOperation.m b/SmartDeviceLink/SDLAsynchronousOperation.m index 49450f49b..d2e12384d 100644 --- a/SmartDeviceLink/SDLAsynchronousOperation.m +++ b/SmartDeviceLink/SDLAsynchronousOperation.m @@ -8,16 +8,21 @@ #import "SDLAsynchronousOperation.h" +#import "SDLLogMacros.h" + @implementation SDLAsynchronousOperation { BOOL executing; BOOL finished; } - (void)start { + SDLLogV(@"Starting operation: %@", self); + if (self.isCancelled) { [self willChangeValueForKey:@"isFinished"]; finished = YES; [self didChangeValueForKey:@"isFinished"]; + SDLLogV(@"Operation was cancelled: %@", self); return; } @@ -28,6 +33,7 @@ } - (void)finishOperation { + SDLLogV(@"Finishing Operation: %@", self); [self willChangeValueForKey:@"isExecuting"]; executing = NO; [self didChangeValueForKey:@"isExecuting"]; diff --git a/SmartDeviceLink/SDLAsynchronousRPCRequestOperation.m b/SmartDeviceLink/SDLAsynchronousRPCRequestOperation.m index 5c67e3e8a..c77c80d52 100644 --- a/SmartDeviceLink/SDLAsynchronousRPCRequestOperation.m +++ b/SmartDeviceLink/SDLAsynchronousRPCRequestOperation.m @@ -91,29 +91,30 @@ NS_ASSUME_NONNULL_BEGIN - (void)sdl_sendRequest:(SDLRPCRequest *)request { __weak typeof(self) weakSelf = self; [self.connectionManager sendConnectionRequest:request withResponseHandler:^(__kindof SDLRPCRequest * _Nullable request, __kindof SDLRPCResponse * _Nullable response, NSError * _Nullable error) { - __strong typeof(self) strongSelf = weakSelf; + if (weakSelf == nil) { return; } - if (strongSelf.isCancelled) { - [self sdl_abortOperationWithRequest:request]; + if (weakSelf.isCancelled) { + [weakSelf sdl_abortOperationWithRequest:request]; BLOCK_RETURN; } - strongSelf.requestsComplete++; + weakSelf.requestsComplete++; // If this request failed set our internal request failed to YES if (error != nil) { - strongSelf.requestFailed = YES; + weakSelf.requestFailed = YES; } - if (strongSelf.progressHandler != NULL) { - strongSelf.progressHandler(request, response, error, strongSelf.percentComplete); - } else if (strongSelf.responseHandler != NULL) { - strongSelf.responseHandler(request, response, error); + if (weakSelf.progressHandler != NULL) { + float percentComplete = weakSelf.percentComplete; + weakSelf.progressHandler(request, response, error, percentComplete); + } else if (weakSelf.responseHandler != NULL) { + weakSelf.responseHandler(request, response, error); } // If we've received responses for all requests, call the completion handler. - if (strongSelf.requestsComplete >= strongSelf.requests.count) { - [strongSelf finishOperation]; + if (weakSelf.requestsComplete >= weakSelf.requests.count) { + [weakSelf finishOperation]; } }]; } diff --git a/SmartDeviceLink/SDLAudioStreamManager.m b/SmartDeviceLink/SDLAudioStreamManager.m index ff16f2b16..11d39812a 100755 --- a/SmartDeviceLink/SDLAudioStreamManager.m +++ b/SmartDeviceLink/SDLAudioStreamManager.m @@ -10,6 +10,7 @@ #import "SDLAudioFile.h" #import "SDLFile.h" +#import "SDLGlobals.h" #import "SDLLogMacros.h" #import "SDLManager.h" #import "SDLPCMAudioConverter.h" @@ -38,9 +39,14 @@ NSString *const SDLErrorDomainAudioStreamManager = @"com.sdl.extension.pcmAudioS if (!self) { return nil; } _mutableQueue = [NSMutableArray array]; - _audioQueue = dispatch_queue_create("com.sdl.audiomanager.transcode", DISPATCH_QUEUE_SERIAL); _shouldPlayWhenReady = NO; + if (@available(iOS 10.0, *)) { + _audioQueue = dispatch_queue_create_with_target("com.sdl.audiomanager.transcode", DISPATCH_QUEUE_SERIAL, [SDLGlobals sharedGlobals].sdlProcessingQueue); + } else { + _audioQueue = [SDLGlobals sharedGlobals].sdlProcessingQueue; + } + _streamManager = streamManager; return self; @@ -146,7 +152,7 @@ NSString *const SDLErrorDomainAudioStreamManager = @"com.sdl.extension.pcmAudioS // Determine the length of the audio PCM data and perform a few items once the audio has finished playing float audioLengthSecs = (float)audioData.length / (float)32000.0; __weak typeof(self) weakself = self; - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(audioLengthSecs * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(audioLengthSecs * NSEC_PER_SEC)), [SDLGlobals sharedGlobals].sdlProcessingQueue, ^{ __strong typeof(weakself) strongSelf = weakself; strongSelf.playing = NO; diff --git a/SmartDeviceLink/SDLCheckChoiceVROptionalOperation.m b/SmartDeviceLink/SDLCheckChoiceVROptionalOperation.m index f42144e67..abe323689 100644 --- a/SmartDeviceLink/SDLCheckChoiceVROptionalOperation.m +++ b/SmartDeviceLink/SDLCheckChoiceVROptionalOperation.m @@ -18,6 +18,7 @@ NS_ASSUME_NONNULL_BEGIN @interface SDLCheckChoiceVROptionalOperation() +@property (strong, nonatomic) NSUUID *operationId; @property (weak, nonatomic) id<SDLConnectionManagerType> connectionManager; @property (copy, nonatomic, nullable) NSError *internalError; @@ -30,6 +31,7 @@ NS_ASSUME_NONNULL_BEGIN if (!self) { return nil; } _connectionManager = connectionManager; + _operationId = [NSUUID UUID]; return self; } @@ -94,7 +96,7 @@ NS_ASSUME_NONNULL_BEGIN #pragma mark - Property Overrides - (nullable NSString *)name { - return @"com.sdl.choicesetmanager.checkVROptional"; + return [NSString stringWithFormat:@"%@ - %@", self.class, self.operationId]; } - (NSOperationQueuePriority)queuePriority { diff --git a/SmartDeviceLink/SDLChoiceSetManager.m b/SmartDeviceLink/SDLChoiceSetManager.m index 037878fc5..7818dac24 100644 --- a/SmartDeviceLink/SDLChoiceSetManager.m +++ b/SmartDeviceLink/SDLChoiceSetManager.m @@ -21,6 +21,7 @@ #import "SDLDisplayCapabilities+ShowManagerExtensions.h" #import "SDLError.h" #import "SDLFileManager.h" +#import "SDLGlobals.h" #import "SDLHMILevel.h" #import "SDLKeyboardProperties.h" #import "SDLLogMacros.h" @@ -127,9 +128,9 @@ UInt16 const ChoiceCellIdMin = 1; - (NSOperationQueue *)sdl_newTransactionQueue { NSOperationQueue *queue = [[NSOperationQueue alloc] init]; - queue.name = @"SDLChoiceSetManager Transaction Queue"; + queue.name = @"com.sdl.screenManager.choiceSetManager.transactionQueue"; queue.maxConcurrentOperationCount = 1; - queue.qualityOfService = NSQualityOfServiceUserInitiated; + queue.underlyingQueue = [SDLGlobals sharedGlobals].sdlConcurrentQueue; queue.suspended = YES; return queue; diff --git a/SmartDeviceLink/SDLDeleteChoicesOperation.m b/SmartDeviceLink/SDLDeleteChoicesOperation.m index 46b7c0d6d..7fd42a491 100644 --- a/SmartDeviceLink/SDLDeleteChoicesOperation.m +++ b/SmartDeviceLink/SDLDeleteChoicesOperation.m @@ -23,6 +23,7 @@ NS_ASSUME_NONNULL_BEGIN @interface SDLDeleteChoicesOperation() +@property (strong, nonatomic) NSUUID *operationId; @property (strong, nonatomic) NSSet<SDLChoiceCell *> *cellsToDelete; @property (weak, nonatomic) id<SDLConnectionManagerType> connectionManager; @property (copy, nonatomic, nullable) NSError *internalError; @@ -37,6 +38,7 @@ NS_ASSUME_NONNULL_BEGIN _connectionManager = connectionManager; _cellsToDelete = cells; + _operationId = [NSUUID UUID]; return self; } @@ -71,7 +73,7 @@ NS_ASSUME_NONNULL_BEGIN #pragma mark - Property Overrides - (nullable NSString *)name { - return @"com.sdl.choicesetmanager.deleteChoices"; + return [NSString stringWithFormat:@"%@ - %@", self.class, self.operationId]; } - (NSOperationQueuePriority)queuePriority { diff --git a/SmartDeviceLink/SDLDeleteFileOperation.h b/SmartDeviceLink/SDLDeleteFileOperation.h index 78563c58f..9252ae725 100644 --- a/SmartDeviceLink/SDLDeleteFileOperation.h +++ b/SmartDeviceLink/SDLDeleteFileOperation.h @@ -29,6 +29,21 @@ NS_ASSUME_NONNULL_BEGIN */ - (instancetype)initWithFileName:(NSString *)fileName connectionManager:(id<SDLConnectionManagerType>)connectionManager completionHandler:(nullable SDLFileManagerDeleteCompletionHandler)completionHandler; +/** + The name of the file to be deleted on the remote system. + */ +@property (copy, nonatomic, readonly) NSString *fileName; + +/** + The connection manager which will handle transporting the request to the remote system. + */ +@property (weak, nonatomic, readonly) id<SDLConnectionManagerType> connectionManager; + +/** + A completion handler to be called when the delete finishes. + */ +@property (copy, nonatomic, nullable, readonly) SDLFileManagerDeleteCompletionHandler completionHandler; + @end -NS_ASSUME_NONNULL_END
\ No newline at end of file +NS_ASSUME_NONNULL_END diff --git a/SmartDeviceLink/SDLDeleteFileOperation.m b/SmartDeviceLink/SDLDeleteFileOperation.m index 4d974a2ad..fa1de55f6 100644 --- a/SmartDeviceLink/SDLDeleteFileOperation.m +++ b/SmartDeviceLink/SDLDeleteFileOperation.m @@ -69,7 +69,7 @@ NS_ASSUME_NONNULL_BEGIN #pragma mark Property Overrides - (nullable NSString *)name { - return self.fileName; + return [NSString stringWithFormat:@"%@ - %@", self.class, self.fileName]; } - (NSOperationQueuePriority)queuePriority { diff --git a/SmartDeviceLink/SDLFile.m b/SmartDeviceLink/SDLFile.m index 3e69a943c..1efe7454b 100644 --- a/SmartDeviceLink/SDLFile.m +++ b/SmartDeviceLink/SDLFile.m @@ -166,6 +166,10 @@ NS_ASSUME_NONNULL_BEGIN #pragma mark - NSObject overrides +- (NSString *)description { + return [NSString stringWithFormat:@"SDLFile: %@", self.name]; +} + - (NSUInteger)hash { return self.name.hash ^ self.data.hash; } diff --git a/SmartDeviceLink/SDLFileManager.m b/SmartDeviceLink/SDLFileManager.m index eef7e92ac..215c098d2 100644 --- a/SmartDeviceLink/SDLFileManager.m +++ b/SmartDeviceLink/SDLFileManager.m @@ -45,14 +45,13 @@ SDLFileManagerState *const SDLFileManagerStateStartupError = @"StartupError"; // Local state @property (strong, nonatomic) NSOperationQueue *transactionQueue; -@property (strong, nonatomic) NSMutableDictionary<SDLFileName *, NSOperation *> *uploadsInProgress; @property (strong, nonatomic) NSMutableSet<SDLFileName *> *uploadedEphemeralFileNames; @property (strong, nonatomic) SDLStateMachine *stateMachine; @property (copy, nonatomic, nullable) SDLFileManagerStartupCompletionHandler startupCompletionHandler; @property (strong, nonatomic) NSMutableDictionary<SDLFileName *, NSNumber<SDLUInt> *> *failedFileUploadsCount; -@property (assign, nonatomic) UInt8 maxFileUploadAttempts; -@property (assign, nonatomic) UInt8 maxArtworkUploadAttempts; +@property (assign, nonatomic) NSUInteger maxFileUploadAttempts; +@property (assign, nonatomic) NSUInteger maxArtworkUploadAttempts; @end @@ -77,9 +76,9 @@ SDLFileManagerState *const SDLFileManagerStateStartupError = @"StartupError"; _mutableRemoteFileNames = [NSMutableSet set]; _transactionQueue = [[NSOperationQueue alloc] init]; - _transactionQueue.name = @"SDLFileManager Transaction Queue"; + _transactionQueue.name = @"com.sdl.fileManager.transactionQueue"; + _transactionQueue.underlyingQueue = [SDLGlobals sharedGlobals].sdlProcessingQueue; _transactionQueue.maxConcurrentOperationCount = 1; - _uploadsInProgress = [[NSMutableDictionary alloc] init]; _uploadedEphemeralFileNames = [[NSMutableSet<SDLFileName *> alloc] init]; _stateMachine = [[SDLStateMachine alloc] initWithTarget:self initialState:SDLFileManagerStateShutdown states:[self.class sdl_stateTransitionDictionary]]; @@ -105,11 +104,13 @@ SDLFileManagerState *const SDLFileManagerStateStartupError = @"StartupError"; - (void)stop { [self.stateMachine transitionToState:SDLFileManagerStateShutdown]; - - // Clear the failed uploads tracking so failed files can be uploaded again when a new connection has been established with Core - _failedFileUploadsCount = [NSMutableDictionary dictionary]; } +- (void)dealloc { + if (self.currentState != SDLFileManagerStateShutdown) { + [self.stateMachine transitionToState:SDLFileManagerStateShutdown]; + } +} #pragma mark - Getters @@ -161,6 +162,9 @@ SDLFileManagerState *const SDLFileManagerStateStartupError = @"StartupError"; [self.class sdl_clearTemporaryFileDirectory]; self.bytesAvailable = 0; + // Clear the failed uploads tracking so failed files can be uploaded again when a new connection has been established with Core + _failedFileUploadsCount = [NSMutableDictionary dictionary]; + if (self.startupCompletionHandler != nil) { self.startupCompletionHandler(NO, [NSError sdl_fileManager_unableToStartError]); self.startupCompletionHandler = nil; @@ -262,7 +266,7 @@ SDLFileManagerState *const SDLFileManagerStateStartupError = @"StartupError"; dispatch_group_leave(deleteFilesTask); // Wait for all files to be deleted - dispatch_group_notify(deleteFilesTask, dispatch_get_main_queue(), ^{ + dispatch_group_notify(deleteFilesTask, [SDLGlobals sharedGlobals].sdlProcessingQueue, ^{ if (completionHandler == nil) { return; } if (failedDeletes.count > 0) { return completionHandler([NSError sdl_fileManager_unableToDelete_ErrorWithUserInfo:failedDeletes]); @@ -302,9 +306,20 @@ SDLFileManagerState *const SDLFileManagerStateStartupError = @"StartupError"; dispatch_group_t uploadFilesTask = dispatch_group_create(); dispatch_group_enter(uploadFilesTask); - for(SDLFile *file in files) { - dispatch_group_enter(uploadFilesTask); + // Wait for all files to be uploaded + dispatch_group_notify(uploadFilesTask, [SDLGlobals sharedGlobals].sdlProcessingQueue, ^{ + if (completionHandler == nil) { return; } + if (failedUploads.count > 0) { + return completionHandler([NSError sdl_fileManager_unableToUpload_ErrorWithUserInfo:failedUploads]); + } + return completionHandler(nil); + }); + + for(NSUInteger i = 0; i < files.count; i++) { + SDLFile *file = files[i]; + dispatch_group_enter(uploadFilesTask); + __weak typeof(self) weakself = self; [self uploadFile:file completionHandler:^(BOOL success, NSUInteger bytesAvailable, NSError * _Nullable error) { if(!success) { failedUploads[file.name] = error; @@ -313,14 +328,17 @@ SDLFileManagerState *const SDLFileManagerStateStartupError = @"StartupError"; // Send an update for each file sent to the remote if (progressHandler != nil) { totalBytesUploaded += file.fileSize; - float uploadPercentage = [self sdl_uploadPercentage:totalBytesToUpload uploadedBytes:totalBytesUploaded]; + float uploadPercentage = [weakself sdl_uploadPercentage:totalBytesToUpload uploadedBytes:totalBytesUploaded]; BOOL continueWithRemainingUploads = progressHandler(file.name, uploadPercentage, error); if (!continueWithRemainingUploads) { // Cancel any remaining files waiting to be uploaded - for(SDLFile *file in files) { - NSOperation *fileUploadOperation = self.uploadsInProgress[file.name]; - if (fileUploadOperation) { - [fileUploadOperation cancel]; + for(NSUInteger j = i + 1; j < files.count; j++) { + SDLFile *cancelFile = files[j]; + for (SDLUploadFileOperation *op in weakself.transactionQueue.operations) { + if ([op.fileWrapper.file isEqual:cancelFile]) { + [op cancel]; + break; + } } } @@ -332,15 +350,6 @@ SDLFileManagerState *const SDLFileManagerStateStartupError = @"StartupError"; }]; } dispatch_group_leave(uploadFilesTask); - - // Wait for all files to be uploaded - dispatch_group_notify(uploadFilesTask, dispatch_get_main_queue(), ^{ - if (completionHandler == nil) { return; } - if (failedUploads.count > 0) { - return completionHandler([NSError sdl_fileManager_unableToUpload_ErrorWithUserInfo:failedUploads]); - } - return completionHandler(nil); - }); } - (void)uploadFile:(SDLFile *)file completionHandler:(nullable SDLFileManagerUploadCompletionHandler)handler { @@ -372,7 +381,7 @@ SDLFileManagerState *const SDLFileManagerStateStartupError = @"StartupError"; } // Check our overwrite settings and error out if it would overwrite - if (file.overwrite == NO && [self.remoteFileNames containsObject:file.name]) { + if (!file.overwrite && [self.remoteFileNames containsObject:file.name]) { if (handler != nil) { handler(NO, self.bytesAvailable, [NSError sdl_fileManager_cannotOverwriteError]); } @@ -389,21 +398,17 @@ SDLFileManagerState *const SDLFileManagerStateStartupError = @"StartupError"; __weak typeof(self) weakSelf = self; SDLFileWrapper *fileWrapper = [SDLFileWrapper wrapperWithFile:file completionHandler:^(BOOL success, NSUInteger bytesAvailable, NSError *_Nullable error) { - if (self.uploadsInProgress[file.name]) { - [self.uploadsInProgress removeObjectForKey:file.name]; - } - if (success) { weakSelf.bytesAvailable = bytesAvailable; [weakSelf.mutableRemoteFileNames addObject:fileName]; [weakSelf.uploadedEphemeralFileNames addObject:fileName]; } else { - self.failedFileUploadsCount = [self.class sdl_incrementFailedUploadCountForFileName:file.name failedFileUploadsCount:self.failedFileUploadsCount]; + weakSelf.failedFileUploadsCount = [weakSelf.class sdl_incrementFailedUploadCountForFileName:file.name failedFileUploadsCount:weakSelf.failedFileUploadsCount]; - UInt8 maxUploadCount = [file isKindOfClass:[SDLArtwork class]] ? self.maxArtworkUploadAttempts : self.maxFileUploadAttempts; - if ([self sdl_canFileBeUploadedAgain:file maxUploadCount:maxUploadCount failedFileUploadsCount:self.failedFileUploadsCount]) { + NSUInteger maxUploadCount = [file isMemberOfClass:[SDLArtwork class]] ? weakSelf.maxArtworkUploadAttempts : self.maxFileUploadAttempts; + if ([weakSelf sdl_canFileBeUploadedAgain:file maxUploadCount:maxUploadCount failedFileUploadsCount:weakSelf.failedFileUploadsCount]) { SDLLogD(@"Attempting to resend file with name %@ after a failed upload attempt", file.name); - return [self sdl_uploadFile:file completionHandler:handler]; + return [weakSelf sdl_uploadFile:file completionHandler:handler]; } } @@ -414,18 +419,18 @@ SDLFileManagerState *const SDLFileManagerStateStartupError = @"StartupError"; SDLUploadFileOperation *uploadOperation = [[SDLUploadFileOperation alloc] initWithFile:fileWrapper connectionManager:self.connectionManager]; - self.uploadsInProgress[file.name] = uploadOperation; [self.transactionQueue addOperation:uploadOperation]; } #pragma mark Artworks - (void)uploadArtwork:(SDLArtwork *)artwork completionHandler:(nullable SDLFileManagerUploadArtworkCompletionHandler)completion { + __weak typeof(self) weakself = self; [self uploadFile:artwork completionHandler:^(BOOL success, NSUInteger bytesAvailable, NSError * _Nullable error) { if (completion == nil) { return; } - if ([self sdl_isErrorCannotOverwriteError:error]) { + if ([weakself sdl_isErrorCannotOverwriteError:error]) { // Artwork with same name already uploaded to remote - return completion(true, artwork.name, bytesAvailable, nil); + return completion(YES, artwork.name, bytesAvailable, nil); } completion(success, artwork.name, bytesAvailable, error); }]; @@ -440,9 +445,10 @@ SDLFileManagerState *const SDLFileManagerStateStartupError = @"StartupError"; @throw [NSException sdl_missingFilesException]; } + __weak typeof(self) weakself = self; [self uploadFiles:artworks progressHandler:^BOOL(SDLFileName * _Nonnull fileName, float uploadPercentage, NSError * _Nullable error) { if (progressHandler == nil) { return YES; } - if ([self sdl_isErrorCannotOverwriteError:error]) { + if ([weakself sdl_isErrorCannotOverwriteError:error]) { return progressHandler(fileName, uploadPercentage, nil); } return progressHandler(fileName, uploadPercentage, error); @@ -457,7 +463,7 @@ SDLFileManagerState *const SDLFileManagerStateStartupError = @"StartupError"; if (error != nil) { for (NSString *erroredArtworkName in error.userInfo) { - if (![self sdl_isErrorCannotOverwriteError:[error.userInfo objectForKey:erroredArtworkName]]) { + if (![weakself sdl_isErrorCannotOverwriteError:error.userInfo[erroredArtworkName]]) { [successfulArtworkUploadNames removeObject:erroredArtworkName]; } else { // An overwrite error means that an artwork with the same name is already uploaded to the remote @@ -523,7 +529,7 @@ SDLFileManagerState *const SDLFileManagerStateStartupError = @"StartupError"; * @param maxUploadCount The max number of times the file is allowed to be uploaded to Core * @return True if the file still needs to be (re)sent to Core; false if not. */ -- (BOOL)sdl_canFileBeUploadedAgain:(nullable SDLFile *)file maxUploadCount:(UInt8)maxUploadCount failedFileUploadsCount:(NSMutableDictionary<SDLFileName *, NSNumber<SDLUInt> *> *)failedFileUploadsCount { +- (BOOL)sdl_canFileBeUploadedAgain:(nullable SDLFile *)file maxUploadCount:(NSUInteger)maxUploadCount failedFileUploadsCount:(NSMutableDictionary<SDLFileName *, NSNumber<SDLUInt> *> *)failedFileUploadsCount { if (![self.currentState isEqualToString:SDLFileManagerStateReady]) { SDLLogW(@"File named %@ failed to upload. The file manager has shutdown so the file upload will not retry.", file.name); return NO; @@ -540,7 +546,7 @@ SDLFileManagerState *const SDLFileManagerStateStartupError = @"StartupError"; } NSNumber *failedUploadCount = failedFileUploadsCount[file.name]; - BOOL canFileBeUploadedAgain = (failedUploadCount == nil) ? YES : (failedUploadCount.integerValue < maxUploadCount); + BOOL canFileBeUploadedAgain = (failedUploadCount == nil) ? YES : (failedUploadCount.unsignedIntegerValue < maxUploadCount); if (!canFileBeUploadedAgain) { SDLLogE(@"File named %@ failed to upload. Max number of upload attempts reached.", file.name); } diff --git a/SmartDeviceLink/SDLFocusableItemLocator.m b/SmartDeviceLink/SDLFocusableItemLocator.m index e3fb4d451..9ab7da07a 100644 --- a/SmartDeviceLink/SDLFocusableItemLocator.m +++ b/SmartDeviceLink/SDLFocusableItemLocator.m @@ -148,7 +148,13 @@ NS_ASSUME_NONNULL_BEGIN @param notification object with notification data */ - (void)sdl_projectionViewUpdated:(NSNotification *)notification { - [self updateInterfaceLayout]; + if ([NSThread isMainThread]) { + [self updateInterfaceLayout]; + } else { + dispatch_async(dispatch_get_main_queue(), ^{ + [self updateInterfaceLayout]; + }); + } } @end diff --git a/SmartDeviceLink/SDLGlobals.h b/SmartDeviceLink/SDLGlobals.h index cf34de68a..2d4edf017 100644 --- a/SmartDeviceLink/SDLGlobals.h +++ b/SmartDeviceLink/SDLGlobals.h @@ -32,6 +32,9 @@ extern NSUInteger const SDLV3MTUSize; @property (strong, nonatomic) SDLVersion *rpcVersion; @property (copy, nonatomic) SDLVersion *maxHeadUnitProtocolVersion; +@property (copy, nonatomic) dispatch_queue_t sdlProcessingQueue; +@property (copy, nonatomic) dispatch_queue_t sdlConcurrentQueue; + + (instancetype)sharedGlobals; - (void)setDynamicMTUSize:(NSUInteger)maxMTUSize forServiceType:(SDLServiceType)serviceType; diff --git a/SmartDeviceLink/SDLGlobals.m b/SmartDeviceLink/SDLGlobals.m index 874f58ed7..dfff3ca50 100644 --- a/SmartDeviceLink/SDLGlobals.m +++ b/SmartDeviceLink/SDLGlobals.m @@ -58,6 +58,12 @@ typedef NSNumber *MTUBox; _rpcVersion = [[SDLVersion alloc] initWithString:@"1.0.0"]; _dynamicMTUDict = [NSMutableDictionary dictionary]; + dispatch_queue_attr_t qosSerial = dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_USER_INITIATED, 0); + dispatch_queue_attr_t qosConcurrent = dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_CONCURRENT, QOS_CLASS_USER_INITIATED, 0); + + _sdlProcessingQueue = dispatch_queue_create("com.sdl.serialProcessing", qosSerial); + _sdlConcurrentQueue = dispatch_queue_create("com.sdl.concurrentProcessing", qosConcurrent); + return self; } diff --git a/SmartDeviceLink/SDLIAPTransport.m b/SmartDeviceLink/SDLIAPTransport.m index d67b2f11e..e83e5aa3d 100644 --- a/SmartDeviceLink/SDLIAPTransport.m +++ b/SmartDeviceLink/SDLIAPTransport.m @@ -80,7 +80,7 @@ int const CreateSessionRetries = 3; */ - (void)sdl_stopEventListening { SDLLogV(@"SDLIAPTransport stopped listening for events"); - [[EAAccessoryManager sharedAccessoryManager] unregisterForLocalNotifications]; + [[NSNotificationCenter defaultCenter] removeObserver:self]; } #pragma mark EAAccessory Notifications diff --git a/SmartDeviceLink/SDLLifecycleManager.m b/SmartDeviceLink/SDLLifecycleManager.m index 8c83f9da9..d59b1e4eb 100644 --- a/SmartDeviceLink/SDLLifecycleManager.m +++ b/SmartDeviceLink/SDLLifecycleManager.m @@ -127,8 +127,13 @@ NSString *const BackgroundTaskTransportName = @"com.sdl.transport.backgroundTask _rpcOperationQueue = [[NSOperationQueue alloc] init]; _rpcOperationQueue.name = @"com.sdl.lifecycle.rpcOperation.concurrent"; - _rpcOperationQueue.maxConcurrentOperationCount = 3; - _lifecycleQueue = dispatch_queue_create("com.sdl.lifecycle", DISPATCH_QUEUE_SERIAL); + _rpcOperationQueue.underlyingQueue = [SDLGlobals sharedGlobals].sdlConcurrentQueue; + + if (@available(iOS 10.0, *)) { + _lifecycleQueue = dispatch_queue_create_with_target("com.sdl.lifecycle", DISPATCH_QUEUE_SERIAL, [SDLGlobals sharedGlobals].sdlProcessingQueue); + } else { + _lifecycleQueue = [SDLGlobals sharedGlobals].sdlProcessingQueue; + } // Managers _fileManager = [[SDLFileManager alloc] initWithConnectionManager:self configuration:_configuration.fileManagerConfig]; @@ -273,7 +278,7 @@ NSString *const BackgroundTaskTransportName = @"com.sdl.transport.backgroundTask // Due to a race condition internally with EAStream, we cannot immediately attempt to restart the proxy, as we will randomly crash. // Apple Bug ID #30059457 __weak typeof(self) weakSelf = self; - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), self.lifecycleQueue, ^{ __strong typeof(weakSelf) strongSelf = weakSelf; if (!strongSelf) { return; } @@ -313,25 +318,23 @@ NSString *const BackgroundTaskTransportName = @"com.sdl.transport.backgroundTask __weak typeof(self) weakSelf = self; [self sdl_sendRequest:regRequest withResponseHandler:^(__kindof SDLRPCRequest *_Nullable request, __kindof SDLRPCResponse *_Nullable response, NSError *_Nullable error) { - dispatch_async(weakSelf.lifecycleQueue, ^{ - // If the success BOOL is NO or we received an error at this point, we failed. Call the ready handler and transition to the DISCONNECTED state. - if (error != nil || ![response.success boolValue]) { - SDLLogE(@"Failed to register the app. Error: %@, Response: %@", error, response); - if (weakSelf.readyHandler) { - weakSelf.readyHandler(NO, error); - } - - if (weakSelf.lifecycleState != SDLLifecycleStateReconnecting) { - [weakSelf sdl_transitionToState:SDLLifecycleStateStopped]; - } - - return; + // If the success BOOL is NO or we received an error at this point, we failed. Call the ready handler and transition to the DISCONNECTED state. + if (error != nil || ![response.success boolValue]) { + SDLLogE(@"Failed to register the app. Error: %@, Response: %@", error, response); + if (weakSelf.readyHandler) { + weakSelf.readyHandler(NO, error); } - weakSelf.registerResponse = (SDLRegisterAppInterfaceResponse *)response; - [SDLGlobals sharedGlobals].rpcVersion = [SDLVersion versionWithSDLMsgVersion:weakSelf.registerResponse.sdlMsgVersion]; - [weakSelf sdl_transitionToState:SDLLifecycleStateRegistered]; - }); + if (weakSelf.lifecycleState != SDLLifecycleStateReconnecting) { + [weakSelf sdl_transitionToState:SDLLifecycleStateStopped]; + } + + return; + } + + weakSelf.registerResponse = (SDLRegisterAppInterfaceResponse *)response; + [SDLGlobals sharedGlobals].rpcVersion = [SDLVersion versionWithSDLMsgVersion:weakSelf.registerResponse.sdlMsgVersion]; + [weakSelf sdl_transitionToState:SDLLifecycleStateRegistered]; }]; } @@ -483,23 +486,19 @@ NSString *const BackgroundTaskTransportName = @"com.sdl.transport.backgroundTask } // If we got to this point, we succeeded, send the error if there was a warning. - dispatch_async(dispatch_get_main_queue(), ^{ - self.readyHandler(YES, startError); - }); + self.readyHandler(YES, startError); [self.notificationDispatcher postNotificationName:SDLDidBecomeReady infoObject:nil]; // Send the hmi level going from NONE to whatever we're at now (could still be NONE) - dispatch_async(dispatch_get_main_queue(), ^{ - [self.delegate hmiLevel:SDLHMILevelNone didChangeToLevel:self.hmiLevel]; + [self.delegate hmiLevel:SDLHMILevelNone didChangeToLevel:self.hmiLevel]; - // Send the audio streaming state going from NOT_AUDIBLE to whatever we're at now (could still be NOT_AUDIBLE) - if ([self.delegate respondsToSelector:@selector(audioStreamingState:didChangeToState:)]) { - [self.delegate audioStreamingState:SDLAudioStreamingStateNotAudible didChangeToState:self.audioStreamingState]; - } - }); + // Send the audio streaming state going from NOT_AUDIBLE to whatever we're at now (could still be NOT_AUDIBLE) + if ([self.delegate respondsToSelector:@selector(audioStreamingState:didChangeToState:)]) { + [self.delegate audioStreamingState:SDLAudioStreamingStateNotAudible didChangeToState:self.audioStreamingState]; + } - // Stop the background task now that setup has completed + // Stop the background task now that setup has completed [self.backgroundTaskManager endBackgroundTask]; } @@ -607,33 +606,25 @@ NSString *const BackgroundTaskTransportName = @"com.sdl.transport.backgroundTask return; } - dispatch_async(_lifecycleQueue, ^{ - [self sdl_sendRequest:rpc withResponseHandler:nil]; - }); + [self sdl_sendRequest:rpc withResponseHandler:nil]; } - (void)sendConnectionRequest:(__kindof SDLRPCRequest *)request withResponseHandler:(nullable SDLResponseHandler)handler { if (![self.lifecycleStateMachine isCurrentState:SDLLifecycleStateReady]) { SDLLogW(@"Manager not ready, request not sent (%@)", request); if (handler) { - dispatch_async(dispatch_get_main_queue(), ^{ - handler(request, nil, [NSError sdl_lifecycle_notReadyError]); - }); + handler(request, nil, [NSError sdl_lifecycle_notReadyError]); } return; } - dispatch_async(_lifecycleQueue, ^{ - [self sdl_sendRequest:request withResponseHandler:handler]; - }); + [self sdl_sendRequest:request withResponseHandler:handler]; } // Managers need to avoid state checking. Part of <SDLConnectionManagerType>. - (void)sendConnectionManagerRequest:(__kindof SDLRPCMessage *)request withResponseHandler:(nullable SDLResponseHandler)handler { - dispatch_async(_lifecycleQueue, ^{ - [self sdl_sendRequest:request withResponseHandler:handler]; - }); + [self sdl_sendRequest:request withResponseHandler:handler]; } - (void)sdl_sendRequest:(__kindof SDLRPCMessage *)request withResponseHandler:(nullable SDLResponseHandler)handler { @@ -645,9 +636,7 @@ NSString *const BackgroundTaskTransportName = @"com.sdl.transport.backgroundTask NSError *error = [NSError sdl_lifecycle_rpcErrorWithDescription:@"Nil Request Sent" andReason:@"A nil RPC request was passed and cannot be sent."]; SDLLogW(@"%@", error); if (handler) { - dispatch_async(dispatch_get_main_queue(), ^{ - handler(nil, nil, error); - }); + handler(nil, nil, error); } return; } @@ -686,8 +675,18 @@ NSString *const BackgroundTaskTransportName = @"com.sdl.transport.backgroundTask } // this is to make sure that the transition happens on the dedicated queue +- (void)sdl_runOnProcessingQueue:(void (^)(void))block { + if (strcmp(dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL), dispatch_queue_get_label(self.lifecycleQueue)) == 0 + || strcmp(dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL), dispatch_queue_get_label([SDLGlobals sharedGlobals].sdlProcessingQueue)) == 0) { + block(); + } else { + dispatch_sync(self.lifecycleQueue, block); + } +} + - (void)sdl_transitionToState:(SDLState *)state { - if (strcmp(dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL), dispatch_queue_get_label(self.lifecycleQueue)) == 0) { + if (strcmp(dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL), dispatch_queue_get_label(self.lifecycleQueue)) == 0 + || strcmp(dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL), dispatch_queue_get_label([SDLGlobals sharedGlobals].sdlProcessingQueue)) == 0) { [self.lifecycleStateMachine transitionToState:state]; } else { // once this method returns, the transition is completed @@ -769,24 +768,22 @@ NSString *const BackgroundTaskTransportName = @"com.sdl.transport.backgroundTask return; } - dispatch_async(dispatch_get_main_queue(), ^{ - if (![oldHMILevel isEqualToEnum:self.hmiLevel] - && !(oldHMILevel == nil && self.hmiLevel == nil)) { - [self.delegate hmiLevel:oldHMILevel didChangeToLevel:self.hmiLevel]; - } + if (![oldHMILevel isEqualToEnum:self.hmiLevel] + && !(oldHMILevel == nil && self.hmiLevel == nil)) { + [self.delegate hmiLevel:oldHMILevel didChangeToLevel:self.hmiLevel]; + } - if (![oldStreamingState isEqualToEnum:self.audioStreamingState] - && !(oldStreamingState == nil && self.audioStreamingState == nil) - && [self.delegate respondsToSelector:@selector(audioStreamingState:didChangeToState:)]) { - [self.delegate audioStreamingState:oldStreamingState didChangeToState:self.audioStreamingState]; - } + if (![oldStreamingState isEqualToEnum:self.audioStreamingState] + && !(oldStreamingState == nil && self.audioStreamingState == nil) + && [self.delegate respondsToSelector:@selector(audioStreamingState:didChangeToState:)]) { + [self.delegate audioStreamingState:oldStreamingState didChangeToState:self.audioStreamingState]; + } - if (![oldSystemContext isEqualToEnum:self.systemContext] - && !(oldSystemContext == nil && self.systemContext == nil) - && [self.delegate respondsToSelector:@selector(systemContext:didChangeToContext:)]) { - [self.delegate systemContext:oldSystemContext didChangeToContext:self.systemContext]; - } - }); + if (![oldSystemContext isEqualToEnum:self.systemContext] + && !(oldSystemContext == nil && self.systemContext == nil) + && [self.delegate respondsToSelector:@selector(systemContext:didChangeToContext:)]) { + [self.delegate systemContext:oldSystemContext didChangeToContext:self.systemContext]; + } } - (void)remoteHardwareDidUnregister:(SDLRPCNotificationNotification *)notification { diff --git a/SmartDeviceLink/SDLListFilesOperation.h b/SmartDeviceLink/SDLListFilesOperation.h index 9107ef758..fc8453820 100644 --- a/SmartDeviceLink/SDLListFilesOperation.h +++ b/SmartDeviceLink/SDLListFilesOperation.h @@ -28,6 +28,16 @@ NS_ASSUME_NONNULL_BEGIN */ - (instancetype)initWithConnectionManager:(id<SDLConnectionManagerType>)connectionManager completionHandler:(nullable SDLFileManagerListFilesCompletionHandler)completionHandler; +/** + The connection manager which will handle transporting the request to the remote system. + */ +@property (weak, nonatomic, readonly) id<SDLConnectionManagerType> connectionManager; + +/** + A completion handler for when the response returns. + */ +@property (copy, nonatomic, nullable, readonly) SDLFileManagerListFilesCompletionHandler completionHandler; + @end NS_ASSUME_NONNULL_END diff --git a/SmartDeviceLink/SDLListFilesOperation.m b/SmartDeviceLink/SDLListFilesOperation.m index ca45ac928..5e6ace166 100644 --- a/SmartDeviceLink/SDLListFilesOperation.m +++ b/SmartDeviceLink/SDLListFilesOperation.m @@ -17,6 +17,7 @@ NS_ASSUME_NONNULL_BEGIN @interface SDLListFilesOperation () +@property (strong, nonatomic) NSUUID *operationId; @property (weak, nonatomic) id<SDLConnectionManagerType> connectionManager; @property (copy, nonatomic, nullable) SDLFileManagerListFilesCompletionHandler completionHandler; @@ -31,6 +32,7 @@ NS_ASSUME_NONNULL_BEGIN return nil; } + _operationId = [NSUUID UUID]; _connectionManager = connectionManager; _completionHandler = completionHandler; @@ -67,7 +69,7 @@ NS_ASSUME_NONNULL_BEGIN #pragma mark Property Overrides - (nullable NSString *)name { - return @"List Files"; + return [NSString stringWithFormat:@"%@ - %@", self.class, self.operationId]; } - (NSOperationQueuePriority)queuePriority { diff --git a/SmartDeviceLink/SDLLogFileModuleMap.m b/SmartDeviceLink/SDLLogFileModuleMap.m index 11e7466e7..e9e2a56ba 100644 --- a/SmartDeviceLink/SDLLogFileModuleMap.m +++ b/SmartDeviceLink/SDLLogFileModuleMap.m @@ -60,7 +60,7 @@ } + (SDLLogFileModule *)sdl_lifecycleManagerModule { - return [SDLLogFileModule moduleWithName:@"Lifecycle" files:[NSSet setWithArray:@[@"SDLLifecycleManager", @"SDLManager"]]]; + return [SDLLogFileModule moduleWithName:@"Lifecycle" files:[NSSet setWithArray:@[@"SDLLifecycleManager", @"SDLManager", @"SDLAsynchronousOperation"]]]; } + (SDLLogFileModule *)sdl_systemCapabilityModule { diff --git a/SmartDeviceLink/SDLLogManager.m b/SmartDeviceLink/SDLLogManager.m index 22918ed9c..ae0fa317f 100644 --- a/SmartDeviceLink/SDLLogManager.m +++ b/SmartDeviceLink/SDLLogManager.m @@ -8,6 +8,7 @@ #import "SDLLogManager.h" +#import "SDLGlobals.h" #import "SDLHexUtility.h" #import "SDLLogConfiguration.h" #import "SDLLogFileModule.h" @@ -189,9 +190,7 @@ static dispatch_queue_t _logQueue = NULL; } - (void)sdl_syncLog:(SDLLogModel *)log { - dispatch_sync(self.class.logQueue, ^{ - [self sdl_log:log]; - }); + [self sdl_log:log]; } - (void)sdl_log:(SDLLogModel *)log { @@ -341,7 +340,11 @@ static dispatch_queue_t _logQueue = NULL; + (dispatch_queue_t)logQueue { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ - _logQueue = dispatch_queue_create("com.sdl.log", DISPATCH_QUEUE_SERIAL); + if (@available(iOS 10.0, *)) { + _logQueue = dispatch_queue_create_with_target("com.sdl.log", DISPATCH_QUEUE_SERIAL, [SDLGlobals sharedGlobals].sdlProcessingQueue); + } else { + _logQueue = [SDLGlobals sharedGlobals].sdlProcessingQueue; + } }); return _logQueue; diff --git a/SmartDeviceLink/SDLMenuManager.m b/SmartDeviceLink/SDLMenuManager.m index 734e1fc00..3f95a5353 100644 --- a/SmartDeviceLink/SDLMenuManager.m +++ b/SmartDeviceLink/SDLMenuManager.m @@ -382,10 +382,10 @@ UInt32 const MenuCellIdMin = 1; } self.inProgressUpdate = [mainMenuCommands arrayByAddingObjectsFromArray:subMenuCommands]; - + __block NSMutableDictionary<SDLRPCRequest *, NSError *> *errors = [NSMutableDictionary dictionary]; __weak typeof(self) weakSelf = self; - [self.connectionManager sendRequests:mainMenuCommands progressHandler:^(__kindof SDLRPCRequest * _Nonnull request, __kindof SDLRPCResponse * _Nullable response, NSError * _Nullable error, float percentComplete) { + [self.connectionManager sendRequests:mainMenuCommands progressHandler:^void(__kindof SDLRPCRequest * _Nonnull request, __kindof SDLRPCResponse * _Nullable response, NSError * _Nullable error, float percentComplete) { if (error != nil) { errors[request] = error; } diff --git a/SmartDeviceLink/SDLPreloadChoicesOperation.m b/SmartDeviceLink/SDLPreloadChoicesOperation.m index caedc168b..a2f83b5b7 100644 --- a/SmartDeviceLink/SDLPreloadChoicesOperation.m +++ b/SmartDeviceLink/SDLPreloadChoicesOperation.m @@ -30,6 +30,7 @@ NS_ASSUME_NONNULL_BEGIN @interface SDLPreloadChoicesOperation() +@property (strong, nonatomic) NSUUID *operationId; @property (strong, nonatomic) NSMutableSet<SDLChoiceCell *> *cellsToUpload; @property (strong, nonatomic) SDLDisplayCapabilities *displayCapabilities; @property (assign, nonatomic, getter=isVROptional) BOOL vrOptional; @@ -51,6 +52,7 @@ NS_ASSUME_NONNULL_BEGIN _displayCapabilities = displayCapabilities; _vrOptional = isVROptional; _cellsToUpload = [cells mutableCopy]; + _operationId = [NSUUID UUID]; _currentState = SDLPreloadChoicesOperationStateWaitingToStart; @@ -191,7 +193,7 @@ NS_ASSUME_NONNULL_BEGIN } - (nullable NSString *)name { - return @"com.sdl.choicesetmanager.preloadChoices"; + return [NSString stringWithFormat:@"%@ - %@", self.class, self.operationId]; } - (NSOperationQueuePriority)queuePriority { diff --git a/SmartDeviceLink/SDLPresentChoiceSetOperation.m b/SmartDeviceLink/SDLPresentChoiceSetOperation.m index 4e923b8e1..a1644fd2e 100644 --- a/SmartDeviceLink/SDLPresentChoiceSetOperation.m +++ b/SmartDeviceLink/SDLPresentChoiceSetOperation.m @@ -32,6 +32,7 @@ NS_ASSUME_NONNULL_BEGIN @interface SDLPresentChoiceSetOperation() +@property (strong, nonatomic) NSUUID *operationId; @property (weak, nonatomic) id<SDLConnectionManagerType> connectionManager; @property (strong, nonatomic, readwrite) SDLChoiceSet *choiceSet; @property (strong, nonatomic) SDLInteractionMode presentationMode; @@ -60,6 +61,7 @@ NS_ASSUME_NONNULL_BEGIN _connectionManager = connectionManager; _choiceSet = choiceSet; _presentationMode = mode; + _operationId = [NSUUID UUID]; _originalKeyboardProperties = originalKeyboardProperties; _keyboardProperties = originalKeyboardProperties; @@ -254,7 +256,7 @@ NS_ASSUME_NONNULL_BEGIN } - (nullable NSString *)name { - return @"com.sdl.choicesetmanager.presentChoiceSet"; + return [NSString stringWithFormat:@"%@ - %@", self.class, self.operationId]; } - (NSOperationQueuePriority)queuePriority { diff --git a/SmartDeviceLink/SDLPresentKeyboardOperation.m b/SmartDeviceLink/SDLPresentKeyboardOperation.m index b81284ebe..4899f8f46 100644 --- a/SmartDeviceLink/SDLPresentKeyboardOperation.m +++ b/SmartDeviceLink/SDLPresentKeyboardOperation.m @@ -23,6 +23,7 @@ NS_ASSUME_NONNULL_BEGIN @interface SDLPresentKeyboardOperation() +@property (strong, nonatomic) NSUUID *operationId; @property (weak, nonatomic) id<SDLConnectionManagerType> connectionManager; @property (weak, nonatomic) id<SDLKeyboardDelegate> keyboardDelegate; @property (copy, nonatomic) NSString *initialText; @@ -46,6 +47,7 @@ NS_ASSUME_NONNULL_BEGIN _keyboardDelegate = keyboardDelegate; _originalKeyboardProperties = originalKeyboardProperties; _keyboardProperties = originalKeyboardProperties; + _operationId = [NSUUID UUID]; return self; } @@ -163,7 +165,7 @@ NS_ASSUME_NONNULL_BEGIN #pragma mark - Property Overrides - (nullable NSString *)name { - return @"com.sdl.choicesetmanager.presentKeyboard"; + return [NSString stringWithFormat:@"%@ - %@", self.class, self.operationId]; } - (NSOperationQueuePriority)queuePriority { diff --git a/SmartDeviceLink/SDLProtocol.m b/SmartDeviceLink/SDLProtocol.m index 3f1996e92..5adfd5b88 100644 --- a/SmartDeviceLink/SDLProtocol.m +++ b/SmartDeviceLink/SDLProtocol.m @@ -39,8 +39,6 @@ NS_ASSUME_NONNULL_BEGIN @interface SDLProtocol () { UInt32 _messageID; - dispatch_queue_t _receiveQueue; - dispatch_queue_t _sendQueue; SDLPrioritizedObjectCollection *_prioritizedCollection; } @@ -65,8 +63,6 @@ NS_ASSUME_NONNULL_BEGIN if (self = [super init]) { _messageID = 0; _hashId = SDLControlFrameInt32NotFound; - _receiveQueue = dispatch_queue_create("com.sdl.protocol.receive", DISPATCH_QUEUE_SERIAL); - _sendQueue = dispatch_queue_create("com.sdl.protocol.transmit", DISPATCH_QUEUE_SERIAL); _prioritizedCollection = [[SDLPrioritizedObjectCollection alloc] init]; _protocolDelegateTable = [NSHashTable weakObjectsHashTable]; _serviceHeaders = [[NSMutableDictionary alloc] init]; @@ -357,13 +353,10 @@ NS_ASSUME_NONNULL_BEGIN - (void)sdl_sendDataToTransport:(NSData *)data onService:(NSInteger)priority { [_prioritizedCollection addObject:data withPriority:priority]; - // TODO: (Joel F.)[2016-02-11] Autoreleasepool? - dispatch_async(_sendQueue, ^{ - NSData *dataToTransmit = nil; - while (dataToTransmit = (NSData *)[self->_prioritizedCollection nextObject]) { - [self.transport sendData:dataToTransmit]; - }; - }); + NSData *dataToTransmit = nil; + while (dataToTransmit = (NSData *)[self->_prioritizedCollection nextObject]) { + [self.transport sendData:dataToTransmit]; + } } - (void)sendRawData:(NSData *)data withServiceType:(SDLServiceType)serviceType { @@ -465,9 +458,7 @@ NS_ASSUME_NONNULL_BEGIN self.receiveBuffer = [[self.receiveBuffer subdataWithRange:NSMakeRange(messageSize, self.receiveBuffer.length - messageSize)] mutableCopy]; // Pass on the message to the message router. - dispatch_async(_receiveQueue, ^{ - [self.messageRouter handleReceivedMessage:message]; - }); + [self.messageRouter handleReceivedMessage:message]; // Call recursively until the buffer is empty or incomplete message is encountered if (self.receiveBuffer.length > 0) { @@ -475,7 +466,6 @@ NS_ASSUME_NONNULL_BEGIN } } -// TODO: This is a v4 packet (create new delegate methods) - (void)handleProtocolStartServiceACKMessage:(SDLProtocolMessage *)startServiceACK { // V5 Packet if (startServiceACK.header.version >= 5) { diff --git a/SmartDeviceLink/SDLProxy.m b/SmartDeviceLink/SDLProxy.m index 6ab2006c8..f32b3de94 100644 --- a/SmartDeviceLink/SDLProxy.m +++ b/SmartDeviceLink/SDLProxy.m @@ -50,7 +50,7 @@ typedef NSString SDLVehicleMake; typedef void (^URLSessionTaskCompletionHandler)(NSData *data, NSURLResponse *response, NSError *error); typedef void (^URLSessionDownloadTaskCompletionHandler)(NSURL *location, NSURLResponse *response, NSError *error); -NSString *const SDLProxyVersion = @"6.3.0"; +NSString *const SDLProxyVersion = @"6.3.1"; const float StartSessionTime = 10.0; const float NotifyProxyClosedDelay = (float)0.1; const int PoliciesCorrelationId = 65535; @@ -65,7 +65,6 @@ static float DefaultConnectionTimeout = 45.0; @property (nullable, nonatomic, strong) SDLDisplayCapabilities *displayCapabilities; @property (nonatomic, strong) NSMutableDictionary<SDLVehicleMake *, Class> *securityManagers; @property (nonatomic, strong) NSURLSession* urlSession; -@property (strong, nonatomic) dispatch_queue_t rpcProcessingQueue; @end @@ -77,7 +76,6 @@ static float DefaultConnectionTimeout = 45.0; if (self = [super init]) { SDLLogD(@"Framework Version: %@", self.proxyVersion); _lsm = [[SDLLockScreenStatusManager alloc] init]; - _rpcProcessingQueue = dispatch_queue_create("com.sdl.rpcProcessingQueue", DISPATCH_QUEUE_SERIAL); _mutableProxyListeners = [NSMutableSet setWithObject:delegate]; _securityManagers = [NSMutableDictionary dictionary]; @@ -150,13 +148,15 @@ static float DefaultConnectionTimeout = 45.0; #pragma mark - Application Lifecycle - (void)sendMobileHMIState { - dispatch_async(dispatch_get_main_queue(), ^{ - [self sdl_sendMobileHMIState]; - }); -} + __block UIApplicationState appState = UIApplicationStateInactive; + if ([NSThread isMainThread]) { + appState = [UIApplication sharedApplication].applicationState; + } else { + dispatch_sync(dispatch_get_main_queue(), ^{ + appState = [UIApplication sharedApplication].applicationState; + }); + } -- (void)sdl_sendMobileHMIState { - UIApplicationState appState = [UIApplication sharedApplication].applicationState; SDLOnHMIStatus *HMIStatusRPC = [[SDLOnHMIStatus alloc] init]; HMIStatusRPC.audioStreamingState = SDLAudioStreamingStateNotAudible; @@ -898,15 +898,13 @@ static float DefaultConnectionTimeout = 45.0; } - (void)invokeMethodOnDelegates:(SEL)aSelector withObject:(nullable id)object { - // Occurs on the protocol receive serial queue - dispatch_async(_rpcProcessingQueue, ^{ - for (id<SDLProxyListener> listener in self.proxyListeners) { - if ([listener respondsToSelector:aSelector]) { - // HAX: http://stackoverflow.com/questions/7017281/performselector-may-cause-a-leak-because-its-selector-is-unknown - ((void (*)(id, SEL, id))[(NSObject *)listener methodForSelector:aSelector])(listener, aSelector, object); - } + // Occurs on the processing serial queue + for (id<SDLProxyListener> listener in self.proxyListeners) { + if ([listener respondsToSelector:aSelector]) { + // HAX: http://stackoverflow.com/questions/7017281/performselector-may-cause-a-leak-because-its-selector-is-unknown + ((void (*)(id, SEL, id))[(NSObject *)listener methodForSelector:aSelector])(listener, aSelector, object); } - }); + } } diff --git a/SmartDeviceLink/SDLRPCRequest.m b/SmartDeviceLink/SDLRPCRequest.m index 1ce2186c1..445bace56 100644 --- a/SmartDeviceLink/SDLRPCRequest.m +++ b/SmartDeviceLink/SDLRPCRequest.m @@ -26,6 +26,10 @@ NS_ASSUME_NONNULL_BEGIN [self.function sdl_setObject:corrID forName:SDLRPCParameterNameCorrelationId]; } +- (NSString *)description { + return [NSString stringWithFormat:@"%@ (%@), id: %@\n%@", self.name, self.messageType, self.correlationID, self.parameters]; +} + @end NS_ASSUME_NONNULL_END diff --git a/SmartDeviceLink/SDLRPCResponse.m b/SmartDeviceLink/SDLRPCResponse.m index c996473e9..c0ad88b74 100644 --- a/SmartDeviceLink/SDLRPCResponse.m +++ b/SmartDeviceLink/SDLRPCResponse.m @@ -44,8 +44,13 @@ NS_ASSUME_NONNULL_BEGIN return self; } + #pragma clang diagnostic pop +- (NSString *)description { + return [NSString stringWithFormat:@"%@ (%@), id: %@\n%@", self.name, self.messageType, self.correlationID, self.parameters]; +} + - (NSNumber<SDLInt> *)correlationID { NSError *error = nil; return [self.function sdl_objectForName:SDLRPCParameterNameCorrelationId ofClass:NSNumber.class error:&error]; diff --git a/SmartDeviceLink/SDLResponseDispatcher.m b/SmartDeviceLink/SDLResponseDispatcher.m index 6851a1575..4ac79c8bf 100644 --- a/SmartDeviceLink/SDLResponseDispatcher.m +++ b/SmartDeviceLink/SDLResponseDispatcher.m @@ -132,8 +132,12 @@ NS_ASSUME_NONNULL_BEGIN // When we get disconnected we have to delete all existing responseHandlers as they are not valid anymore for (SDLRPCCorrelationId *correlationID in self.rpcResponseHandlerMap.dictionaryRepresentation) { SDLResponseHandler responseHandler = self.rpcResponseHandlerMap[correlationID]; - responseHandler(self.rpcRequestDictionary[correlationID], nil, [NSError sdl_lifecycle_notConnectedError]); + + if (responseHandler != NULL) { + responseHandler(self.rpcRequestDictionary[correlationID], nil, [NSError sdl_lifecycle_notConnectedError]); + } } + [self.rpcRequestDictionary removeAllObjects]; [self.rpcResponseHandlerMap removeAllObjects]; [self.commandHandlerMap removeAllObjects]; diff --git a/SmartDeviceLink/SDLTouch.m b/SmartDeviceLink/SDLTouch.m index e4007471f..d9fa83c7a 100644 --- a/SmartDeviceLink/SDLTouch.m +++ b/SmartDeviceLink/SDLTouch.m @@ -58,6 +58,10 @@ NS_ASSUME_NONNULL_BEGIN return self.identifier == SDLTouchIdentifierSecondFinger; } +- (NSString *)description { + return [NSString stringWithFormat:@"SDLTouch: ID: %ld, Location: %@, Timestamp: %lu, firstFinger? %@, secondFinger? %@", (long)_identifier, NSStringFromCGPoint(_location), (unsigned long)_timeStamp, (self.isFirstFinger ? @"YES" : @"NO"), (self.isSecondFinger ? @"YES" : @"NO")]; +} + @end NS_ASSUME_NONNULL_END diff --git a/SmartDeviceLink/SDLTouchManager.m b/SmartDeviceLink/SDLTouchManager.m index 9a66d81e4..1f4f4adea 100644 --- a/SmartDeviceLink/SDLTouchManager.m +++ b/SmartDeviceLink/SDLTouchManager.m @@ -9,8 +9,8 @@ #import "SDLTouchManager.h" #import "CGPoint_Util.h" -#import "dispatch_timer.h" +#import "SDLGlobals.h" #import "SDLFocusableItemHitTester.h" #import "SDLLogMacros.h" #import "SDLNotificationConstants.h" @@ -75,7 +75,7 @@ static NSUInteger const MaximumNumberOfTouches = 2; * @abstract * Timer used for distinguishing between single & double taps. */ -@property (nonatomic, strong, nullable) dispatch_source_t singleTapTimer; +@property (nonatomic, strong, nullable) NSTimer *singleTapTimer; /*! * @abstract @@ -131,39 +131,43 @@ static NSUInteger const MaximumNumberOfTouches = 2; return; } - dispatch_async(dispatch_get_main_queue(), ^{ - if (self.performingTouchType == SDLPerformingTouchTypePanningTouch) { - CGPoint storedTouchLocation = self.lastStoredTouchLocation; - CGPoint notifiedTouchLocation = self.lastNotifiedTouchLocation; + if (self.performingTouchType == SDLPerformingTouchTypePanningTouch) { + CGPoint storedTouchLocation = self.lastStoredTouchLocation; + CGPoint notifiedTouchLocation = self.lastNotifiedTouchLocation; - if (CGPointEqualToPoint(storedTouchLocation, CGPointZero) || - CGPointEqualToPoint(notifiedTouchLocation, CGPointZero) || - CGPointEqualToPoint(storedTouchLocation, notifiedTouchLocation)) { - return; - } + if (CGPointEqualToPoint(storedTouchLocation, CGPointZero) || + CGPointEqualToPoint(notifiedTouchLocation, CGPointZero) || + CGPointEqualToPoint(storedTouchLocation, notifiedTouchLocation)) { + return; + } - if ([self.touchEventDelegate respondsToSelector:@selector(touchManager:didReceivePanningFromPoint:toPoint:)]) { + if ([self.touchEventDelegate respondsToSelector:@selector(touchManager:didReceivePanningFromPoint:toPoint:)]) { + dispatch_async(dispatch_get_main_queue(), ^{ [self.touchEventDelegate touchManager:self didReceivePanningFromPoint:notifiedTouchLocation toPoint:storedTouchLocation]; self.lastNotifiedTouchLocation = storedTouchLocation; - } - } else if (self.performingTouchType == SDLPerformingTouchTypeMultiTouch) { - if (self.previousPinchDistance == self.currentPinchGesture.distance) { - return; - } + }); + } + } else if (self.performingTouchType == SDLPerformingTouchTypeMultiTouch) { + if (self.previousPinchDistance == self.currentPinchGesture.distance) { + return; + } - if ([self.touchEventDelegate respondsToSelector:@selector(touchManager:didReceivePinchAtCenterPoint:withScale:)]) { - CGFloat scale = self.currentPinchGesture.distance / self.previousPinchDistance; + if ([self.touchEventDelegate respondsToSelector:@selector(touchManager:didReceivePinchAtCenterPoint:withScale:)]) { + + CGFloat scale = self.currentPinchGesture.distance / self.previousPinchDistance; + CGPoint center = self.currentPinchGesture.center; + dispatch_async(dispatch_get_main_queue(), ^{ [self.touchEventDelegate touchManager:self - didReceivePinchAtCenterPoint:self.currentPinchGesture.center + didReceivePinchAtCenterPoint:center withScale:scale]; - } - - self.previousPinchDistance = self.currentPinchGesture.distance; + }); } - }); + + self.previousPinchDistance = self.currentPinchGesture.distance; + } } #pragma mark - SDLDidReceiveTouchEventNotification @@ -186,25 +190,25 @@ static NSUInteger const MaximumNumberOfTouches = 2; [onTouchEvent.event enumerateObjectsUsingBlock:^(SDLTouchEvent *touchEvent, NSUInteger idx, BOOL *stop) { SDLTouch *touch = [[SDLTouch alloc] initWithTouchEvent:touchEvent]; - if (self.touchEventHandler) { - self.touchEventHandler(touch, touchType); + if (self.touchEventHandler != NULL) { + dispatch_async(dispatch_get_main_queue(), ^{ + self.touchEventHandler(touch, touchType); + }); } if (!self.touchEventDelegate || (touch.identifier > MaximumNumberOfTouches)) { return; } - dispatch_async(dispatch_get_main_queue(), ^{ - if ([onTouchEvent.type isEqualToEnum:SDLTouchTypeBegin]) { - [self sdl_handleTouchBegan:touch]; - } else if ([onTouchEvent.type isEqualToEnum:SDLTouchTypeMove]) { - [self sdl_handleTouchMoved:touch]; - } else if ([onTouchEvent.type isEqualToEnum:SDLTouchTypeEnd]) { - [self sdl_handleTouchEnded:touch]; - } else if ([onTouchEvent.type isEqualToEnum:SDLTouchTypeCancel]) { - [self sdl_handleTouchCanceled:touch]; - } - }); + if ([onTouchEvent.type isEqualToEnum:SDLTouchTypeBegin]) { + [self sdl_handleTouchBegan:touch]; + } else if ([onTouchEvent.type isEqualToEnum:SDLTouchTypeMove]) { + [self sdl_handleTouchMoved:touch]; + } else if ([onTouchEvent.type isEqualToEnum:SDLTouchTypeEnd]) { + [self sdl_handleTouchEnded:touch]; + } else if ([onTouchEvent.type isEqualToEnum:SDLTouchTypeCancel]) { + [self sdl_handleTouchCanceled:touch]; + } }]; } @@ -227,8 +231,11 @@ static NSUInteger const MaximumNumberOfTouches = 2; self.currentPinchGesture = [[SDLPinchGesture alloc] initWithFirstTouch:self.previousTouch secondTouch:touch]; self.previousPinchDistance = self.currentPinchGesture.distance; if ([self.touchEventDelegate respondsToSelector:@selector(touchManager:pinchDidStartInView:atCenterPoint:)]) { - UIView *hitView = (self.hitTester != nil) ? [self.hitTester viewForPoint:self.currentPinchGesture.center] : nil; - [self.touchEventDelegate touchManager:self pinchDidStartInView:hitView atCenterPoint:self.currentPinchGesture.center]; + CGPoint center = self.currentPinchGesture.center; + dispatch_async(dispatch_get_main_queue(), ^{ + UIView *hitView = (self.hitTester != nil) ? [self.hitTester viewForPoint:center] : nil; + [self.touchEventDelegate touchManager:self pinchDidStartInView:hitView atCenterPoint:center]; + }); } } break; } @@ -275,8 +282,10 @@ static NSUInteger const MaximumNumberOfTouches = 2; _performingTouchType = SDLPerformingTouchTypePanningTouch; if ([self.touchEventDelegate respondsToSelector:@selector(touchManager:panningDidStartInView:atPoint:)]) { - UIView *hitView = (self.hitTester != nil) ? [self.hitTester viewForPoint:touch.location] : nil; - [self.touchEventDelegate touchManager:self panningDidStartInView:hitView atPoint:touch.location]; + dispatch_async(dispatch_get_main_queue(), ^{ + UIView *hitView = (self.hitTester != nil) ? [self.hitTester viewForPoint:touch.location] : nil; + [self.touchEventDelegate touchManager:self panningDidStartInView:hitView atPoint:touch.location]; + }); } } break; case SDLPerformingTouchTypePanningTouch: { @@ -302,9 +311,11 @@ static NSUInteger const MaximumNumberOfTouches = 2; [self sdl_setMultiTouchFingerTouchForTouch:touch]; if (self.currentPinchGesture.isValid) { if ([self.touchEventDelegate respondsToSelector:@selector(touchManager:pinchDidEndInView:atCenterPoint:)]) { - UIView *hitView = (self.hitTester != nil) ? [self.hitTester viewForPoint:self.currentPinchGesture.center] : nil; - [self.touchEventDelegate touchManager:self pinchDidEndInView:hitView atCenterPoint:self.currentPinchGesture.center]; - self.currentPinchGesture = nil; + dispatch_async(dispatch_get_main_queue(), ^{ + UIView *hitView = (self.hitTester != nil) ? [self.hitTester viewForPoint:self.currentPinchGesture.center] : nil; + [self.touchEventDelegate touchManager:self pinchDidEndInView:hitView atCenterPoint:self.currentPinchGesture.center]; + self.currentPinchGesture = nil; + }); } else { self.currentPinchGesture = nil; } @@ -312,8 +323,10 @@ static NSUInteger const MaximumNumberOfTouches = 2; } break; case SDLPerformingTouchTypePanningTouch: { if ([self.touchEventDelegate respondsToSelector:@selector(touchManager:panningDidEndInView:atPoint:)]) { - UIView *hitView = (self.hitTester != nil) ? [self.hitTester viewForPoint:touch.location] : nil; - [self.touchEventDelegate touchManager:self panningDidEndInView:hitView atPoint:touch.location]; + dispatch_async(dispatch_get_main_queue(), ^{ + UIView *hitView = (self.hitTester != nil) ? [self.hitTester viewForPoint:touch.location] : nil; + [self.touchEventDelegate touchManager:self panningDidEndInView:hitView atPoint:touch.location]; + }); } } break; case SDLPerformingTouchTypeSingleTouch: { @@ -333,8 +346,10 @@ static NSUInteger const MaximumNumberOfTouches = 2; CGPoint centerPoint = CGPointCenterOfPoints(touch.location, self.singleTapTouch.location); if ([self.touchEventDelegate respondsToSelector:@selector(touchManager:didReceiveDoubleTapForView:atPoint:)]) { - UIView *hitView = (self.hitTester != nil) ? [self.hitTester viewForPoint:centerPoint] : nil; - [self.touchEventDelegate touchManager:self didReceiveDoubleTapForView:hitView atPoint:centerPoint]; + dispatch_async(dispatch_get_main_queue(), ^{ + UIView *hitView = (self.hitTester != nil) ? [self.hitTester viewForPoint:centerPoint] : nil; + [self.touchEventDelegate touchManager:self didReceiveDoubleTapForView:hitView atPoint:centerPoint]; + }); } } @@ -368,16 +383,21 @@ static NSUInteger const MaximumNumberOfTouches = 2; [self sdl_setMultiTouchFingerTouchForTouch:touch]; if (self.currentPinchGesture.isValid) { if ([self.touchEventDelegate respondsToSelector:@selector(touchManager:pinchCanceledAtCenterPoint:)]) { - [self.touchEventDelegate touchManager:self - pinchCanceledAtCenterPoint:self.currentPinchGesture.center]; + CGPoint center = self.currentPinchGesture.center; + dispatch_async(dispatch_get_main_queue(), ^{ + [self.touchEventDelegate touchManager:self + pinchCanceledAtCenterPoint:center]; + }); } self.currentPinchGesture = nil; } } break; case SDLPerformingTouchTypePanningTouch: { if ([self.touchEventDelegate respondsToSelector:@selector(touchManager:panningCanceledAtPoint:)]) { - [self.touchEventDelegate touchManager:self - panningCanceledAtPoint:touch.location]; + dispatch_async(dispatch_get_main_queue(), ^{ + [self.touchEventDelegate touchManager:self + panningCanceledAtPoint:touch.location]; + }); } } break; case SDLPerformingTouchTypeSingleTouch: // fallthrough @@ -413,18 +433,32 @@ static NSUInteger const MaximumNumberOfTouches = 2; * @param point Screen coordinates of the tap gesture */ - (void)sdl_initializeSingleTapTimerAtPoint:(CGPoint)point { - __weak typeof(self) weakSelf = self; - self.singleTapTimer = dispatch_create_timer(self.tapTimeThreshold, NO, ^{ - // If timer was not canceled by a second tap then only one tap detected - typeof(weakSelf) strongSelf = weakSelf; - strongSelf.singleTapTouch = nil; - [strongSelf sdl_cancelSingleTapTimer]; - if ([strongSelf.touchEventDelegate respondsToSelector:@selector(touchManager:didReceiveSingleTapForView:atPoint:)]) { + if (self.singleTapTimer != nil) { + [self sdl_cancelSingleTapTimer]; + } + + self.singleTapTimer = [NSTimer timerWithTimeInterval:self.tapTimeThreshold target:self selector:@selector(sdl_singleTapTimerCallback:) userInfo:@{@"point": [NSValue valueWithCGPoint:point]} repeats:NO]; + [[NSRunLoop mainRunLoop] addTimer:self.singleTapTimer forMode:NSRunLoopCommonModes]; +} + +/** + The method that will be called when the timer fires that was started in `sdl_initializeSingleTapTimerAtPoint:`. + + This is called on the main thread based on `sdl_initializeSingleTapTimerAtPoint:` + + @param timer The timer that was fired + */ +- (void)sdl_singleTapTimerCallback:(NSTimer *)timer { + CGPoint point = ((NSValue *)timer.userInfo[@"point"]).CGPointValue; + self.singleTapTouch = nil; + [self sdl_cancelSingleTapTimer]; + if ([self.touchEventDelegate respondsToSelector:@selector(touchManager:didReceiveSingleTapForView:atPoint:)]) { + dispatch_async(dispatch_get_main_queue(), ^{ [self sdl_getSingleTapHitView:point hitViewHandler:^(UIView * _Nullable selectedView) { - [strongSelf.touchEventDelegate touchManager:strongSelf didReceiveSingleTapForView:selectedView atPoint:point]; + [self.touchEventDelegate touchManager:self didReceiveSingleTapForView:selectedView atPoint:point]; }]; - } - }); + }); + } } /** @@ -441,24 +475,22 @@ static NSUInteger const MaximumNumberOfTouches = 2; return hitViewHandler(nil); } - dispatch_async(dispatch_get_main_queue(), ^{ - UIView *hitView = [self.hitTester viewForPoint:point]; - dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ - if (!hitViewHandler) { return; } - return hitViewHandler(hitView); - }); - }); + UIView *hitView = [self.hitTester viewForPoint:point]; + if (!hitViewHandler) { return; } + + return hitViewHandler(hitView); } /** * Cancels a tap gesture timer */ - (void)sdl_cancelSingleTapTimer { - if (self.singleTapTimer == NULL) { + if (self.singleTapTimer == nil) { return; } - dispatch_stop_timer(self.singleTapTimer); - self.singleTapTimer = NULL; + + [self.singleTapTimer invalidate]; + self.singleTapTimer = nil; } @end diff --git a/SmartDeviceLink/SDLUploadFileOperation.h b/SmartDeviceLink/SDLUploadFileOperation.h index 40c4b36c4..cd3eaa4af 100644 --- a/SmartDeviceLink/SDLUploadFileOperation.h +++ b/SmartDeviceLink/SDLUploadFileOperation.h @@ -31,6 +31,8 @@ NS_ASSUME_NONNULL_BEGIN */ - (instancetype)initWithFile:(SDLFileWrapper *)file connectionManager:(id<SDLConnectionManagerType>)connectionManager; +@property (nonatomic, strong, readonly) SDLFileWrapper *fileWrapper; + @end NS_ASSUME_NONNULL_END diff --git a/SmartDeviceLink/SDLUploadFileOperation.m b/SmartDeviceLink/SDLUploadFileOperation.m index 620d0f833..f9edfe2f5 100644 --- a/SmartDeviceLink/SDLUploadFileOperation.m +++ b/SmartDeviceLink/SDLUploadFileOperation.m @@ -24,7 +24,7 @@ NS_ASSUME_NONNULL_BEGIN @interface SDLUploadFileOperation () -@property (strong, nonatomic) SDLFileWrapper *fileWrapper; +@property (strong, nonatomic, readwrite) SDLFileWrapper *fileWrapper; @property (weak, nonatomic) id<SDLConnectionManagerType> connectionManager; @property (strong, nonatomic) NSInputStream *inputStream; @@ -70,21 +70,25 @@ NS_ASSUME_NONNULL_BEGIN __block NSInteger highestCorrelationIDReceived = -1; if (self.isCancelled) { + completion(NO, bytesAvailable, [NSError sdl_fileManager_fileUploadCanceled]); [self finishOperation]; - return completion(NO, bytesAvailable, [NSError sdl_fileManager_fileUploadCanceled]); + return; } if (file == nil) { + completion(NO, bytesAvailable, [NSError sdl_fileManager_fileDoesNotExistError]); [self finishOperation]; - return completion(NO, bytesAvailable, [NSError sdl_fileManager_fileDoesNotExistError]); + return; } self.inputStream = [self sdl_openInputStreamWithFile:file]; if (self.inputStream == nil || ![self.inputStream hasBytesAvailable]) { // If the file does not exist or the passed data is nil, return an error [self sdl_closeInputStream]; + + completion(NO, bytesAvailable, [NSError sdl_fileManager_fileDoesNotExistError]); [self finishOperation]; - return completion(NO, bytesAvailable, [NSError sdl_fileManager_fileDoesNotExistError]); + return; } dispatch_group_t putFileGroup = dispatch_group_create(); @@ -92,7 +96,7 @@ NS_ASSUME_NONNULL_BEGIN // Wait for all packets be sent before returning whether or not the upload was a success __weak typeof(self) weakself = self; - dispatch_group_notify(putFileGroup, dispatch_get_main_queue(), ^{ + dispatch_group_notify(putFileGroup, [SDLGlobals sharedGlobals].sdlProcessingQueue, ^{ typeof(weakself) strongself = weakself; [weakself sdl_closeInputStream]; @@ -101,6 +105,7 @@ NS_ASSUME_NONNULL_BEGIN } else { completion(YES, bytesAvailable, nil); } + [weakself finishOperation]; }); @@ -259,7 +264,7 @@ NS_ASSUME_NONNULL_BEGIN #pragma mark - Property Overrides - (nullable NSString *)name { - return self.fileWrapper.file.name; + return [NSString stringWithFormat:@"%@ - %@", self.class, self.fileWrapper.file.name]; } - (NSOperationQueuePriority)queuePriority { diff --git a/SmartDeviceLink/dispatch_timer.h b/SmartDeviceLink/dispatch_timer.h deleted file mode 100644 index 1dd8bb9f2..000000000 --- a/SmartDeviceLink/dispatch_timer.h +++ /dev/null @@ -1,18 +0,0 @@ -// -// dispatch_timer.h -// MobileNav -// -// Created by Muller, Alexander (A.) on 5/12/16. -// Copyright © 2016 Alex Muller. All rights reserved. -// - -#ifndef dispatch_timer_h -#define dispatch_timer_h - -#include <dispatch/dispatch.h> -#include <stdio.h> - -dispatch_source_t dispatch_create_timer(double afterInterval, bool repeating, dispatch_block_t block); -void dispatch_stop_timer(dispatch_source_t timer); - -#endif /* dispatch_timer_h */ diff --git a/SmartDeviceLink/dispatch_timer.m b/SmartDeviceLink/dispatch_timer.m deleted file mode 100644 index 445095eb6..000000000 --- a/SmartDeviceLink/dispatch_timer.m +++ /dev/null @@ -1,38 +0,0 @@ -// -// dispatch_timer.c -// MobileNav -// -// Created by Muller, Alexander (A.) on 5/12/16. -// Copyright © 2016 Alex Muller. All rights reserved. -// - -#include "dispatch_timer.h" - -dispatch_source_t dispatch_create_timer(double afterInterval, bool repeating, dispatch_block_t block) { - dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, - 0); - dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, - 0, - 0, - queue); - dispatch_source_set_timer(timer, - dispatch_time(DISPATCH_TIME_NOW, (int64_t)(afterInterval * NSEC_PER_SEC)), - (uint64_t)(afterInterval * NSEC_PER_SEC), - (1ull * NSEC_PER_SEC) / 10); - dispatch_source_set_event_handler(timer, ^{ - if (!repeating) { - dispatch_stop_timer(timer); - } - if (block) { - block(); - } - }); - dispatch_resume(timer); - - return timer; -} - -void dispatch_stop_timer(dispatch_source_t timer) { - dispatch_source_set_event_handler(timer, NULL); - dispatch_source_cancel(timer); -} |
