Changeset 199326 in webkit
- Timestamp:
- Apr 11, 2016 6:00:07 PM (8 years ago)
- Location:
- trunk/Source
- Files:
-
- 28 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r199323 r199326 1 2016-04-11 Jeremy Jones <jeremyj@apple.com> 2 3 When clearing cache, also clear AVFoundation cache. 4 https://bugs.webkit.org/show_bug.cgi?id=155783 5 rdar://problem/25252541 6 7 Reviewed by Darin Adler. 8 9 Use AVAssetCache at a specified location on disk for all AVURLAssets. This AVAssetCache 10 can then be used to manage the cache storage used by AVFoundation. It is used to query the 11 contents of the cache in originsInMediaCache() and to clear the cache completely or partially in 12 clearMediaCache() and clearMediaCacheForOrigins(). 13 14 Use SecurityOrigin instead of the less formal site String to represent origins in the cache. 15 16 * html/HTMLMediaElement.cpp: 17 (WebCore::sharedMediaCacheDirectory): Added. 18 (WebCore::HTMLMediaElement::setMediaCacheDirectory): Added. 19 (WebCore::HTMLMediaElement::mediaCacheDirectory): Added. 20 (WebCore::HTMLMediaElement::originsInMediaCache): Added. 21 (WebCore::HTMLMediaElement::clearMediaCache): Added parameter. 22 (WebCore::HTMLMediaElement::clearMediaCacheForOrigins): Added. 23 (WebCore::HTMLMediaElement::mediaPlayerMediaCacheDirectory): Added. 24 (WebCore::HTMLMediaElement::getSitesInMediaCache): Deleted. 25 (WebCore::HTMLMediaElement::clearMediaCacheForSite): Deleted. 26 * html/HTMLMediaElement.h: 27 (WebCore::HTMLMediaElement::clearMediaCache): Added parameter. 28 * platform/graphics/MediaPlayer.cpp: 29 (WebCore::addMediaEngine): Add new cache methods. 30 (WebCore::addToHash): Added. 31 (WebCore::MediaPlayer::originsInMediaCache): Added. 32 (WebCore::MediaPlayer::clearMediaCache): Added parameter. 33 (WebCore::MediaPlayer::clearMediaCacheForOrigins): Added. 34 (WebCore::MediaPlayer::getSitesInMediaCache): Deleted. 35 (WebCore::MediaPlayer::clearMediaCacheForSite): Deleted. 36 * platform/graphics/MediaPlayer.h: 37 (WebCore::MediaPlayerClient::mediaPlayerMediaCacheDirectory): Added. 38 * platform/graphics/MediaPlayerPrivate.h: 39 (WebCore::MediaPlayerPrivateInterface::originsInMediaCache): Added. 40 (WebCore::MediaPlayerPrivateInterface::clearMediaCache): Added parameter. 41 (WebCore::MediaPlayerPrivateInterface::clearMediaCacheForOrigins): Added. 42 (WebCore::MediaPlayerPrivateInterface::getSitesInMediaCache): Deleted. 43 (WebCore::MediaPlayerPrivateInterface::clearMediaCacheForSite): Deleted. 44 * platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h: 45 * platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm: 46 (WebCore::MediaPlayerPrivateAVFoundationObjC::registerMediaEngine): Added cache methods. 47 (WebCore::assetCacheForPath): Added. 48 (WebCore::MediaPlayerPrivateAVFoundationObjC::originsInMediaCache): Added. 49 (WebCore::toSystemClockTime): Added. 50 (WebCore::MediaPlayerPrivateAVFoundationObjC::clearMediaCache): Added parameter. 51 (WebCore::MediaPlayerPrivateAVFoundationObjC::clearMediaCacheForOrigins): Added. 52 (WebCore::MediaPlayerPrivateAVFoundationObjC::createAVAssetForURL): Added. 53 * platform/graphics/mac/MediaPlayerPrivateQTKit.h: 54 * platform/graphics/mac/MediaPlayerPrivateQTKit.mm: 55 (WebCore::MediaPlayerPrivateQTKit::registerMediaEngine): Added cache methods. 56 (WebCore::MediaPlayerPrivateQTKit::originsInMediaCache): Added. 57 (WebCore::MediaPlayerPrivateQTKit::clearMediaCache): Added parameter. 58 (WebCore::MediaPlayerPrivateQTKit::clearMediaCacheForOrigins): Added. 59 (WebCore::MediaPlayerPrivateQTKit::getSitesInMediaCache): Deleted. 60 (WebCore::MediaPlayerPrivateQTKit::clearMediaCacheForSite): Deleted. 61 * platform/spi/mac/AVFoundationSPI.h: 62 1 63 2016-04-11 Commit Queue <commit-queue@webkit.org> 2 64 -
trunk/Source/WebCore/html/HTMLMediaElement.cpp
r199321 r199326 5594 5594 document().decrementLoadEventDelayCount(); 5595 5595 } 5596 5597 5598 void HTMLMediaElement::getSitesInMediaCache(Vector<String>& sites) 5599 { 5600 MediaPlayer::getSitesInMediaCache(sites); 5601 } 5602 5603 void HTMLMediaElement::clearMediaCache() 5604 { 5605 MediaPlayer::clearMediaCache(); 5606 } 5607 5608 void HTMLMediaElement::clearMediaCacheForSite(const String& site) 5609 { 5610 MediaPlayer::clearMediaCacheForSite(site); 5596 5597 static String& sharedMediaCacheDirectory() 5598 { 5599 static NeverDestroyed<String> sharedMediaCacheDirectory; 5600 return sharedMediaCacheDirectory; 5601 } 5602 5603 void HTMLMediaElement::setMediaCacheDirectory(const String& path) 5604 { 5605 sharedMediaCacheDirectory() = path; 5606 } 5607 5608 const String& HTMLMediaElement::mediaCacheDirectory() 5609 { 5610 return sharedMediaCacheDirectory(); 5611 } 5612 5613 HashSet<RefPtr<SecurityOrigin>> HTMLMediaElement::originsInMediaCache(const String& path) 5614 { 5615 return MediaPlayer::originsInMediaCache(path); 5616 } 5617 5618 void HTMLMediaElement::clearMediaCache(const String& path, std::chrono::system_clock::time_point modifiedSince) 5619 { 5620 MediaPlayer::clearMediaCache(path, modifiedSince); 5621 } 5622 5623 void HTMLMediaElement::clearMediaCacheForOrigins(const String& path, const HashSet<RefPtr<SecurityOrigin>>& origins) 5624 { 5625 MediaPlayer::clearMediaCacheForOrigins(path, origins); 5611 5626 } 5612 5627 … … 6193 6208 } 6194 6209 6210 const String& HTMLMediaElement::mediaPlayerMediaCacheDirectory() const 6211 { 6212 return mediaCacheDirectory(); 6213 } 6214 6195 6215 bool HTMLMediaElement::mediaPlayerShouldWaitForResponseToAuthenticationChallenge(const AuthenticationChallenge& challenge) 6196 6216 { -
trunk/Source/WebCore/html/HTMLMediaElement.h
r199321 r199326 381 381 382 382 // Media cache management. 383 WEBCORE_EXPORT static void getSitesInMediaCache(Vector<String>&); 384 WEBCORE_EXPORT static void clearMediaCache(); 385 WEBCORE_EXPORT static void clearMediaCacheForSite(const String&); 383 WEBCORE_EXPORT static void setMediaCacheDirectory(const String&); 384 WEBCORE_EXPORT static const String& mediaCacheDirectory(); 385 WEBCORE_EXPORT static HashSet<RefPtr<SecurityOrigin>> originsInMediaCache(const String&); 386 WEBCORE_EXPORT static void clearMediaCache(const String&, std::chrono::system_clock::time_point modifiedSince = { }); 387 WEBCORE_EXPORT static void clearMediaCacheForOrigins(const String&, const HashSet<RefPtr<SecurityOrigin>>&); 386 388 static void resetMediaEngines(); 387 389 … … 598 600 RefPtr<PlatformMediaResourceLoader> mediaPlayerCreateResourceLoader() override; 599 601 bool mediaPlayerShouldUsePersistentCache() const override; 602 const String& mediaPlayerMediaCacheDirectory() const override; 600 603 601 604 #if PLATFORM(WIN) && USE(AVFOUNDATION) -
trunk/Source/WebCore/platform/graphics/MediaPlayer.cpp
r199321 r199326 171 171 MediaEngineSupportedTypes getSupportedTypes; 172 172 MediaEngineSupportsType supportsTypeAndCodecs; 173 MediaEngine GetSitesInMediaCache getSitesInMediaCache;173 MediaEngineOriginsInMediaCache originsInMediaCache; 174 174 MediaEngineClearMediaCache clearMediaCache; 175 MediaEngineClearMediaCacheFor Site clearMediaCacheForSite;175 MediaEngineClearMediaCacheForOrigins clearMediaCacheForOrigins; 176 176 MediaEngineSupportsKeySystem supportsKeySystem; 177 177 }; 178 178 179 static void addMediaEngine(CreateMediaEnginePlayer, MediaEngineSupportedTypes, MediaEngineSupportsType, MediaEngine GetSitesInMediaCache, MediaEngineClearMediaCache, MediaEngineClearMediaCacheForSite, MediaEngineSupportsKeySystem);179 static void addMediaEngine(CreateMediaEnginePlayer, MediaEngineSupportedTypes, MediaEngineSupportsType, MediaEngineOriginsInMediaCache, MediaEngineClearMediaCache, MediaEngineClearMediaCacheForOrigins, MediaEngineSupportsKeySystem); 180 180 181 181 static bool haveMediaEnginesVector; … … 235 235 236 236 static void addMediaEngine(CreateMediaEnginePlayer constructor, MediaEngineSupportedTypes getSupportedTypes, MediaEngineSupportsType supportsType, 237 MediaEngine GetSitesInMediaCache getSitesInMediaCache, MediaEngineClearMediaCache clearMediaCache, MediaEngineClearMediaCacheForSite clearMediaCacheForSite, MediaEngineSupportsKeySystem supportsKeySystem)237 MediaEngineOriginsInMediaCache originsInMediaCache, MediaEngineClearMediaCache clearMediaCache, MediaEngineClearMediaCacheForOrigins clearMediaCacheForOrigins, MediaEngineSupportsKeySystem supportsKeySystem) 238 238 { 239 239 ASSERT(constructor); … … 241 241 ASSERT(supportsType); 242 242 243 mutableInstalledMediaEnginesVector().append(MediaPlayerFactory { constructor, getSupportedTypes, supportsType, getSitesInMediaCache, clearMediaCache, clearMediaCacheForSite, supportsKeySystem });243 mutableInstalledMediaEnginesVector().append(MediaPlayerFactory { constructor, getSupportedTypes, supportsType, originsInMediaCache, clearMediaCache, clearMediaCacheForOrigins, supportsKeySystem }); 244 244 } 245 245 … … 1043 1043 } 1044 1044 1045 void MediaPlayer::getSitesInMediaCache(Vector<String>& sites) 1046 { 1045 template<typename T> 1046 static void addToHash(HashSet<T>& toHash, HashSet<T>&& fromHash) 1047 { 1048 if (toHash.isEmpty()) 1049 toHash = WTFMove(fromHash); 1050 else 1051 toHash.add(fromHash.begin(), fromHash.end()); 1052 } 1053 1054 HashSet<RefPtr<SecurityOrigin>> MediaPlayer::originsInMediaCache(const String& path) 1055 { 1056 HashSet<RefPtr<SecurityOrigin>> origins; 1047 1057 for (auto& engine : installedMediaEngines()) { 1048 if (!engine. getSitesInMediaCache)1058 if (!engine.originsInMediaCache) 1049 1059 continue; 1050 Vector<String> engineSites; 1051 engine.getSitesInMediaCache(engineSites); 1052 sites.appendVector(engineSites); 1060 addToHash(origins, engine.originsInMediaCache(path)); 1053 1061 } 1054 } 1055 1056 void MediaPlayer::clearMediaCache() 1062 return origins; 1063 } 1064 1065 void MediaPlayer::clearMediaCache(const String& path, std::chrono::system_clock::time_point modifiedSince) 1057 1066 { 1058 1067 for (auto& engine : installedMediaEngines()) { 1059 1068 if (engine.clearMediaCache) 1060 engine.clearMediaCache( );1069 engine.clearMediaCache(path, modifiedSince); 1061 1070 } 1062 1071 } 1063 1072 1064 void MediaPlayer::clearMediaCacheFor Site(const String& site)1073 void MediaPlayer::clearMediaCacheForOrigins(const String& path, const HashSet<RefPtr<SecurityOrigin>>& origins) 1065 1074 { 1066 1075 for (auto& engine : installedMediaEngines()) { 1067 if (engine.clearMediaCacheFor Site)1068 engine.clearMediaCacheFor Site(site);1076 if (engine.clearMediaCacheForOrigins) 1077 engine.clearMediaCacheForOrigins(path, origins); 1069 1078 } 1070 1079 } -
trunk/Source/WebCore/platform/graphics/MediaPlayer.h
r199321 r199326 41 41 #include "PlatformMediaResourceLoader.h" 42 42 #include "PlatformMediaSession.h" 43 #include "SecurityOriginHash.h" 43 44 #include "Timer.h" 44 45 #include "VideoTrackPrivate.h" … … 237 238 virtual bool doesHaveAttribute(const AtomicString&, AtomicString* = 0) const { return false; } 238 239 virtual bool mediaPlayerShouldUsePersistentCache() const { return true; } 240 virtual const String& mediaPlayerMediaCacheDirectory() const { return emptyString(); } 239 241 240 242 #if ENABLE(VIDEO_TRACK) … … 293 295 static void getSupportedTypes(HashSet<String, ASCIICaseInsensitiveHash>&); 294 296 static bool isAvailable(); 295 static void getSitesInMediaCache(Vector<String>&);296 static void clearMediaCache( );297 static void clearMediaCacheFor Site(const String&);297 static HashSet<RefPtr<SecurityOrigin>> originsInMediaCache(const String& path); 298 static void clearMediaCache(const String& path, std::chrono::system_clock::time_point modifiedSince); 299 static void clearMediaCacheForOrigins(const String& path, const HashSet<RefPtr<SecurityOrigin>>&); 298 300 static bool supportsKeySystem(const String& keySystem, const String& mimeType); 299 301 … … 631 633 typedef void (*MediaEngineSupportedTypes)(HashSet<String, ASCIICaseInsensitiveHash>& types); 632 634 typedef MediaPlayer::SupportsType (*MediaEngineSupportsType)(const MediaEngineSupportParameters& parameters); 633 typedef void (*MediaEngineGetSitesInMediaCache)(Vector<String>&);634 typedef void (*MediaEngineClearMediaCache)( );635 typedef void (*MediaEngineClearMediaCacheFor Site)(const String&);635 typedef HashSet<RefPtr<SecurityOrigin>> (*MediaEngineOriginsInMediaCache)(const String& path); 636 typedef void (*MediaEngineClearMediaCache)(const String& path, std::chrono::system_clock::time_point modifiedSince); 637 typedef void (*MediaEngineClearMediaCacheForOrigins)(const String& path, const HashSet<RefPtr<SecurityOrigin>>&); 636 638 typedef bool (*MediaEngineSupportsKeySystem)(const String& keySystem, const String& mimeType); 637 639 638 640 typedef void (*MediaEngineRegistrar)(CreateMediaEnginePlayer, MediaEngineSupportedTypes, MediaEngineSupportsType, 639 MediaEngine GetSitesInMediaCache, MediaEngineClearMediaCache, MediaEngineClearMediaCacheForSite, MediaEngineSupportsKeySystem);641 MediaEngineOriginsInMediaCache, MediaEngineClearMediaCache, MediaEngineClearMediaCacheForOrigins, MediaEngineSupportsKeySystem); 640 642 typedef void (*MediaEngineRegister)(MediaEngineRegistrar); 641 643 -
trunk/Source/WebCore/platform/graphics/MediaPlayerPrivate.h
r199321 r199326 215 215 virtual unsigned videoDecodedByteCount() const { return 0; } 216 216 217 void getSitesInMediaCache(Vector<String>&) {}218 void clearMediaCache( ) { }219 void clearMediaCacheFor Site(const String&) { }217 HashSet<RefPtr<SecurityOrigin>> originsInMediaCache(const String&) { return { }; } 218 void clearMediaCache(const String&, std::chrono::system_clock::time_point) { } 219 void clearMediaCacheForOrigins(const String&, const HashSet<RefPtr<SecurityOrigin>>&) { } 220 220 221 221 virtual void setPrivateBrowsingMode(bool) { } -
trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h
r199321 r199326 88 88 static void registerMediaEngine(MediaEngineRegistrar); 89 89 90 static HashSet<RefPtr<SecurityOrigin>> originsInMediaCache(const String&); 91 static void clearMediaCache(const String&, std::chrono::system_clock::time_point modifiedSince); 92 static void clearMediaCacheForOrigins(const String&, const HashSet<RefPtr<SecurityOrigin>>&); 93 90 94 void setAsset(RetainPtr<id>); 91 95 void tracksChanged() override; -
trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm
r199321 r199326 159 159 SOFT_LINK_CLASS(AVFoundation, AVAssetImageGenerator) 160 160 SOFT_LINK_CLASS(AVFoundation, AVMetadataItem) 161 SOFT_LINK_CLASS(AVFoundation, AVAssetCache) 161 162 162 163 SOFT_LINK_CLASS(CoreImage, CIContext) … … 228 229 229 230 #if ENABLE(AVF_CAPTIONS) 231 SOFT_LINK_POINTER(AVFoundation, AVURLAssetCacheKey, NSString*) 230 232 SOFT_LINK_POINTER(AVFoundation, AVURLAssetHTTPCookiesKey, NSString*) 231 233 SOFT_LINK_POINTER(AVFoundation, AVURLAssetOutOfBandAlternateTracksKey, NSString*) … … 243 245 #define AVURLAssetHTTPCookiesKey getAVURLAssetHTTPCookiesKey() 244 246 #define AVURLAssetOutOfBandAlternateTracksKey getAVURLAssetOutOfBandAlternateTracksKey() 247 #define AVURLAssetCacheKey getAVURLAssetCacheKey() 245 248 #define AVURLAssetUsesNoPersistentCacheKey getAVURLAssetUsesNoPersistentCacheKey() 246 249 #define AVOutOfBandAlternateTrackDisplayNameKey getAVOutOfBandAlternateTrackDisplayNameKey() … … 423 426 if (isAvailable()) 424 427 registrar([](MediaPlayer* player) { return std::make_unique<MediaPlayerPrivateAVFoundationObjC>(player); }, 425 getSupportedTypes, supportsType, 0, 0, 0, supportsKeySystem); 428 getSupportedTypes, supportsType, originsInMediaCache, clearMediaCache, clearMediaCacheForOrigins, supportsKeySystem); 429 } 430 431 static AVAssetCache *assetCacheForPath(const String& path) 432 { 433 NSURL *assetCacheURL; 434 435 if (path.isEmpty()) 436 assetCacheURL = [[NSURL fileURLWithPath:NSTemporaryDirectory()] URLByAppendingPathComponent:@"MediaCache" isDirectory:YES]; 437 else 438 assetCacheURL = [NSURL fileURLWithPath:path isDirectory:YES]; 439 440 return [getAVAssetCacheClass() assetCacheWithURL:assetCacheURL]; 441 } 442 443 HashSet<RefPtr<SecurityOrigin>> MediaPlayerPrivateAVFoundationObjC::originsInMediaCache(const String& path) 444 { 445 HashSet<RefPtr<SecurityOrigin>> origins; 446 for (NSString *key in [assetCacheForPath(path) allKeys]) { 447 URL keyAsURL = URL(URL(), key); 448 if (keyAsURL.isValid()) 449 origins.add(SecurityOrigin::create(keyAsURL)); 450 } 451 return origins; 452 } 453 454 static std::chrono::system_clock::time_point toSystemClockTime(NSDate *date) 455 { 456 ASSERT(date); 457 using namespace std::chrono; 458 459 return system_clock::time_point(duration_cast<system_clock::duration>(duration<double>(date.timeIntervalSince1970))); 460 } 461 462 void MediaPlayerPrivateAVFoundationObjC::clearMediaCache(const String& path, std::chrono::system_clock::time_point modifiedSince) 463 { 464 LOG(Media, "MediaPlayerPrivateAVFoundationObjC::clearMediaCache()"); 465 466 AVAssetCache* assetCache = assetCacheForPath(path); 467 468 for (NSString *key in [assetCache allKeys]) { 469 if (toSystemClockTime([assetCache lastModifiedDateOfEntryForKey:key]) > modifiedSince) 470 [assetCache removeEntryForKey:key]; 471 } 472 473 NSFileManager *fileManager = [NSFileManager defaultManager]; 474 NSURL *baseURL = [assetCache URL]; 475 476 if (modifiedSince <= std::chrono::system_clock::time_point { }) { 477 [fileManager removeItemAtURL:baseURL error:nil]; 478 return; 479 } 480 481 NSArray *propertyKeys = @[NSURLNameKey, NSURLContentModificationDateKey, NSURLIsRegularFileKey]; 482 NSDirectoryEnumerator *enumerator = [fileManager enumeratorAtURL:baseURL includingPropertiesForKeys: 483 propertyKeys options:NSDirectoryEnumerationSkipsSubdirectoryDescendants 484 errorHandler:nil]; 485 486 RetainPtr<NSMutableArray> urlsToDelete = adoptNS([[NSMutableArray alloc] init]); 487 for (NSURL *fileURL : enumerator) { 488 NSDictionary *fileAttributes = [fileURL resourceValuesForKeys:propertyKeys error:nil]; 489 490 if (![fileAttributes[NSURLNameKey] hasPrefix:@"CachedMedia-"]) 491 continue; 492 493 if (![fileAttributes[NSURLIsRegularFileKey] boolValue]) 494 continue; 495 496 if (toSystemClockTime(fileAttributes[NSURLContentModificationDateKey]) <= modifiedSince) 497 continue; 498 499 [urlsToDelete addObject:fileURL]; 500 } 501 502 for (NSURL *fileURL in urlsToDelete.get()) 503 [fileManager removeItemAtURL:fileURL error:nil]; 504 } 505 506 void MediaPlayerPrivateAVFoundationObjC::clearMediaCacheForOrigins(const String& path, const HashSet<RefPtr<SecurityOrigin>>& origins) 507 { 508 LOG(Media, "MediaPlayerPrivateAVFoundationObjC::clearMediaCacheForOrigins()"); 509 AVAssetCache* assetCache = assetCacheForPath(path); 510 for (NSString *key in [assetCache allKeys]) { 511 URL keyAsURL = URL(URL(), key); 512 if (keyAsURL.isValid()) { 513 if (origins.contains(SecurityOrigin::create(keyAsURL))) 514 [assetCache removeEntryForKey:key]; 515 } 516 } 426 517 } 427 518 … … 875 966 #endif 876 967 877 [options setObject:[NSNumber numberWithBool:!player()->client().mediaPlayerShouldUsePersistentCache()] forKey:AVURLAssetUsesNoPersistentCacheKey]; 968 bool usePersistentCache = player()->client().mediaPlayerShouldUsePersistentCache(); 969 [options setObject:@(!usePersistentCache) forKey:AVURLAssetUsesNoPersistentCacheKey]; 970 971 if (usePersistentCache) 972 [options setObject:assetCacheForPath(player()->client().mediaPlayerMediaCacheDirectory()) forKey:AVURLAssetCacheKey]; 878 973 879 974 NSURL *cocoaURL = canonicalURL(url); -
trunk/Source/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.h
r199321 r199326 69 69 static MediaPlayer::SupportsType supportsType(const MediaEngineSupportParameters&); 70 70 71 static void getSitesInMediaCache(Vector<String>&);72 static void clearMediaCache( );73 static void clearMediaCacheFor Site(const String&);71 static HashSet<RefPtr<SecurityOrigin>> originsInMediaCache(const String&); 72 static void clearMediaCache(const String&, std::chrono::system_clock::time_point modifiedSince); 73 static void clearMediaCacheForOrigins(const String&, const HashSet<RefPtr<SecurityOrigin>>&); 74 74 static bool isAvailable(); 75 75 -
trunk/Source/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm
r199321 r199326 176 176 if (isAvailable()) 177 177 registrar([](MediaPlayer* player) { return std::make_unique<MediaPlayerPrivateQTKit>(player); }, getSupportedTypes, 178 supportsType, getSitesInMediaCache, clearMediaCache, clearMediaCacheForSite, 0);178 supportsType, originsInMediaCache, clearMediaCache, clearMediaCacheForOrigins, 0); 179 179 } 180 180 … … 1340 1340 } 1341 1341 1342 void MediaPlayerPrivateQTKit::getSitesInMediaCache(Vector<String>& sites) 1343 { 1342 HashSet<RefPtr<SecurityOrigin>> MediaPlayerPrivateQTKit::originsInMediaCache(const String&) 1343 { 1344 HashSet<RefPtr<SecurityOrigin>> origins; 1344 1345 NSArray *mediaSites = wkQTGetSitesInMediaDownloadCache(); 1345 for (NSString *site in mediaSites) 1346 sites.append(site); 1347 } 1348 1349 void MediaPlayerPrivateQTKit::clearMediaCache() 1346 1347 for (NSString *site in mediaSites) { 1348 URL siteAsURL = URL(URL(), site); 1349 if (siteAsURL.isValid()) 1350 origins.add(SecurityOrigin::create(siteAsURL)); 1351 } 1352 return origins; 1353 } 1354 1355 void MediaPlayerPrivateQTKit::clearMediaCache(const String&, std::chrono::system_clock::time_point) 1350 1356 { 1351 1357 LOG(Media, "MediaPlayerPrivateQTKit::clearMediaCache()"); … … 1353 1359 } 1354 1360 1355 void MediaPlayerPrivateQTKit::clearMediaCacheForSite(const String& site) 1356 { 1357 LOG(Media, "MediaPlayerPrivateQTKit::clearMediaCacheForSite()"); 1358 wkQTClearMediaDownloadCacheForSite(site); 1361 void MediaPlayerPrivateQTKit::clearMediaCacheForOrigins(const String&, const HashSet<RefPtr<SecurityOrigin>>& origins) 1362 { 1363 LOG(Media, "MediaPlayerPrivateQTKit::clearMediaCacheForOrigins()"); 1364 for (auto& origin : origins) 1365 wkQTClearMediaDownloadCacheForSite(origin->toRawString()); 1359 1366 } 1360 1367 -
trunk/Source/WebCore/platform/spi/mac/AVFoundationSPI.h
r199321 r199326 56 56 #endif // ENABLE(WIRELESS_PLAYBACK_TARGET) && !PLATFORM(IOS) 57 57 58 #if USE(APPLE_INTERNAL_SDK) 59 #import <AVFoundation/AVAssetCache_Private.h> 60 #else 61 NS_ASSUME_NONNULL_BEGIN 62 @interface AVAssetCache : NSObject 63 + (AVAssetCache *)assetCacheWithURL:(NSURL *)URL; 64 - (id)initWithURL:(NSURL *)URL; 65 - (NSArray *)allKeys; 66 - (NSDate *)lastModifiedDateOfEntryForKey:(NSString *)key; 67 - (void)removeEntryForKey:(NSString *)key; 68 @property (nonatomic, readonly, copy) NSURL *URL; 69 @end 70 NS_ASSUME_NONNULL_END 71 #endif 72 58 73 #if PLATFORM(IOS) 59 74 -
trunk/Source/WebKit2/ChangeLog
r199321 r199326 1 2016-04-11 Jeremy Jones <jeremyj@apple.com> 2 3 When clearing cache, also clear AVFoundation cache. 4 https://bugs.webkit.org/show_bug.cgi?id=155783 5 rdar://problem/25252541 6 7 Reviewed by Darin Adler. 8 9 Include the HTMLMediaElement media cache when doing disk cache operations. 10 Add a sandbox extension for media cache directory. This allows the UI process and the web process 11 to access the same cache. 12 13 * Shared/WebProcessCreationParameters.cpp: 14 (WebKit::WebProcessCreationParameters::encode): Add media cache directory. 15 (WebKit::WebProcessCreationParameters::decode): Add media cache directory. 16 * Shared/WebProcessCreationParameters.h: 17 * UIProcess/API/APIProcessPoolConfiguration.cpp: 18 (API::ProcessPoolConfiguration::createWithLegacyOptions): 19 (API::ProcessPoolConfiguration::ProcessPoolConfiguration): Add media cache directory. 20 (API::ProcessPoolConfiguration::copy): Add media cache directory. 21 * UIProcess/API/APIProcessPoolConfiguration.h: 22 * UIProcess/API/APIWebsiteDataStore.cpp: 23 (API::WebsiteDataStore::defaultMediaCacheDirectory): Default implementation. 24 * UIProcess/API/APIWebsiteDataStore.h: 25 * UIProcess/API/Cocoa/APIWebsiteDataStoreCocoa.mm: 26 (API::WebsiteDataStore::defaultMediaCacheDirectory): Media cache is in temporary directory. 27 (API::WebsiteDataStore::tempDirectoryFileSystemRepresentation): For resources in temporary directory. 28 (API::WebsiteDataStore::defaultDataStoreConfiguration): Init media cache directory. 29 * UIProcess/Cocoa/WebProcessPoolCocoa.mm: 30 (WebKit::WebProcessPool::legacyPlatformDefaultMediaCacheDirectory): 31 * UIProcess/WebProcessPool.cpp: 32 (WebKit::legacyWebsiteDataStoreConfiguration): Add mediaCacheDirectory. 33 (WebKit::WebProcessPool::createNewWebProcess): Add mediaCacheDirectory. 34 * UIProcess/WebProcessPool.h: 35 * UIProcess/WebsiteData/WebsiteDataStore.cpp: 36 (WebKit::WebsiteDataStore::WebsiteDataStore): 37 (WebKit::WebsiteDataStore::fetchData): Implement for mediaCacheDirectory. 38 (WebKit::WebsiteDataStore::removeData): Implement for mediaCacheDirectory. 39 * UIProcess/WebsiteData/WebsiteDataStore.h: 40 * UIProcess/efl/WebProcessPoolEfl.cpp: 41 (WebKit::WebProcessPool::legacyPlatformDefaultMediaCacheDirectory): Added. 42 * UIProcess/gtk/WebProcessPoolGtk.cpp: 43 (WebKit::WebProcessPool::legacyPlatformDefaultMediaCacheDirectory): Added. 44 * WebProcess/WebProcess.cpp: 45 (WebKit::WebProcess::initializeWebProcess): Initialize media cache directory. 46 * WebProcess/cocoa/WebProcessCocoa.mm: 47 (WebKit::WebProcess::platformInitializeWebProcess): Consume sandbox extension. 48 1 49 2016-04-11 Commit Queue <commit-queue@webkit.org> 2 50 -
trunk/Source/WebKit2/Shared/WebProcessCreationParameters.cpp
r199321 r199326 66 66 encoder << webSQLDatabaseDirectory; 67 67 encoder << webSQLDatabaseDirectoryExtensionHandle; 68 encoder << mediaCacheDirectory; 69 encoder << mediaCacheDirectoryExtensionHandle; 68 70 #if ENABLE(SECCOMP_FILTERS) 69 71 encoder << cookieStorageDirectory; … … 160 162 if (!decoder.decode(parameters.webSQLDatabaseDirectoryExtensionHandle)) 161 163 return false; 164 if (!decoder.decode(parameters.mediaCacheDirectory)) 165 return false; 166 if (!decoder.decode(parameters.mediaCacheDirectoryExtensionHandle)) 167 return false; 162 168 #if ENABLE(SECCOMP_FILTERS) 163 169 if (!decoder.decode(parameters.cookieStorageDirectory)) -
trunk/Source/WebKit2/Shared/WebProcessCreationParameters.h
r199321 r199326 73 73 String webSQLDatabaseDirectory; 74 74 SandboxExtension::Handle webSQLDatabaseDirectoryExtensionHandle; 75 String mediaCacheDirectory; 76 SandboxExtension::Handle mediaCacheDirectoryExtensionHandle; 75 77 #if ENABLE(SECCOMP_FILTERS) 76 78 String cookieStorageDirectory; -
trunk/Source/WebKit2/UIProcess/API/APIProcessPoolConfiguration.cpp
r199321 r199326 47 47 configuration->m_applicationCacheDirectory = WebKit::WebProcessPool::legacyPlatformDefaultApplicationCacheDirectory(); 48 48 configuration->m_diskCacheDirectory = WebKit::WebProcessPool::legacyPlatformDefaultNetworkCacheDirectory(); 49 configuration->m_mediaCacheDirectory = WebKit::WebProcessPool::legacyPlatformDefaultMediaCacheDirectory(); 49 50 configuration->m_indexedDBDatabaseDirectory = WebKit::WebProcessPool::legacyPlatformDefaultIndexedDBDatabaseDirectory(); 50 51 configuration->m_localStorageDirectory = WebKit::WebProcessPool::legacyPlatformDefaultLocalStorageDirectory(); … … 58 59 : m_applicationCacheDirectory(WebsiteDataStore::defaultApplicationCacheDirectory()) 59 60 , m_diskCacheDirectory(WebsiteDataStore::defaultNetworkCacheDirectory()) 61 , m_mediaCacheDirectory(WebsiteDataStore::defaultMediaCacheDirectory()) 60 62 , m_indexedDBDatabaseDirectory(WebsiteDataStore::defaultIndexedDBDatabaseDirectory()) 61 63 , m_localStorageDirectory(WebsiteDataStore::defaultLocalStorageDirectory()) … … 80 82 copy->m_applicationCacheDirectory = this->m_applicationCacheDirectory; 81 83 copy->m_diskCacheDirectory = this->m_diskCacheDirectory; 84 copy->m_mediaCacheDirectory = this->m_mediaCacheDirectory; 82 85 copy->m_indexedDBDatabaseDirectory = this->m_indexedDBDatabaseDirectory; 83 86 copy->m_injectedBundlePath = this->m_injectedBundlePath; -
trunk/Source/WebKit2/UIProcess/API/APIProcessPoolConfiguration.h
r199321 r199326 66 66 void setDiskCacheDirectory(const WTF::String& diskCacheDirectory) { m_diskCacheDirectory = diskCacheDirectory; } 67 67 68 const WTF::String& mediaCacheDirectory() const { return m_mediaCacheDirectory; } 69 void setMediaCacheDirectory(const WTF::String& mediaCacheDirectory) { m_mediaCacheDirectory = mediaCacheDirectory; } 70 68 71 const WTF::String& indexedDBDatabaseDirectory() const { return m_indexedDBDatabaseDirectory; } 69 72 void setIndexedDBDatabaseDirectory(const WTF::String& indexedDBDatabaseDirectory) { m_indexedDBDatabaseDirectory = indexedDBDatabaseDirectory; } … … 103 106 WTF::String m_applicationCacheDirectory; 104 107 WTF::String m_diskCacheDirectory; 108 WTF::String m_mediaCacheDirectory; 105 109 WTF::String m_indexedDBDatabaseDirectory; 106 110 WTF::String m_injectedBundlePath; -
trunk/Source/WebKit2/UIProcess/API/APIWebsiteDataStore.cpp
r199321 r199326 138 138 139 139 #endif 140 141 #if !PLATFORM(COCOA) 142 String WebsiteDataStore::defaultMediaCacheDirectory() 143 { 144 // FIXME: Implement. https://bugs.webkit.org/show_bug.cgi?id=156369 and https://bugs.webkit.org/show_bug.cgi?id=156370 145 return String(); 146 } 147 #endif 140 148 141 149 } -
trunk/Source/WebKit2/UIProcess/API/APIWebsiteDataStore.h
r199321 r199326 50 50 static String defaultApplicationCacheDirectory(); 51 51 static String defaultNetworkCacheDirectory(); 52 static String defaultMediaCacheDirectory(); 52 53 53 54 static String defaultIndexedDBDatabaseDirectory(); … … 61 62 WebsiteDataStore(); 62 63 64 static String tempDirectoryFileSystemRepresentation(const String& directoryName); 63 65 static String cacheDirectoryFileSystemRepresentation(const String& directoryName); 64 66 static String websiteDataDirectoryFileSystemRepresentation(const String& directoryName); -
trunk/Source/WebKit2/UIProcess/API/Cocoa/APIWebsiteDataStoreCocoa.mm
r199321 r199326 58 58 } 59 59 60 String WebsiteDataStore::defaultMediaCacheDirectory() 61 { 62 return tempDirectoryFileSystemRepresentation("MediaCache"); 63 } 64 60 65 String WebsiteDataStore::defaultIndexedDBDatabaseDirectory() 61 66 { … … 81 86 { 82 87 return websiteDataDirectoryFileSystemRepresentation("ResourceLoadStatistics"); 88 } 89 90 String WebsiteDataStore::tempDirectoryFileSystemRepresentation(const String& directoryName) 91 { 92 static dispatch_once_t onceToken; 93 static NSURL *tempURL; 94 95 dispatch_once(&onceToken, ^{ 96 NSURL *url = [NSURL fileURLWithPath:NSTemporaryDirectory()]; 97 if (!url) 98 RELEASE_ASSERT_NOT_REACHED(); 99 100 if (!WebKit::processHasContainer()) { 101 NSString *bundleIdentifier = [NSBundle mainBundle].bundleIdentifier; 102 if (!bundleIdentifier) 103 bundleIdentifier = [NSProcessInfo processInfo].processName; 104 url = [url URLByAppendingPathComponent:bundleIdentifier isDirectory:YES]; 105 } 106 107 tempURL = [[url URLByAppendingPathComponent:@"WebKit" isDirectory:YES] retain]; 108 }); 109 110 NSURL *url = [tempURL URLByAppendingPathComponent:directoryName isDirectory:YES]; 111 if (![[NSFileManager defaultManager] createDirectoryAtURL:url withIntermediateDirectories:YES attributes:nil error:nullptr]) 112 LOG_ERROR("Failed to create directory %@", url); 113 114 return url.absoluteURL.path.fileSystemRepresentation; 83 115 } 84 116 … … 145 177 configuration.applicationCacheDirectory = defaultApplicationCacheDirectory(); 146 178 configuration.networkCacheDirectory = defaultNetworkCacheDirectory(); 179 configuration.mediaCacheDirectory = defaultMediaCacheDirectory(); 147 180 148 181 configuration.webSQLDatabaseDirectory = defaultWebSQLDatabaseDirectory(); -
trunk/Source/WebKit2/UIProcess/Cocoa/WebProcessPoolCocoa.mm
r199321 r199326 65 65 NSString *WebKitJSCFTLJITEnabledDefaultsKey = @"WebKitJSCFTLJITEnabledDefaultsKey"; 66 66 NSString *WebKitMediaKeysStorageDirectoryDefaultsKey = @"WebKitMediaKeysStorageDirectory"; 67 NSString *WebKitMediaCacheDirectoryDefaultsKey = @"WebKitMediaCacheDirectory"; 67 68 68 69 #if !PLATFORM(IOS) … … 335 336 localStorageDirectory = @"~/Library/WebKit/LocalStorage"; 336 337 return stringByResolvingSymlinksInPath([localStorageDirectory stringByStandardizingPath]); 338 } 339 340 String WebProcessPool::legacyPlatformDefaultMediaCacheDirectory() 341 { 342 registerUserDefaultsIfNeeded(); 343 344 NSString *mediaKeysCacheDirectory = [[NSUserDefaults standardUserDefaults] objectForKey:WebKitMediaCacheDirectoryDefaultsKey]; 345 if (!mediaKeysCacheDirectory || ![mediaKeysCacheDirectory isKindOfClass:[NSString class]]) { 346 mediaKeysCacheDirectory = NSTemporaryDirectory(); 347 348 if (!WebKit::processHasContainer()) { 349 NSString *bundleIdentifier = [NSBundle mainBundle].bundleIdentifier; 350 if (!bundleIdentifier) 351 bundleIdentifier = [NSProcessInfo processInfo].processName; 352 mediaKeysCacheDirectory = [mediaKeysCacheDirectory stringByAppendingPathComponent:bundleIdentifier]; 353 } 354 mediaKeysCacheDirectory = [mediaKeysCacheDirectory stringByAppendingPathComponent:@"WebKit/MediaCache"]; 355 } 356 return stringByResolvingSymlinksInPath([mediaKeysCacheDirectory stringByStandardizingPath]); 337 357 } 338 358 -
trunk/Source/WebKit2/UIProcess/WebProcessPool.cpp
r199321 r199326 129 129 configuration.webSQLDatabaseDirectory = processPoolConfiguration.webSQLDatabaseDirectory(); 130 130 configuration.applicationCacheDirectory = processPoolConfiguration.applicationCacheDirectory(); 131 configuration.mediaCacheDirectory = processPoolConfiguration.mediaCacheDirectory(); 131 132 configuration.mediaKeysStorageDirectory = processPoolConfiguration.mediaKeysStorageDirectory(); 132 133 configuration.networkCacheDirectory = processPoolConfiguration.diskCacheDirectory(); … … 545 546 SandboxExtension::createHandleForReadWriteDirectory(parameters.webSQLDatabaseDirectory, parameters.webSQLDatabaseDirectoryExtensionHandle); 546 547 548 parameters.mediaCacheDirectory = m_configuration->mediaCacheDirectory(); 549 if (!parameters.mediaCacheDirectory.isEmpty()) 550 SandboxExtension::createHandleForReadWriteDirectory(parameters.mediaCacheDirectory, parameters.mediaCacheDirectoryExtensionHandle); 551 547 552 #if ENABLE(SECCOMP_FILTERS) 548 553 parameters.cookieStorageDirectory = this->cookieStorageDirectory(); -
trunk/Source/WebKit2/UIProcess/WebProcessPool.h
r199321 r199326 362 362 static String legacyPlatformDefaultWebSQLDatabaseDirectory(); 363 363 static String legacyPlatformDefaultMediaKeysStorageDirectory(); 364 static String legacyPlatformDefaultMediaCacheDirectory(); 364 365 static String legacyPlatformDefaultApplicationCacheDirectory(); 365 366 static String legacyPlatformDefaultNetworkCacheDirectory(); -
trunk/Source/WebKit2/UIProcess/WebsiteData/WebsiteDataStore.cpp
r199321 r199326 38 38 #include <WebCore/ApplicationCacheStorage.h> 39 39 #include <WebCore/DatabaseTracker.h> 40 #include <WebCore/HTMLMediaElement.h> 40 41 #include <WebCore/OriginLock.h> 41 42 #include <WebCore/SecurityOrigin.h> … … 78 79 , m_networkCacheDirectory(WTFMove(configuration.networkCacheDirectory)) 79 80 , m_applicationCacheDirectory(WTFMove(configuration.applicationCacheDirectory)) 81 , m_mediaCacheDirectory(WTFMove(configuration.mediaCacheDirectory)) 80 82 , m_webSQLDatabaseDirectory(WTFMove(configuration.webSQLDatabaseDirectory)) 81 83 , m_mediaKeysStorageDirectory(WTFMove(configuration.mediaKeysStorageDirectory)) … … 255 257 256 258 RefPtr<CallbackAggregator> callbackAggregator = adoptRef(new CallbackAggregator(fetchOptions, WTFMove(completionHandler))); 259 260 if (dataTypes.contains(WebsiteDataType::DiskCache)) { 261 StringCapture mediaCacheDirectory { m_mediaCacheDirectory }; 262 263 callbackAggregator->addPendingCallback(); 264 m_queue->dispatch([fetchOptions, mediaCacheDirectory, callbackAggregator] { 265 HashSet<RefPtr<WebCore::SecurityOrigin>> origins = WebCore::HTMLMediaElement::originsInMediaCache(mediaCacheDirectory.string()); 266 WebsiteData* websiteData = new WebsiteData; 267 268 for (auto& origin : origins) { 269 WebsiteData::Entry entry { origin, WebsiteDataType::DiskCache, 0 }; 270 websiteData->entries.append(WTFMove(entry)); 271 } 272 273 WTF::RunLoop::main().dispatch([callbackAggregator, origins, websiteData] { 274 callbackAggregator->removePendingCallback(WTFMove(*websiteData)); 275 276 delete websiteData; 277 }); 278 }); 279 } 257 280 258 281 auto networkProcessAccessType = computeNetworkProcessAccessTypeForDataFetch(dataTypes, !isPersistent()); … … 530 553 RefPtr<CallbackAggregator> callbackAggregator = adoptRef(new CallbackAggregator(WTFMove(completionHandler))); 531 554 555 if (dataTypes.contains(WebsiteDataType::DiskCache)) { 556 StringCapture mediaCacheDirectory { m_mediaCacheDirectory }; 557 558 callbackAggregator->addPendingCallback(); 559 m_queue->dispatch([modifiedSince, mediaCacheDirectory, callbackAggregator] { 560 WebCore::HTMLMediaElement::clearMediaCache(mediaCacheDirectory.string(), modifiedSince); 561 562 WTF::RunLoop::main().dispatch([callbackAggregator] { 563 callbackAggregator->removePendingCallback(); 564 }); 565 }); 566 } 567 532 568 auto networkProcessAccessType = computeNetworkProcessAccessTypeForDataRemoval(dataTypes, !isPersistent()); 533 569 if (networkProcessAccessType != ProcessAccessType::None) { … … 756 792 757 793 RefPtr<CallbackAggregator> callbackAggregator = adoptRef(new CallbackAggregator(WTFMove(completionHandler))); 758 794 795 if (dataTypes.contains(WebsiteDataType::DiskCache)) { 796 StringCapture mediaCacheDirectory { m_mediaCacheDirectory }; 797 HashSet<RefPtr<WebCore::SecurityOrigin>> origins; 798 for (const auto& dataRecord : dataRecords) { 799 for (const auto& origin : dataRecord.origins) 800 origins.add(origin); 801 } 802 803 callbackAggregator->addPendingCallback(); 804 m_queue->dispatch([origins, mediaCacheDirectory, callbackAggregator] { 805 WebCore::HTMLMediaElement::clearMediaCacheForOrigins(mediaCacheDirectory.string(), origins); 806 807 WTF::RunLoop::main().dispatch([callbackAggregator] { 808 callbackAggregator->removePendingCallback(); 809 }); 810 }); 811 } 812 759 813 auto networkProcessAccessType = computeNetworkProcessAccessTypeForDataRemoval(dataTypes, !isPersistent()); 760 814 if (networkProcessAccessType != ProcessAccessType::None) { -
trunk/Source/WebKit2/UIProcess/WebsiteData/WebsiteDataStore.h
r199321 r199326 62 62 String applicationCacheDirectory; 63 63 64 String mediaCacheDirectory; 64 65 String webSQLDatabaseDirectory; 65 66 String localStorageDirectory; … … 118 119 const String m_networkCacheDirectory; 119 120 const String m_applicationCacheDirectory; 121 const String m_mediaCacheDirectory; 120 122 121 123 const String m_webSQLDatabaseDirectory; -
trunk/Source/WebKit2/UIProcess/efl/WebProcessPoolEfl.cpp
r199321 r199326 88 88 } 89 89 90 String WebProcessPool::legacyPlatformDefaultMediaCacheDirectory() 91 { 92 return API::WebsiteDataStore::defaultMediaCacheDirectory(); 93 } 94 90 95 void WebProcessPool::platformInitializeWebProcess(WebProcessCreationParameters& parameters) 91 96 { -
trunk/Source/WebKit2/UIProcess/gtk/WebProcessPoolGtk.cpp
r199321 r199326 87 87 } 88 88 89 WTF::String WebProcessPool::legacyPlatformDefaultMediaCacheDirectory() 90 { 91 return API::WebsiteDataStore::defaultMediaCacheDirectory(); 92 } 93 89 94 void WebProcessPool::platformInitializeWebProcess(WebProcessCreationParameters& parameters) 90 95 { -
trunk/Source/WebKit2/WebProcess/WebProcess.cpp
r199321 r199326 78 78 #include <WebCore/GCController.h> 79 79 #include <WebCore/GlyphPage.h> 80 #include <WebCore/HTMLMediaElement.h> 80 81 #include <WebCore/IconDatabase.h> 81 82 #include <WebCore/JSDOMWindow.h> … … 294 295 ApplicationCacheStorage::singleton().setCacheDirectory(parameters.applicationCacheDirectory); 295 296 297 if (!parameters.mediaCacheDirectory.isEmpty()) 298 WebCore::HTMLMediaElement::setMediaCacheDirectory(parameters.mediaCacheDirectory); 299 296 300 setCacheModel(static_cast<uint32_t>(parameters.cacheModel)); 297 301 -
trunk/Source/WebKit2/WebProcess/cocoa/WebProcessCocoa.mm
r199321 r199326 136 136 SandboxExtension::consumePermanently(parameters.webSQLDatabaseDirectoryExtensionHandle); 137 137 SandboxExtension::consumePermanently(parameters.applicationCacheDirectoryExtensionHandle); 138 SandboxExtension::consumePermanently(parameters.mediaCacheDirectoryExtensionHandle); 138 139 SandboxExtension::consumePermanently(parameters.mediaKeyStorageDirectoryExtensionHandle); 139 140 #if PLATFORM(IOS)
Note: See TracChangeset
for help on using the changeset viewer.