diff options
author | mcasas@chromium.org <mcasas@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-03-07 17:24:15 +0000 |
---|---|---|
committer | mcasas@chromium.org <mcasas@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-03-07 17:24:15 +0000 |
commit | b242a522833e4465005c8efc13189f574a85691e (patch) | |
tree | 08a4962258e99811b8bfcc845f53d1723786d429 | |
parent | cbed02ae31011f741d1341472abc0108cf42b148 (diff) | |
download | chromium_src-b242a522833e4465005c8efc13189f574a85691e.zip chromium_src-b242a522833e4465005c8efc13189f574a85691e.tar.gz chromium_src-b242a522833e4465005c8efc13189f574a85691e.tar.bz2 |
Mac AVFoundation device monitor: clean removal of device observers
This CL fixes a crash happening when Chrome shuts down or a capture
device is removed from the system while there are observers observing
the "suspended" property of the AVCaptureDevice going out of scope --
basically leaving the observer observing a zombie.
For that, the CrAVFoundationSuspendObserver registers to observe both
"suspended" and "connected". In the case of "connected" received, it
can only mean disconnected, so both observers are removed. The |device|
pointer is passed to -addObserver:forKeyPath:options:context: as the
|context|, and is received then in the -observeValueForKeyPath:... .
CrAVFoundationSuspendObserver renamed to CrAVFoundationDeviceObserver.
BUG=288562, 348917
Review URL: https://codereview.chromium.org/188383004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@255648 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | content/browser/device_monitor_mac.mm | 22 |
1 files changed, 15 insertions, 7 deletions
diff --git a/content/browser/device_monitor_mac.mm b/content/browser/device_monitor_mac.mm index 34d1916..0e53674 100644 --- a/content/browser/device_monitor_mac.mm +++ b/content/browser/device_monitor_mac.mm @@ -204,14 +204,14 @@ void QTKitMonitorImpl::OnDeviceChanged() { ConsolidateDevicesListAndNotify(snapshot_devices); } -// Forward declaration for use by CrAVFoundationSuspendObserver. +// Forward declaration for use by CrAVFoundationDeviceObserver. class AVFoundationMonitorImpl; } // namespace // This class is a Key-Value Observer (KVO) shim. It is needed because C++ // classes cannot observe Key-Values directly. -@interface CrAVFoundationSuspendObserver : NSObject { +@interface CrAVFoundationDeviceObserver : NSObject { @private AVFoundationMonitorImpl* receiver_; } @@ -232,7 +232,7 @@ class AVFoundationMonitorImpl : public DeviceMonitorMacImpl { virtual void OnDeviceChanged() OVERRIDE; private: - base::scoped_nsobject<CrAVFoundationSuspendObserver> suspend_observer_; + base::scoped_nsobject<CrAVFoundationDeviceObserver> suspend_observer_; DISALLOW_COPY_AND_ASSIGN(AVFoundationMonitorImpl); }; @@ -255,7 +255,7 @@ AVFoundationMonitorImpl::AVFoundationMonitorImpl( usingBlock:^(NSNotification* notification) { OnDeviceChanged();}]; suspend_observer_.reset( - [[CrAVFoundationSuspendObserver alloc] initWithChangeReceiver:this]); + [[CrAVFoundationDeviceObserver alloc] initWithChangeReceiver:this]); for (CrAVCaptureDevice* device in [AVCaptureDeviceGlue devices]) [suspend_observer_ startObserving:device]; } @@ -292,7 +292,7 @@ void AVFoundationMonitorImpl::OnDeviceChanged() { } // namespace -@implementation CrAVFoundationSuspendObserver +@implementation CrAVFoundationDeviceObserver - (id)initWithChangeReceiver:(AVFoundationMonitorImpl*)receiver { if ((self = [super init])) { @@ -307,13 +307,19 @@ void AVFoundationMonitorImpl::OnDeviceChanged() { [device addObserver:self forKeyPath:@"suspended" options:0 - context:nil]; + context:device]; + [device addObserver:self + forKeyPath:@"connected" + options:0 + context:device]; } - (void)stopObserving:(CrAVCaptureDevice*)device { DCHECK(device != nil); [device removeObserver:self forKeyPath:@"suspended"]; + [device removeObserver:self + forKeyPath:@"connected"]; } - (void)observeValueForKeyPath:(NSString*)keyPath @@ -322,9 +328,11 @@ void AVFoundationMonitorImpl::OnDeviceChanged() { context:(void*)context { if ([keyPath isEqual:@"suspended"]) receiver_->OnDeviceChanged(); + if ([keyPath isEqual:@"connected"]) + [self stopObserving:static_cast<CrAVCaptureDevice*>(context)]; } -@end // @implementation CrAVFoundationSuspendObserver +@end // @implementation CrAVFoundationDeviceObserver namespace content { |