Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1283)

Side by Side Diff: webrtc/modules/audio_device/ios/objc/RTCAudioSession.mm

Issue 1796983004: Use RTCAudioSessionDelegate in AudioDeviceIOS. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Some nits. Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright 2016 The WebRTC Project Authors. All rights reserved. 2 * Copyright 2016 The WebRTC Project Authors. All rights reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source 5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
11 #import "webrtc/modules/audio_device/ios/objc/RTCAudioSession.h" 11 #import "webrtc/modules/audio_device/ios/objc/RTCAudioSession.h"
12 12
13 #include "webrtc/base/checks.h" 13 #include "webrtc/base/checks.h"
14 #include "webrtc/base/criticalsection.h" 14 #include "webrtc/base/criticalsection.h"
15 #include "webrtc/modules/audio_device/ios/audio_device_ios.h"
15 16
16 #import "webrtc/base/objc/RTCLogging.h" 17 #import "webrtc/base/objc/RTCLogging.h"
17 #import "webrtc/modules/audio_device/ios/objc/RTCAudioSession+Private.h" 18 #import "webrtc/modules/audio_device/ios/objc/RTCAudioSession+Private.h"
18 19
19 NSString * const kRTCAudioSessionErrorDomain = @"org.webrtc.RTCAudioSession"; 20 NSString * const kRTCAudioSessionErrorDomain = @"org.webrtc.RTCAudioSession";
20 NSInteger const kRTCAudioSessionErrorLockRequired = -1; 21 NSInteger const kRTCAudioSessionErrorLockRequired = -1;
21 NSInteger const kRTCAudioSessionErrorConfiguration = -2; 22 NSInteger const kRTCAudioSessionErrorConfiguration = -2;
22 23
23 // This class needs to be thread-safe because it is accessed from many threads. 24 // This class needs to be thread-safe because it is accessed from many threads.
24 // TODO(tkchin): Consider more granular locking. We're not expecting a lot of 25 // TODO(tkchin): Consider more granular locking. We're not expecting a lot of
25 // lock contention so coarse locks should be fine for now. 26 // lock contention so coarse locks should be fine for now.
26 @implementation RTCAudioSession { 27 @implementation RTCAudioSession {
27 rtc::CriticalSection _crit; 28 rtc::CriticalSection _crit;
28 AVAudioSession *_session; 29 AVAudioSession *_session;
29 NSHashTable *_delegates;
30 NSInteger _activationCount; 30 NSInteger _activationCount;
31 NSInteger _lockRecursionCount; 31 NSInteger _lockRecursionCount;
32 BOOL _isActive; 32 BOOL _isActive;
33 BOOL _shouldDelayAudioConfiguration; 33 BOOL _shouldDelayAudioConfiguration;
34 } 34 }
35 35
36 @synthesize session = _session; 36 @synthesize session = _session;
37 @synthesize delegates = _delegates;
37 38
38 + (instancetype)sharedInstance { 39 + (instancetype)sharedInstance {
39 static dispatch_once_t onceToken; 40 static dispatch_once_t onceToken;
40 static RTCAudioSession *sharedInstance = nil; 41 static RTCAudioSession *sharedInstance = nil;
41 dispatch_once(&onceToken, ^{ 42 dispatch_once(&onceToken, ^{
42 sharedInstance = [[RTCAudioSession alloc] init]; 43 sharedInstance = [[RTCAudioSession alloc] init];
43 }); 44 });
44 return sharedInstance; 45 return sharedInstance;
45 } 46 }
46 47
47 - (instancetype)init { 48 - (instancetype)init {
48 if (self = [super init]) { 49 if (self = [super init]) {
49 _session = [AVAudioSession sharedInstance]; 50 _session = [AVAudioSession sharedInstance];
50 _delegates = [NSHashTable weakObjectsHashTable];
51 51
52 NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; 52 NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
53 [center addObserver:self 53 [center addObserver:self
54 selector:@selector(handleInterruptionNotification:) 54 selector:@selector(handleInterruptionNotification:)
55 name:AVAudioSessionInterruptionNotification 55 name:AVAudioSessionInterruptionNotification
56 object:nil]; 56 object:nil];
57 [center addObserver:self 57 [center addObserver:self
58 selector:@selector(handleRouteChangeNotification:) 58 selector:@selector(handleRouteChangeNotification:)
59 name:AVAudioSessionRouteChangeNotification 59 name:AVAudioSessionRouteChangeNotification
60 object:nil]; 60 object:nil];
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
102 } 102 }
103 } 103 }
104 104
105 - (BOOL)shouldDelayAudioConfiguration { 105 - (BOOL)shouldDelayAudioConfiguration {
106 @synchronized(self) { 106 @synchronized(self) {
107 return _shouldDelayAudioConfiguration; 107 return _shouldDelayAudioConfiguration;
108 } 108 }
109 } 109 }
110 110
111 - (void)addDelegate:(id<RTCAudioSessionDelegate>)delegate { 111 - (void)addDelegate:(id<RTCAudioSessionDelegate>)delegate {
112 if (!delegate) {
113 return;
114 }
112 @synchronized(self) { 115 @synchronized(self) {
113 [_delegates addObject:delegate]; 116 _delegates.push_back(delegate);
117 [self removeZeroedDelegates];
114 } 118 }
115 } 119 }
116 120
117 - (void)removeDelegate:(id<RTCAudioSessionDelegate>)delegate { 121 - (void)removeDelegate:(id<RTCAudioSessionDelegate>)delegate {
122 if (!delegate) {
123 return;
124 }
118 @synchronized(self) { 125 @synchronized(self) {
119 [_delegates removeObject:delegate]; 126 _delegates.erase(std::remove(_delegates.begin(),
127 _delegates.end(),
128 delegate));
129 [self removeZeroedDelegates];
120 } 130 }
121 } 131 }
122 132
123 - (void)lockForConfiguration { 133 - (void)lockForConfiguration {
124 _crit.Enter(); 134 _crit.Enter();
125 @synchronized(self) { 135 @synchronized(self) {
126 ++_lockRecursionCount; 136 ++_lockRecursionCount;
127 } 137 }
128 } 138 }
129 139
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
220 } 230 }
221 231
222 - (NSTimeInterval)outputLatency { 232 - (NSTimeInterval)outputLatency {
223 return self.session.outputLatency; 233 return self.session.outputLatency;
224 } 234 }
225 235
226 - (NSTimeInterval)IOBufferDuration { 236 - (NSTimeInterval)IOBufferDuration {
227 return self.session.IOBufferDuration; 237 return self.session.IOBufferDuration;
228 } 238 }
229 239
240 // TODO(tkchin): Simplify the amount of locking happening here. Likely that we
241 // can just do atomic increments / decrements.
230 - (BOOL)setActive:(BOOL)active 242 - (BOOL)setActive:(BOOL)active
231 error:(NSError **)outError { 243 error:(NSError **)outError {
232 if (![self checkLock:outError]) { 244 if (![self checkLock:outError]) {
233 return NO; 245 return NO;
234 } 246 }
235 NSInteger activationCount = self.activationCount; 247 NSInteger activationCount = self.activationCount;
236 if (!active && activationCount == 0) { 248 if (!active && activationCount == 0) {
237 RTCLogWarning(@"Attempting to deactivate without prior activation."); 249 RTCLogWarning(@"Attempting to deactivate without prior activation.");
238 } 250 }
239 BOOL success = YES; 251 BOOL success = YES;
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after
452 NSLocalizedDescriptionKey: 464 NSLocalizedDescriptionKey:
453 @"Must call lockForConfiguration before calling this method." 465 @"Must call lockForConfiguration before calling this method."
454 }; 466 };
455 NSError *error = 467 NSError *error =
456 [[NSError alloc] initWithDomain:kRTCAudioSessionErrorDomain 468 [[NSError alloc] initWithDomain:kRTCAudioSessionErrorDomain
457 code:kRTCAudioSessionErrorLockRequired 469 code:kRTCAudioSessionErrorLockRequired
458 userInfo:userInfo]; 470 userInfo:userInfo];
459 return error; 471 return error;
460 } 472 }
461 473
462 - (NSSet *)delegates { 474 - (std::vector<__weak id<RTCAudioSessionDelegate> >)delegates {
463 @synchronized(self) { 475 @synchronized(self) {
464 return _delegates.setRepresentation; 476 // Note: this returns a copy.
477 return _delegates;
465 } 478 }
466 } 479 }
467 480
481 - (void)pushDelegate:(id<RTCAudioSessionDelegate>)delegate {
482 @synchronized(self) {
483 _delegates.insert(_delegates.begin(), delegate);
484 }
485 }
486
487 - (void)removeZeroedDelegates {
488 @synchronized(self) {
489 for (auto it = _delegates.begin(); it != _delegates.end(); ++it) {
490 if (!*it) {
491 _delegates.erase(it);
492 }
493 }
494 }
495 }
496
468 - (NSInteger)activationCount { 497 - (NSInteger)activationCount {
469 @synchronized(self) { 498 @synchronized(self) {
470 return _activationCount; 499 return _activationCount;
471 } 500 }
472 } 501 }
473 502
474 - (NSInteger)incrementActivationCount { 503 - (NSInteger)incrementActivationCount {
475 RTCLog(@"Incrementing activation count."); 504 RTCLog(@"Incrementing activation count.");
476 @synchronized(self) { 505 @synchronized(self) {
477 return ++_activationCount; 506 return ++_activationCount;
(...skipping 28 matching lines...) Expand all
506 withOptions:options 535 withOptions:options
507 error:&error]) { 536 error:&error]) {
508 self.isActive = shouldActivate; 537 self.isActive = shouldActivate;
509 } else { 538 } else {
510 RTCLogError(@"Failed to set session active to %d. Error:%@", 539 RTCLogError(@"Failed to set session active to %d. Error:%@",
511 shouldActivate, error.localizedDescription); 540 shouldActivate, error.localizedDescription);
512 } 541 }
513 } 542 }
514 543
515 - (void)notifyDidBeginInterruption { 544 - (void)notifyDidBeginInterruption {
516 for (id<RTCAudioSessionDelegate> delegate in self.delegates) { 545 for (auto delegate : self.delegates) {
517 [delegate audioSessionDidBeginInterruption:self]; 546 [delegate audioSessionDidBeginInterruption:self];
518 } 547 }
519 } 548 }
520 549
521 - (void)notifyDidEndInterruptionWithShouldResumeSession: 550 - (void)notifyDidEndInterruptionWithShouldResumeSession:
522 (BOOL)shouldResumeSession { 551 (BOOL)shouldResumeSession {
523 for (id<RTCAudioSessionDelegate> delegate in self.delegates) { 552 for (auto delegate : self.delegates) {
524 [delegate audioSessionDidEndInterruption:self 553 [delegate audioSessionDidEndInterruption:self
525 shouldResumeSession:shouldResumeSession]; 554 shouldResumeSession:shouldResumeSession];
526 } 555 }
527 556
528 } 557 }
529 558
530 - (void)notifyDidChangeRouteWithReason:(AVAudioSessionRouteChangeReason)reason 559 - (void)notifyDidChangeRouteWithReason:(AVAudioSessionRouteChangeReason)reason
531 previousRoute:(AVAudioSessionRouteDescription *)previousRoute { 560 previousRoute:(AVAudioSessionRouteDescription *)previousRoute {
532 for (id<RTCAudioSessionDelegate> delegate in self.delegates) { 561 for (auto delegate : self.delegates) {
533 [delegate audioSessionDidChangeRoute:self 562 [delegate audioSessionDidChangeRoute:self
534 reason:reason 563 reason:reason
535 previousRoute:previousRoute]; 564 previousRoute:previousRoute];
536 } 565 }
537 } 566 }
538 567
539 - (void)notifyMediaServicesWereLost { 568 - (void)notifyMediaServicesWereLost {
540 for (id<RTCAudioSessionDelegate> delegate in self.delegates) { 569 for (auto delegate : self.delegates) {
541 [delegate audioSessionMediaServicesWereLost:self]; 570 [delegate audioSessionMediaServicesWereLost:self];
542 } 571 }
543 } 572 }
544 573
545 - (void)notifyMediaServicesWereReset { 574 - (void)notifyMediaServicesWereReset {
546 for (id<RTCAudioSessionDelegate> delegate in self.delegates) { 575 for (auto delegate : self.delegates) {
547 [delegate audioSessionMediaServicesWereReset:self]; 576 [delegate audioSessionMediaServicesWereReset:self];
548 } 577 }
549 } 578 }
550 579
551 @end 580 @end
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698