Changeset 207704 in webkit


Ignore:
Timestamp:
Oct 21, 2016, 8:35:04 PM (9 years ago)
Author:
eric.carlson@apple.com
Message:

[MediaStream] Dynamically generate media capture sandbox extensions
https://bugs.webkit.org/show_bug.cgi?id=154861
<rdar://problem/24909411>

Reviewed by Tim Horton.

Source/WebCore:

No new tests, some of these changes are covered by existing tests and some can only be tested
with physical capture devices.

  • platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.mm: AVSampleBufferAudioRenderer and AVSampleBufferRenderSynchronizer are now declared in AVFoundationSPI.h.
  • platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.h:
  • platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.mm:

(WebCore::MediaPlayerPrivateMediaStreamAVFObjC::MediaPlayerPrivateMediaStreamAVFObjC): Initialize

AVSampleBufferRenderSynchronizer.

(WebCore::MediaPlayerPrivateMediaStreamAVFObjC::isAvailable): Fail if AVSampleBufferRenderSynchronizer

isn't available.

(WebCore::MediaPlayerPrivateMediaStreamAVFObjC::enqueueAudioSampleBufferFromTrack): Take a MediaSample&

instead of a PlatformSample&.

(WebCore::MediaPlayerPrivateMediaStreamAVFObjC::enqueueVideoSampleBufferFromTrack): Ditto.
(WebCore::MediaPlayerPrivateMediaStreamAVFObjC::ensureLayer): Add the sample buffer display

later to the synchronizer.

(WebCore::MediaPlayerPrivateMediaStreamAVFObjC::destroyLayer): Remove the sample buffer display

later from the synchronizer.

(WebCore::MediaPlayerPrivateMediaStreamAVFObjC::play): Start the synchronizer.
(WebCore::MediaPlayerPrivateMediaStreamAVFObjC::pause): Stash the current clock time in

m_pausedTime, but leave the clock running. Pause the synchronizer.

(WebCore::MediaPlayerPrivateMediaStreamAVFObjC::currentMediaTime): Return the clock time

when playing, m_pausedTime time when paused because we leave the clock running forever.

(WebCore::MediaPlayerPrivateMediaStreamAVFObjC::sampleBufferUpdated):

  • platform/graphics/avfoundation/objc/SourceBufferPrivateAVFObjC.mm: AVSampleBufferAudioRenderer is now declared in AVFoundationSPI.h.
  • platform/spi/mac/AVFoundationSPI.h: Add AVSampleBufferAudioRenderer and AVSampleBufferRenderSynchronizer.

Source/WebKit2:

  • Shared/SandboxExtension.h:

(WebKit::SandboxExtension::createHandleForGenericExtension):

  • Shared/mac/SandboxExtensionMac.mm:

(WebKit::wkSandboxExtensionType): Add case for generic handle.
(WebKit::SandboxExtension::createHandleForGenericExtension): New.

  • UIProcess/UserMediaPermissionRequestManagerProxy.cpp:

(WebKit::UserMediaPermissionRequestManagerProxy::invalidateRequests): Clear the list of extensions granted.
(WebKit::UserMediaPermissionRequestManagerProxy::userMediaAccessWasGranted): Extend the web

process sandbox as necessary.

  • UIProcess/UserMediaPermissionRequestManagerProxy.h:
  • WebProcess/MediaStream/UserMediaPermissionRequestManager.cpp:

(WebKit::UserMediaPermissionRequestManager::~UserMediaPermissionRequestManager): Revoke all

sandbox extensions.

(WebKit::UserMediaPermissionRequestManager::grantUserMediaDevicesSandboxExtension): Consume

sandbox extensions.

  • WebProcess/MediaStream/UserMediaPermissionRequestManager.h:
  • WebProcess/WebPage/WebPage.cpp:

(WebKit::WebPage::grantUserMediaDevicesSandboxExtension): Pass-through to user media manager.

  • WebProcess/WebPage/WebPage.h:
  • WebProcess/WebPage/WebPage.messages.in: Add GrantUserMediaDevicesSandboxExtension.
  • WebProcess/com.apple.WebProcess.sb.in: Add rules, defines, and a macro to allow dynamic extensions for media capture devices.
Location:
trunk/Source
Files:
17 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r207700 r207704  
     12016-10-21  Eric Carlson  <eric.carlson@apple.com>
     2
     3        [MediaStream] Dynamically generate media capture sandbox extensions
     4        https://bugs.webkit.org/show_bug.cgi?id=154861
     5        <rdar://problem/24909411>
     6
     7        Reviewed by Tim Horton.
     8
     9        No new tests, some of these changes are covered by existing tests and some can only be tested
     10        with physical capture devices.
     11
     12        * platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.mm: AVSampleBufferAudioRenderer
     13          and AVSampleBufferRenderSynchronizer are now declared in AVFoundationSPI.h.
     14
     15        * platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.h:
     16        * platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.mm:
     17        (WebCore::MediaPlayerPrivateMediaStreamAVFObjC::MediaPlayerPrivateMediaStreamAVFObjC): Initialize
     18          AVSampleBufferRenderSynchronizer.
     19        (WebCore::MediaPlayerPrivateMediaStreamAVFObjC::isAvailable): Fail if AVSampleBufferRenderSynchronizer
     20          isn't available.
     21        (WebCore::MediaPlayerPrivateMediaStreamAVFObjC::enqueueAudioSampleBufferFromTrack): Take a MediaSample&
     22          instead of a PlatformSample&.
     23        (WebCore::MediaPlayerPrivateMediaStreamAVFObjC::enqueueVideoSampleBufferFromTrack): Ditto.
     24        (WebCore::MediaPlayerPrivateMediaStreamAVFObjC::ensureLayer): Add the sample buffer display
     25          later to the synchronizer.
     26        (WebCore::MediaPlayerPrivateMediaStreamAVFObjC::destroyLayer): Remove the sample buffer display
     27          later from the synchronizer.
     28        (WebCore::MediaPlayerPrivateMediaStreamAVFObjC::play): Start the synchronizer.
     29        (WebCore::MediaPlayerPrivateMediaStreamAVFObjC::pause): Stash the current clock time in
     30          m_pausedTime, but leave the clock running. Pause the synchronizer.
     31        (WebCore::MediaPlayerPrivateMediaStreamAVFObjC::currentMediaTime): Return the clock time
     32          when playing, m_pausedTime time when paused because we leave the clock running forever.
     33        (WebCore::MediaPlayerPrivateMediaStreamAVFObjC::sampleBufferUpdated):
     34
     35        * platform/graphics/avfoundation/objc/SourceBufferPrivateAVFObjC.mm: AVSampleBufferAudioRenderer
     36          is now declared in AVFoundationSPI.h.
     37
     38        * platform/spi/mac/AVFoundationSPI.h: Add AVSampleBufferAudioRenderer and AVSampleBufferRenderSynchronizer.
     39
    1402016-10-21  Commit Queue  <commit-queue@webkit.org>
    241
  • trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.mm

    r207694 r207704  
    9494
    9595#pragma mark -
    96 #pragma mark AVSampleBufferAudioRenderer
    97 
    98 @interface AVSampleBufferAudioRenderer : NSObject
    99 - (void)setVolume:(float)volume;
    100 - (void)setMuted:(BOOL)muted;
    101 @property (nonatomic, copy) NSString *audioTimePitchAlgorithm;
    102 @end
    103 
    104 #pragma mark -
    105 #pragma mark AVSampleBufferRenderSynchronizer
    106 
    107 @interface AVSampleBufferRenderSynchronizer : NSObject
    108 - (CMTimebaseRef)timebase;
    109 - (float)rate;
    110 - (void)setRate:(float)rate;
    111 - (void)setRate:(float)rate time:(CMTime)time;
    112 - (NSArray *)renderers;
    113 - (void)addRenderer:(id)renderer;
    114 - (void)removeRenderer:(id)renderer atTime:(CMTime)time withCompletionHandler:(void (^)(BOOL didRemoveRenderer))completionHandler;
    115 - (id)addPeriodicTimeObserverForInterval:(CMTime)interval queue:(dispatch_queue_t)queue usingBlock:(void (^)(CMTime time))block;
    116 - (id)addBoundaryTimeObserverForTimes:(NSArray *)times queue:(dispatch_queue_t)queue usingBlock:(void (^)(void))block;
    117 - (void)removeTimeObserver:(id)observer;
    118 @end
    119 
    120 #pragma mark -
    12196#pragma mark AVStreamSession
    12297
  • trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.h

    r204466 r207704  
    3838OBJC_CLASS AVSampleBufferAudioRenderer;
    3939OBJC_CLASS AVSampleBufferDisplayLayer;
     40OBJC_CLASS AVSampleBufferRenderSynchronizer;
    4041OBJC_CLASS AVStreamSession;
    4142typedef struct opaqueCMSampleBuffer *CMSampleBufferRef;
     
    122123    void setSize(const IntSize&) override { /* No-op */ }
    123124
    124     void enqueueAudioSampleBufferFromTrack(MediaStreamTrackPrivate&, PlatformSample);
    125     void enqueueVideoSampleBufferFromTrack(MediaStreamTrackPrivate&, PlatformSample);
     125    void enqueueAudioSampleBufferFromTrack(MediaStreamTrackPrivate&, MediaSample&);
     126    void enqueueVideoSampleBufferFromTrack(MediaStreamTrackPrivate&, MediaSample&);
    126127    bool shouldEnqueueVideoSampleBuffer() const;
    127128    void flushAndRemoveVideoSampleBuffers();
     
    187188    RefPtr<MediaStreamPrivate> m_mediaStreamPrivate;
    188189    RetainPtr<AVSampleBufferDisplayLayer> m_sampleBufferDisplayLayer;
     190    RetainPtr<AVSampleBufferRenderSynchronizer> m_synchronizer;
    189191    RetainPtr<CGImageRef> m_pausedImage;
     192    double m_pausedTime { 0 };
    190193    std::unique_ptr<Clock> m_clock;
    191194
  • trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.mm

    r205682 r207704  
    3030
    3131#import "AVAudioCaptureSource.h"
     32#import "AVFoundationSPI.h"
    3233#import "AVVideoCaptureSource.h"
    3334#import "AudioTrackPrivateMediaStream.h"
     
    3637#import "Logging.h"
    3738#import "MediaStreamPrivate.h"
     39#import "MediaTimeAVFoundation.h"
    3840#import "VideoTrackPrivateMediaStream.h"
    3941#import <AVFoundation/AVSampleBufferDisplayLayer.h>
     
    5557
    5658SOFT_LINK_CLASS_OPTIONAL(AVFoundation, AVSampleBufferDisplayLayer)
     59SOFT_LINK_CLASS_OPTIONAL(AVFoundation, AVSampleBufferRenderSynchronizer)
    5760
    5861namespace WebCore {
     
    6467    : m_player(player)
    6568    , m_weakPtrFactory(this)
     69    , m_synchronizer(adoptNS([allocAVSampleBufferRenderSynchronizerInstance() init]))
    6670    , m_clock(Clock::create())
    6771#if PLATFORM(MAC) && ENABLE(VIDEO_PRESENTATION_MODE)
     
    100104bool MediaPlayerPrivateMediaStreamAVFObjC::isAvailable()
    101105{
    102     return AVFoundationLibrary() && isCoreMediaFrameworkAvailable() && getAVSampleBufferDisplayLayerClass();
     106    return AVFoundationLibrary() && isCoreMediaFrameworkAvailable() && getAVSampleBufferDisplayLayerClass() && getAVSampleBufferRenderSynchronizerClass();
    103107}
    104108
     
    120124#pragma mark AVSampleBuffer Methods
    121125
    122 void MediaPlayerPrivateMediaStreamAVFObjC::enqueueAudioSampleBufferFromTrack(MediaStreamTrackPrivate&, PlatformSample)
     126void MediaPlayerPrivateMediaStreamAVFObjC::enqueueAudioSampleBufferFromTrack(MediaStreamTrackPrivate&, MediaSample&)
    123127{
    124128    // FIXME: https://bugs.webkit.org/show_bug.cgi?id=159836
    125129}
    126130
    127 void MediaPlayerPrivateMediaStreamAVFObjC::enqueueVideoSampleBufferFromTrack(MediaStreamTrackPrivate& track, PlatformSample platformSample)
    128 {
    129     if (&track != m_mediaStreamPrivate->activeVideoTrack())
    130         return;
    131 
    132     if (shouldEnqueueVideoSampleBuffer()) {
    133         [m_sampleBufferDisplayLayer enqueueSampleBuffer:platformSample.sample.cmSampleBuffer];
    134         m_isFrameDisplayed = true;
    135        
    136         if (!m_hasEverEnqueuedVideoFrame) {
    137             m_hasEverEnqueuedVideoFrame = true;
    138             m_player->firstVideoFrameAvailable();
    139 
    140             updatePausedImage();
    141         }
     131void MediaPlayerPrivateMediaStreamAVFObjC::enqueueVideoSampleBufferFromTrack(MediaStreamTrackPrivate& track, MediaSample& sample)
     132{
     133    if (&track != m_mediaStreamPrivate->activeVideoTrack() || !shouldEnqueueVideoSampleBuffer())
     134        return;
     135
     136    sample.setTimestamps(toMediaTime(CMTimebaseGetTime([m_synchronizer timebase])), MediaTime::invalidTime());
     137    [m_sampleBufferDisplayLayer enqueueSampleBuffer:sample.platformSample().sample.cmSampleBuffer];
     138    m_isFrameDisplayed = true;
     139
     140    if (!m_hasEverEnqueuedVideoFrame) {
     141        m_hasEverEnqueuedVideoFrame = true;
     142        m_player->firstVideoFrameAvailable();
     143        updatePausedImage();
    142144    }
    143145}
     
    173175#endif
    174176    m_sampleBufferDisplayLayer.get().backgroundColor = cachedCGColor(Color::black);
    175    
     177
     178    [m_synchronizer addRenderer:m_sampleBufferDisplayLayer.get()];
     179
    176180    renderingModeChanged();
    177181   
     
    187191   
    188192    [m_sampleBufferDisplayLayer flush];
     193    CMTime currentTime = CMTimebaseGetTime([m_synchronizer timebase]);
     194    [m_synchronizer removeRenderer:m_sampleBufferDisplayLayer.get() atTime:currentTime withCompletionHandler:^(BOOL){
     195        // No-op.
     196    }];
    189197    m_sampleBufferDisplayLayer = nullptr;
     198
    190199    renderingModeChanged();
    191200   
     
    311320    m_clock->start();
    312321    m_playing = true;
     322    [m_synchronizer setRate:1];
    313323    m_haveEverPlayed = true;
    314324    scheduleDeferredTask([this] {
     
    325335        return;
    326336
    327     m_clock->stop();
     337    m_pausedTime = m_clock->currentTime();
    328338    m_playing = false;
     339    [m_synchronizer setRate:0];
    329340    updateDisplayMode();
    330341    updatePausedImage();
     
    387398MediaTime MediaPlayerPrivateMediaStreamAVFObjC::currentMediaTime() const
    388399{
    389     return MediaTime::createWithDouble(m_clock->currentTime());
     400    return MediaTime::createWithDouble(m_playing ? m_clock->currentTime() : m_pausedTime);
    390401}
    391402
     
    515526        break;
    516527    case RealtimeMediaSource::Video:
    517         enqueueVideoSampleBufferFromTrack(track, mediaSample.platformSample());
     528        enqueueVideoSampleBufferFromTrack(track, mediaSample);
    518529        m_hasReceivedMedia = true;
    519530        scheduleDeferredTask([this] {
  • trunk/Source/WebCore/platform/graphics/avfoundation/objc/SourceBufferPrivateAVFObjC.mm

    r207694 r207704  
    113113
    114114#pragma mark -
    115 #pragma mark AVSampleBufferAudioRenderer
    116 
    117 @interface AVSampleBufferAudioRenderer : NSObject
    118 - (NSInteger)status;
    119 - (NSError*)error;
    120 - (void)enqueueSampleBuffer:(CMSampleBufferRef)sampleBuffer;
    121 - (void)flush;
    122 - (BOOL)isReadyForMoreMediaData;
    123 - (void)requestMediaDataWhenReadyOnQueue:(dispatch_queue_t)queue usingBlock:(void (^)(void))block;
    124 - (void)stopRequestingMediaData;
    125 @end
    126 
    127 #pragma mark -
    128115#pragma mark WebAVStreamDataParserListener
    129116
  • trunk/Source/WebCore/platform/spi/mac/AVFoundationSPI.h

    r207523 r207704  
    163163
    164164NS_ASSUME_NONNULL_END
     165
     166#import <CoreMedia/CMSampleBuffer.h>
     167#import <CoreMedia/CMSync.h>
     168
     169NS_ASSUME_NONNULL_BEGIN
     170
     171@interface AVSampleBufferRenderSynchronizer : NSObject
     172- (CMTimebaseRef)timebase;
     173- (float)rate;
     174- (void)setRate:(float)rate;
     175- (void)setRate:(float)rate time:(CMTime)time;
     176- (NSArray *)renderers;
     177- (void)addRenderer:(id)renderer;
     178- (void)removeRenderer:(id)renderer atTime:(CMTime)time withCompletionHandler:(void (^)(BOOL didRemoveRenderer))completionHandler;
     179- (id)addPeriodicTimeObserverForInterval:(CMTime)interval queue:(dispatch_queue_t)queue usingBlock:(void (^)(CMTime time))block;
     180- (id)addBoundaryTimeObserverForTimes:(NSArray *)times queue:(dispatch_queue_t)queue usingBlock:(void (^)(void))block;
     181- (void)removeTimeObserver:(id)observer;
     182@end
     183
     184NS_ASSUME_NONNULL_END
     185
     186NS_ASSUME_NONNULL_BEGIN
     187
     188@interface AVSampleBufferAudioRenderer : NSObject
     189- (NSInteger)status;
     190- (NSError*)error;
     191- (void)enqueueSampleBuffer:(CMSampleBufferRef)sampleBuffer;
     192- (void)flush;
     193- (BOOL)isReadyForMoreMediaData;
     194- (void)requestMediaDataWhenReadyOnQueue:(dispatch_queue_t)queue usingBlock:(void (^)(void))block;
     195- (void)stopRequestingMediaData;
     196- (void)setVolume:(float)volume;
     197- (void)setMuted:(BOOL)muted;
     198@property (nonatomic, copy) NSString *audioTimePitchAlgorithm;
     199@end
     200
     201NS_ASSUME_NONNULL_END
  • trunk/Source/WebKit2/ChangeLog

    r207699 r207704  
     12016-10-21  Eric Carlson  <eric.carlson@apple.com>
     2
     3        [MediaStream] Dynamically generate media capture sandbox extensions
     4        https://bugs.webkit.org/show_bug.cgi?id=154861
     5        <rdar://problem/24909411>
     6
     7        Reviewed by Tim Horton.
     8
     9        * Shared/SandboxExtension.h:
     10        (WebKit::SandboxExtension::createHandleForGenericExtension):
     11        * Shared/mac/SandboxExtensionMac.mm:
     12        (WebKit::wkSandboxExtensionType): Add case for generic handle.
     13        (WebKit::SandboxExtension::createHandleForGenericExtension): New.
     14
     15        * UIProcess/UserMediaPermissionRequestManagerProxy.cpp:
     16        (WebKit::UserMediaPermissionRequestManagerProxy::invalidateRequests): Clear the list of extensions granted.
     17        (WebKit::UserMediaPermissionRequestManagerProxy::userMediaAccessWasGranted): Extend the web
     18          process sandbox as necessary.
     19        * UIProcess/UserMediaPermissionRequestManagerProxy.h:
     20
     21        * WebProcess/MediaStream/UserMediaPermissionRequestManager.cpp:
     22        (WebKit::UserMediaPermissionRequestManager::~UserMediaPermissionRequestManager): Revoke all
     23          sandbox extensions.
     24        (WebKit::UserMediaPermissionRequestManager::grantUserMediaDevicesSandboxExtension): Consume
     25          sandbox extensions.
     26        * WebProcess/MediaStream/UserMediaPermissionRequestManager.h:
     27
     28        * WebProcess/WebPage/WebPage.cpp:
     29        (WebKit::WebPage::grantUserMediaDevicesSandboxExtension): Pass-through to user media manager.
     30        * WebProcess/WebPage/WebPage.h:
     31
     32        * WebProcess/WebPage/WebPage.messages.in: Add GrantUserMediaDevicesSandboxExtension.
     33
     34        * WebProcess/com.apple.WebProcess.sb.in: Add rules, defines, and a macro to allow dynamic extensions
     35          for media capture devices.
     36
    1372016-10-21  Gavin Barraclough  <barraclough@apple.com>
    238
  • trunk/Source/WebKit2/Shared/SandboxExtension.h

    r204668 r207704  
    4848    enum Type {
    4949        ReadOnly,
    50         ReadWrite
     50        ReadWrite,
     51        Generic,
    5152    };
    5253
     
    9495    static bool createHandleForReadWriteDirectory(const String& path, Handle&); // Will attempt to create the directory.
    9596    static String createHandleForTemporaryFile(const String& prefix, Type type, Handle&);
     97    static bool createHandleForGenericExtension(const String& extensionClass, Handle&);
    9698    ~SandboxExtension();
    9799
     
    128130inline bool SandboxExtension::createHandleForReadWriteDirectory(const String&, Handle&) { return true; }
    129131inline String SandboxExtension::createHandleForTemporaryFile(const String& /*prefix*/, Type, Handle&) {return String();}
     132inline bool SandboxExtension::createHandleForGenericExtension(const String& /*extensionClass*/, Handle&) { return true; }
    130133inline SandboxExtension::~SandboxExtension() { }
    131134inline bool SandboxExtension::revoke() { return true; }
  • trunk/Source/WebKit2/Shared/mac/SandboxExtensionMac.mm

    r204668 r207704  
    160160    case SandboxExtension::ReadWrite:
    161161        return WKSandboxExtensionTypeReadWrite;
     162    case SandboxExtension::Generic:
     163        return WKSandboxExtensionTypeGeneric;
     164
    162165    }
    163166
     
    275278}
    276279
     280bool SandboxExtension::createHandleForGenericExtension(const String& extensionClass, Handle& handle)
     281{
     282    ASSERT(!handle.m_sandboxExtension);
     283
     284    handle.m_sandboxExtension = WKSandboxExtensionCreate(extensionClass.utf8().data(), wkSandboxExtensionType(Type::Generic));
     285    if (!handle.m_sandboxExtension) {
     286        WTFLogAlways("Could not create a '%s' sandbox extension", extensionClass.utf8().data());
     287        return false;
     288    }
     289   
     290    return true;
     291}
     292
    277293SandboxExtension::SandboxExtension(const Handle& handle)
    278294    : m_sandboxExtension(handle.m_sandboxExtension)
  • trunk/Source/WebKit2/UIProcess/UserMediaPermissionRequestManagerProxy.cpp

    r207463 r207704  
    4848        request->invalidate();
    4949    m_pendingDeviceRequests.clear();
     50
     51    m_pageSandboxExtensionsGranted.clear();
    5052}
    5153
     
    121123void UserMediaPermissionRequestManagerProxy::userMediaAccessWasGranted(uint64_t userMediaID, const String& audioDeviceUID, const String& videoDeviceUID)
    122124{
     125    ASSERT(!audioDeviceUID.isEmpty() || !videoDeviceUID.isEmpty());
     126
    123127    if (!m_page.isValid())
    124128        return;
     
    128132
    129133#if ENABLE(MEDIA_STREAM)
     134    size_t extensionCount = 0;
     135    unsigned requiredExtensions = SandboxExtensionsGranted::None;
     136    if (!audioDeviceUID.isEmpty()) {
     137        requiredExtensions |= SandboxExtensionsGranted::Audio;
     138        extensionCount++;
     139    }
     140    if (!videoDeviceUID.isEmpty()) {
     141        requiredExtensions |= SandboxExtensionsGranted::Video;
     142        extensionCount++;
     143    }
     144
     145    unsigned currentExtensions = m_pageSandboxExtensionsGranted.get(m_page.pageID());
     146    if (!(requiredExtensions & currentExtensions)) {
     147        ASSERT(extensionCount);
     148        m_pageSandboxExtensionsGranted.set(m_page.pageID(), requiredExtensions | currentExtensions);
     149        SandboxExtension::HandleArray handles;
     150        handles.allocate(extensionCount);
     151        if (!videoDeviceUID.isEmpty())
     152            SandboxExtension::createHandleForGenericExtension("com.apple.webkit.camera", handles[--extensionCount]);
     153        if (!audioDeviceUID.isEmpty())
     154            SandboxExtension::createHandleForGenericExtension("com.apple.webkit.microphone", handles[--extensionCount]);
     155        m_page.process().send(Messages::WebPage::GrantUserMediaDevicesSandboxExtension(handles), m_page.pageID());
     156    }
     157
    130158    m_page.process().send(Messages::WebPage::UserMediaAccessWasGranted(userMediaID, audioDeviceUID, videoDeviceUID), m_page.pageID());
    131159#else
  • trunk/Source/WebKit2/UIProcess/UserMediaPermissionRequestManagerProxy.h

    r207463 r207704  
    6060    HashMap<uint64_t, RefPtr<UserMediaPermissionCheckProxy>> m_pendingDeviceRequests;
    6161
     62    enum SandboxExtensionsGranted {
     63        None = 0,
     64        Video = 1 << 0,
     65        Audio = 1 << 1
     66    };
     67    HashMap<uint64_t, unsigned> m_pageSandboxExtensionsGranted;
     68
    6269    WebPageProxy& m_page;
    6370};
  • trunk/Source/WebKit2/WebProcess/MediaStream/UserMediaPermissionRequestManager.cpp

    r207463 r207704  
    5151UserMediaPermissionRequestManager::~UserMediaPermissionRequestManager()
    5252{
     53    for (auto& sandboxExtension : m_userMediaDeviceSandboxExtensions)
     54        sandboxExtension->revoke();
    5355}
    5456
     
    143145}
    144146
     147void UserMediaPermissionRequestManager::grantUserMediaDevicesSandboxExtension(const SandboxExtension::HandleArray& sandboxExtensionHandles)
     148{
     149    ASSERT(m_userMediaDeviceSandboxExtensions.size() <= 2);
     150
     151    for (size_t i = 0; i < sandboxExtensionHandles.size(); i++) {
     152        if (RefPtr<SandboxExtension> extension = SandboxExtension::create(sandboxExtensionHandles[i])) {
     153            extension->consume();
     154            m_userMediaDeviceSandboxExtensions.append(extension.release());
     155        }
     156    }
     157}
     158
    145159} // namespace WebKit
    146160
  • trunk/Source/WebKit2/WebProcess/MediaStream/UserMediaPermissionRequestManager.h

    r207463 r207704  
    2323#if ENABLE(MEDIA_STREAM)
    2424
     25#include "SandboxExtension.h"
    2526#include <WebCore/MediaConstraints.h>
    2627#include <WebCore/MediaDevicesEnumerationRequest.h>
     
    4950    void didCompleteMediaDeviceEnumeration(uint64_t, const Vector<WebCore::CaptureDevice>& deviceList, const String& deviceIdentifierHashSalt, bool originHasPersistentAccess);
    5051
     52    void grantUserMediaDevicesSandboxExtension(const SandboxExtension::HandleArray&);
     53
    5154private:
    5255    WebPage& m_page;
     
    5760    HashMap<uint64_t, RefPtr<WebCore::MediaDevicesEnumerationRequest>> m_idToMediaDevicesEnumerationRequestMap;
    5861    HashMap<RefPtr<WebCore::MediaDevicesEnumerationRequest>, uint64_t> m_mediaDevicesEnumerationRequestToIDMap;
     62
     63    Vector<RefPtr<SandboxExtension>> m_userMediaDeviceSandboxExtensions;
    5964};
    6065
  • trunk/Source/WebKit2/WebProcess/WebPage/WebPage.cpp

    r207699 r207704  
    37073707    m_userMediaPermissionRequestManager.didCompleteMediaDeviceEnumeration(userMediaID, devices, deviceIdentifierHashSalt, originHasPersistentAccess);
    37083708}
     3709
     3710void WebPage::grantUserMediaDevicesSandboxExtension(const SandboxExtension::HandleArray& handles)
     3711{
     3712    m_userMediaPermissionRequestManager.grantUserMediaDevicesSandboxExtension(handles);
     3713}
    37093714#endif
    37103715
  • trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h

    r207699 r207704  
    11721172
    11731173    void didCompleteMediaDeviceEnumeration(uint64_t userMediaID, const Vector<WebCore::CaptureDevice>& devices, const String& deviceIdentifierHashSalt, bool originHasPersistentAccess);
     1174    void grantUserMediaDevicesSandboxExtension(const SandboxExtension::HandleArray&);
    11741175#endif
    11751176
  • trunk/Source/WebKit2/WebProcess/WebPage/WebPage.messages.in

    r207689 r207704  
    292292    UserMediaAccessWasDenied(uint64_t userMediaID, uint64_t reason, String invalidConstraint)
    293293    DidCompleteMediaDeviceEnumeration(uint64_t userMediaID, Vector<WebCore::CaptureDevice> devices, String mediaDeviceIdentifierHashSalt, bool hasPersistentAccess)
     294    GrantUserMediaDevicesSandboxExtension(WebKit::SandboxExtension::HandleArray sandboxExtensionHandle)
    294295#endif
    295296
  • trunk/Source/WebKit2/WebProcess/com.apple.WebProcess.sb.in

    r202642 r207704  
    319319;; Data Detectors
    320320(allow file-read* (subpath "/private/var/db/datadetectors/sys"))
     321
     322;; Media capture, utilities
     323(if (not (defined? 'sbpl-filter?))
     324  (define (sbpl-filter? x)
     325      (and (list? x)
     326           (eq? (car x) 'filter))))
     327
     328(macro (with-filter form)
     329   (let* ((ps (cdr form))
     330          (extra-filter (car ps))
     331          (rules (cdr ps)))
     332    `(letrec
     333        ((collect
     334             (lambda (l filters non-filters)
     335                 (if (null? l)
     336                     (list filters non-filters)
     337                     (let*
     338                         ((x (car l))
     339                          (rest (cdr l)))
     340                         (if (sbpl-filter? x)
     341                             (collect rest (cons x filters) non-filters)
     342                             (collect rest filters (cons x non-filters)))))))
     343         (inject-filter
     344             (lambda args
     345                 (let* ((collected (collect args '() '()))
     346                        (filters (car collected))
     347                        (non-filters (cadr collected)))
     348                 (if (null? filters)
     349                     (cons ,extra-filter non-filters)
     350                     (cons (require-all (apply require-any filters) ,extra-filter) non-filters)))))
     351         (orig-allow allow)
     352         (orig-deny deny)
     353         (wrapper
     354             (lambda (action)
     355                 (lambda args (apply action (apply inject-filter args))))))
     356        (set! allow (wrapper orig-allow))
     357        (set! deny (wrapper orig-deny))
     358        ,@rules
     359        (set! deny orig-deny)
     360        (set! allow orig-allow))))
     361
     362(define (home-library-preferences-regex home-library-preferences-relative-regex)
     363    (regex (string-append "^" (regex-quote (param "HOME_LIBRARY_PREFERENCES_DIR")) home-library-preferences-relative-regex)))
     364
     365(define (home-library-preferences-literal home-library-preferences-relative-literal)
     366    (literal (string-append (param "HOME_LIBRARY_PREFERENCES_DIR") home-library-preferences-relative-literal)))
     367
     368(define (shared-preferences-read . domains)
     369  (for-each (lambda (domain)
     370              (begin
     371                (if (defined? `user-preference-read)
     372                    (allow user-preference-read (preference-domain domain)))
     373                ; (Temporary) backward compatibility with non-CFPreferences readers.
     374                (allow file-read*
     375                       (literal (string-append "/Library/Preferences/" domain ".plist"))
     376                       (home-library-preferences-literal (string-append "/" domain ".plist"))
     377                       (home-library-preferences-regex (string-append #"/ByHost/" (regex-quote domain) #"\..*\.plist$")))))
     378            domains))
     379
     380;; Media capture, microphone access
     381(with-filter (extension "com.apple.webkit.microphone")
     382    (allow device-microphone))
     383
     384;; Media capture, camera access
     385(with-filter (extension "com.apple.webkit.camera")
     386    (shared-preferences-read "com.apple.coremedia")
     387    (allow mach-lookup (extension "com.apple.app-sandbox.mach"))
     388    (allow mach-lookup
     389        (global-name "com.apple.cmio.AppleCameraAssistant")
     390        ;; Apple DAL assistants
     391        (global-name "com.apple.cmio.VDCAssistant")
     392        (global-name "com.apple.cmio.AVCAssistant")
     393        (global-name "com.apple.cmio.IIDCVideoAssistant")
     394        ;; QuickTimeIIDCDigitizer assistant
     395        (global-name "com.apple.IIDCAssistant"))
     396    (allow iokit-open
     397        ;; QuickTimeUSBVDCDigitizer
     398        (iokit-user-client-class "IOUSBDeviceUserClientV2")
     399        (iokit-user-client-class "IOUSBInterfaceUserClientV2"))
     400    (allow device-camera))
Note: See TracChangeset for help on using the changeset viewer.