<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[283592] trunk/Source</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/283592">283592</a></dd>
<dt>Author</dt> <dd>akeerthi@apple.com</dd>
<dt>Date</dt> <dd>2021-10-05 17:42:35 -0700 (Tue, 05 Oct 2021)</dd>
</dl>

<h3>Log Message</h3>
<pre>[iOS] Transcode videos selected from UIImagePickerController
https://bugs.webkit.org/show_bug.cgi?id=230639
rdar://79665678

Reviewed by Tim Horton.

Source/WebCore:

* en.lproj/Localizable.strings:

Add a localizable string for the message displayed while transcoding
video.

Source/WebCore/PAL:

Add AVFoundation API needed to transcode video.

* pal/cocoa/AVFoundationSoftLink.h:
* pal/cocoa/AVFoundationSoftLink.mm:

Source/WebKit:

File inputs on iOS allow users to choose images/videos from the system
photo picker, using UIImagePickerController. In single selection mode,
UIImagePickerController transcodes the selected video to H.264. However,
in multiple selection mode, video is not transcoded and is left in its
original format.

Today, videos on most iOS devices are encoded with HEVC by default.
However, some sites, such as Twitter, only accept H.264 encoded video.
Thus, the current video upload behavior is problematic, as users may be
unable to upload video.

Unfortunately, the photo picking functionality of UIImagePickerController
is deprecated. The best solution would be to adopt PHPickerViewController,
the replacement API, which performs transcoding when retrieving selected
items (regardless of single/multiple selection). However,
PHPickerViewController currently lacks other functionality that WebKit
requires, preventing adoption.

Consequently, the short term solution is to transcode the videos in
WebKit, ensuring H.264 encoded video is always provided to sites. See
below for implementation details.

* Platform/spi/ios/PhotosUISPI.h: Added.
* UIProcess/ios/forms/WKFileUploadPanel.mm:
(-[_WKFileUploadItem setFileURL:]):

Add a setter to update the file URL. Called after transcoding a _WKFileUploadItem.

(-[WKFileUploadMediaTranscoder initWithItems:videoCount:completionHandler:]):

Introduce WKFileUploadMediaTranscoder to manage transcoding of videos
and the display of progress UI. Transcoding is performed serially
(one video at a time), but occurs off the main thread.

(-[WKFileUploadMediaTranscoder start]):

Begin transcoding. Run a timer to update the progress UI, as
AVAssetExportSession does not provide progress updates on its own.

The progress UI is implemented using PUActivityProgressController, to
match system Photos UI.

(-[WKFileUploadMediaTranscoder _processItemAtIndex:]):

Transcode a single video, using AVAssetExportSession. If transcoding
fails for any reason, the original video is used as a fallback.
Transcoding can also be cancelled using the progress UI, in which case
no more videos are processed.

(-[WKFileUploadMediaTranscoder _finishedProcessing]):
(-[WKFileUploadMediaTranscoder _dismissProgress]):
(-[WKFileUploadMediaTranscoder _updateProgress:]):
(-[WKFileUploadMediaTranscoder _temporaryDirectoryCreateIfNecessary]):
(-[WKFileUploadPanel _chooseMediaItems:]):

Refactor the common aspects of single/multiple media selection into a
single method.

(-[WKFileUploadPanel imagePickerController:didFinishPickingMediaWithInfo:]):
(-[WKFileUploadPanel imagePickerController:didFinishPickingMultipleMediaWithInfo:]):
(-[WKFileUploadPanel _processMediaInfoDictionaries:successBlock:failureBlock:]):
(-[WKFileUploadPanel _processMediaInfoDictionaries:atIndex:processedResults:successBlock:failureBlock:]):
(-[WKFileUploadPanel _uploadItemFromMediaInfo:successBlock:failureBlock:]):

Remove redundant platform conditional.

(-[WKFileUploadPanel _uploadMediaItemsTranscodingVideo:]):

If any videos were selected, transcode them prior to uploading.

* WebKit.xcodeproj/project.pbxproj:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCorePALChangeLog">trunk/Source/WebCore/PAL/ChangeLog</a></li>
<li><a href="#trunkSourceWebCorePALpalcocoaAVFoundationSoftLinkh">trunk/Source/WebCore/PAL/pal/cocoa/AVFoundationSoftLink.h</a></li>
<li><a href="#trunkSourceWebCorePALpalcocoaAVFoundationSoftLinkmm">trunk/Source/WebCore/PAL/pal/cocoa/AVFoundationSoftLink.mm</a></li>
<li><a href="#trunkSourceWebCoreenlprojLocalizablestrings">trunk/Source/WebCore/en.lproj/Localizable.strings</a></li>
<li><a href="#trunkSourceWebKitChangeLog">trunk/Source/WebKit/ChangeLog</a></li>
<li><a href="#trunkSourceWebKitUIProcessiosformsWKFileUploadPanelmm">trunk/Source/WebKit/UIProcess/ios/forms/WKFileUploadPanel.mm</a></li>
<li><a href="#trunkSourceWebKitWebKitxcodeprojprojectpbxproj">trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceWebKitPlatformspiiosPhotosUISPIh">trunk/Source/WebKit/Platform/spi/ios/PhotosUISPI.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (283591 => 283592)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog   2021-10-06 00:20:55 UTC (rev 283591)
+++ trunk/Source/WebCore/ChangeLog      2021-10-06 00:42:35 UTC (rev 283592)
</span><span class="lines">@@ -1,3 +1,16 @@
</span><ins>+2021-10-05  Aditya Keerthi  <akeerthi@apple.com>
+
+        [iOS] Transcode videos selected from UIImagePickerController
+        https://bugs.webkit.org/show_bug.cgi?id=230639
+        rdar://79665678
+
+        Reviewed by Tim Horton.
+
+        * en.lproj/Localizable.strings:
+
+        Add a localizable string for the message displayed while transcoding
+        video.
+
</ins><span class="cx"> 2021-10-05  Chris Dumez  <cdumez@apple.com>
</span><span class="cx"> 
</span><span class="cx">         ASSERT(m_callback->hasCallback()) under IntersectionObserver::notify()
</span></span></pre></div>
<a id="trunkSourceWebCorePALChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/PAL/ChangeLog (283591 => 283592)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/PAL/ChangeLog       2021-10-06 00:20:55 UTC (rev 283591)
+++ trunk/Source/WebCore/PAL/ChangeLog  2021-10-06 00:42:35 UTC (rev 283592)
</span><span class="lines">@@ -1,3 +1,16 @@
</span><ins>+2021-10-05  Aditya Keerthi  <akeerthi@apple.com>
+
+        [iOS] Transcode videos selected from UIImagePickerController
+        https://bugs.webkit.org/show_bug.cgi?id=230639
+        rdar://79665678
+
+        Reviewed by Tim Horton.
+
+        Add AVFoundation API needed to transcode video.
+
+        * pal/cocoa/AVFoundationSoftLink.h:
+        * pal/cocoa/AVFoundationSoftLink.mm:
+
</ins><span class="cx"> 2021-10-05  Ayumi Kojima  <ayumi_kojima@apple.com>
</span><span class="cx"> 
</span><span class="cx">         Unreviewed, reverting r283339.
</span></span></pre></div>
<a id="trunkSourceWebCorePALpalcocoaAVFoundationSoftLinkh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/PAL/pal/cocoa/AVFoundationSoftLink.h (283591 => 283592)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/PAL/pal/cocoa/AVFoundationSoftLink.h        2021-10-06 00:20:55 UTC (rev 283591)
+++ trunk/Source/WebCore/PAL/pal/cocoa/AVFoundationSoftLink.h   2021-10-06 00:42:35 UTC (rev 283592)
</span><span class="lines">@@ -38,6 +38,7 @@
</span><span class="cx"> 
</span><span class="cx"> SOFT_LINK_CLASS_FOR_HEADER(PAL, AVAssetCache)
</span><span class="cx"> SOFT_LINK_CLASS_FOR_HEADER(PAL, AVAssetCollection)
</span><ins>+SOFT_LINK_CLASS_FOR_HEADER(PAL, AVAssetExportSession)
</ins><span class="cx"> SOFT_LINK_CLASS_FOR_HEADER(PAL, AVAssetImageGenerator)
</span><span class="cx"> SOFT_LINK_CLASS_FOR_HEADER(PAL, AVAssetReader)
</span><span class="cx"> SOFT_LINK_CLASS_FOR_HEADER(PAL, AVAssetReaderSampleReferenceOutput)
</span><span class="lines">@@ -190,6 +191,8 @@
</span><span class="cx"> #define AVVideoCodecTypeHEVCWithAlpha PAL::get_AVFoundation_AVVideoCodecTypeHEVCWithAlpha()
</span><span class="cx"> SOFT_LINK_CONSTANT_FOR_HEADER(PAL, AVFoundation, AVFileTypeMPEG4, NSString *)
</span><span class="cx"> #define AVFileTypeMPEG4 PAL::get_AVFoundation_AVFileTypeMPEG4()
</span><ins>+SOFT_LINK_CONSTANT_FOR_HEADER(PAL, AVFoundation, AVFileTypeQuickTimeMovie, NSString *)
+#define AVFileTypeQuickTimeMovie PAL::get_AVFoundation_AVFileTypeQuickTimeMovie()
</ins><span class="cx"> SOFT_LINK_CONSTANT_FOR_HEADER(PAL, AVFoundation, AVVideoCodecKey, NSString *)
</span><span class="cx"> #define AVVideoCodecKey PAL::get_AVFoundation_AVVideoCodecKey()
</span><span class="cx"> SOFT_LINK_CONSTANT_FOR_HEADER(PAL, AVFoundation, AVVideoCodecH264, NSString *)
</span><span class="lines">@@ -336,4 +339,7 @@
</span><span class="cx"> SOFT_LINK_CLASS_FOR_HEADER(PAL, AVAudioPCMBuffer)
</span><span class="cx"> #endif // PLATFORM(COCOA)
</span><span class="cx"> 
</span><ins>+SOFT_LINK_CONSTANT_FOR_HEADER(PAL, AVFoundation, AVAssetExportPresetHighestQuality, NSString *)
+#define AVAssetExportPresetHighestQuality PAL::get_AVFoundation_AVAssetExportPresetHighestQuality()
+
</ins><span class="cx"> #endif // USE(AVFOUNDATION)
</span></span></pre></div>
<a id="trunkSourceWebCorePALpalcocoaAVFoundationSoftLinkmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/PAL/pal/cocoa/AVFoundationSoftLink.mm (283591 => 283592)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/PAL/pal/cocoa/AVFoundationSoftLink.mm       2021-10-06 00:20:55 UTC (rev 283591)
+++ trunk/Source/WebCore/PAL/pal/cocoa/AVFoundationSoftLink.mm  2021-10-06 00:42:35 UTC (rev 283592)
</span><span class="lines">@@ -63,6 +63,7 @@
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx"> SOFT_LINK_CLASS_FOR_SOURCE_WITH_EXPORT(PAL, AVFoundation, AVAssetCache, PAL_EXPORT)
</span><ins>+SOFT_LINK_CLASS_FOR_SOURCE_WITH_EXPORT(PAL, AVFoundation, AVAssetExportSession, PAL_EXPORT)
</ins><span class="cx"> SOFT_LINK_CLASS_FOR_SOURCE_WITH_EXPORT(PAL, AVFoundation, AVAssetImageGenerator, PAL_EXPORT)
</span><span class="cx"> SOFT_LINK_CLASS_FOR_SOURCE_WITH_EXPORT(PAL, AVFoundation, AVAssetReader, PAL_EXPORT)
</span><span class="cx"> SOFT_LINK_CLASS_FOR_SOURCE_WITH_EXPORT(PAL, AVFoundation, AVAssetWriter, PAL_EXPORT)
</span><span class="lines">@@ -133,6 +134,7 @@
</span><span class="cx"> SOFT_LINK_CONSTANT_FOR_SOURCE_WITH_EXPORT(PAL, AVFoundation, AVCaptureDeviceWasConnectedNotification, NSString *, PAL_EXPORT)
</span><span class="cx"> SOFT_LINK_CONSTANT_FOR_SOURCE_WITH_EXPORT(PAL, AVFoundation, AVCaptureDeviceWasDisconnectedNotification, NSString *, PAL_EXPORT)
</span><span class="cx"> SOFT_LINK_CONSTANT_FOR_SOURCE_WITH_EXPORT(PAL, AVFoundation, AVFileTypeMPEG4, NSString *, PAL_EXPORT)
</span><ins>+SOFT_LINK_CONSTANT_FOR_SOURCE_WITH_EXPORT(PAL, AVFoundation, AVFileTypeQuickTimeMovie, NSString *, PAL_EXPORT)
</ins><span class="cx"> SOFT_LINK_CONSTANT_FOR_SOURCE_WITH_EXPORT(PAL, AVFoundation, AVLayerVideoGravityResize, NSString *, PAL_EXPORT)
</span><span class="cx"> SOFT_LINK_CONSTANT_FOR_SOURCE_WITH_EXPORT(PAL, AVFoundation, AVLayerVideoGravityResizeAspect, NSString *, PAL_EXPORT)
</span><span class="cx"> SOFT_LINK_CONSTANT_FOR_SOURCE_WITH_EXPORT(PAL, AVFoundation, AVLayerVideoGravityResizeAspectFill, NSString *, PAL_EXPORT)
</span><span class="lines">@@ -253,4 +255,6 @@
</span><span class="cx"> SOFT_LINK_CLASS_FOR_SOURCE_WITH_EXPORT(PAL, AVFoundation, AVAudioPCMBuffer, PAL_EXPORT)
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+SOFT_LINK_CONSTANT_FOR_SOURCE_WITH_EXPORT(PAL, AVFoundation, AVAssetExportPresetHighestQuality, NSString *, PAL_EXPORT)
+
</ins><span class="cx"> #endif // USE(AVFOUNDATION)
</span></span></pre></div>
<a id="trunkSourceWebCoreenlprojLocalizablestrings"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/en.lproj/Localizable.strings (283591 => 283592)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/en.lproj/Localizable.strings        2021-10-06 00:20:55 UTC (rev 283591)
+++ trunk/Source/WebCore/en.lproj/Localizable.strings   2021-10-06 00:42:35 UTC (rev 283592)
</span><span class="lines">@@ -754,6 +754,9 @@
</span><span class="cx"> /* Description of the PostScript type supported by the PDF pseudo plug-in. Visible in the Installed Plug-ins page in Safari. */
</span><span class="cx"> "PostScript" = "PostScript";
</span><span class="cx"> 
</span><ins>+/* Title for file upload progress view */
+"Preparing (file upload)" = "Preparing…";
+
</ins><span class="cx"> /* Title for Quick Look action button */
</span><span class="cx"> "Quick Look" = "Quick Look";
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebKitChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/ChangeLog (283591 => 283592)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/ChangeLog    2021-10-06 00:20:55 UTC (rev 283591)
+++ trunk/Source/WebKit/ChangeLog       2021-10-06 00:42:35 UTC (rev 283592)
</span><span class="lines">@@ -1,3 +1,83 @@
</span><ins>+2021-10-05  Aditya Keerthi  <akeerthi@apple.com>
+
+        [iOS] Transcode videos selected from UIImagePickerController
+        https://bugs.webkit.org/show_bug.cgi?id=230639
+        rdar://79665678
+
+        Reviewed by Tim Horton.
+
+        File inputs on iOS allow users to choose images/videos from the system
+        photo picker, using UIImagePickerController. In single selection mode,
+        UIImagePickerController transcodes the selected video to H.264. However,
+        in multiple selection mode, video is not transcoded and is left in its
+        original format.
+
+        Today, videos on most iOS devices are encoded with HEVC by default.
+        However, some sites, such as Twitter, only accept H.264 encoded video.
+        Thus, the current video upload behavior is problematic, as users may be
+        unable to upload video.
+
+        Unfortunately, the photo picking functionality of UIImagePickerController
+        is deprecated. The best solution would be to adopt PHPickerViewController,
+        the replacement API, which performs transcoding when retrieving selected
+        items (regardless of single/multiple selection). However,
+        PHPickerViewController currently lacks other functionality that WebKit
+        requires, preventing adoption.
+
+        Consequently, the short term solution is to transcode the videos in
+        WebKit, ensuring H.264 encoded video is always provided to sites. See
+        below for implementation details.
+
+        * Platform/spi/ios/PhotosUISPI.h: Added.
+        * UIProcess/ios/forms/WKFileUploadPanel.mm:
+        (-[_WKFileUploadItem setFileURL:]):
+
+        Add a setter to update the file URL. Called after transcoding a _WKFileUploadItem.
+
+        (-[WKFileUploadMediaTranscoder initWithItems:videoCount:completionHandler:]):
+
+        Introduce WKFileUploadMediaTranscoder to manage transcoding of videos
+        and the display of progress UI. Transcoding is performed serially
+        (one video at a time), but occurs off the main thread.
+
+        (-[WKFileUploadMediaTranscoder start]):
+
+        Begin transcoding. Run a timer to update the progress UI, as
+        AVAssetExportSession does not provide progress updates on its own.
+
+        The progress UI is implemented using PUActivityProgressController, to
+        match system Photos UI.
+
+        (-[WKFileUploadMediaTranscoder _processItemAtIndex:]):
+
+        Transcode a single video, using AVAssetExportSession. If transcoding
+        fails for any reason, the original video is used as a fallback.
+        Transcoding can also be cancelled using the progress UI, in which case
+        no more videos are processed.
+
+        (-[WKFileUploadMediaTranscoder _finishedProcessing]):
+        (-[WKFileUploadMediaTranscoder _dismissProgress]):
+        (-[WKFileUploadMediaTranscoder _updateProgress:]):
+        (-[WKFileUploadMediaTranscoder _temporaryDirectoryCreateIfNecessary]):
+        (-[WKFileUploadPanel _chooseMediaItems:]):
+
+        Refactor the common aspects of single/multiple media selection into a
+        single method.
+
+        (-[WKFileUploadPanel imagePickerController:didFinishPickingMediaWithInfo:]):
+        (-[WKFileUploadPanel imagePickerController:didFinishPickingMultipleMediaWithInfo:]):
+        (-[WKFileUploadPanel _processMediaInfoDictionaries:successBlock:failureBlock:]):
+        (-[WKFileUploadPanel _processMediaInfoDictionaries:atIndex:processedResults:successBlock:failureBlock:]):
+        (-[WKFileUploadPanel _uploadItemFromMediaInfo:successBlock:failureBlock:]):
+
+        Remove redundant platform conditional.
+
+        (-[WKFileUploadPanel _uploadMediaItemsTranscodingVideo:]):
+
+        If any videos were selected, transcode them prior to uploading.
+
+        * WebKit.xcodeproj/project.pbxproj:
+
</ins><span class="cx"> 2021-10-05  Alex Christensen  <achristensen@webkit.org>
</span><span class="cx"> 
</span><span class="cx">         Add an entitlement check to only allow AdAttributionDaemon to be connected to by the network process
</span></span></pre></div>
<a id="trunkSourceWebKitPlatformspiiosPhotosUISPIh"></a>
<div class="addfile"><h4>Added: trunk/Source/WebKit/Platform/spi/ios/PhotosUISPI.h (0 => 283592)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/Platform/spi/ios/PhotosUISPI.h                               (rev 0)
+++ trunk/Source/WebKit/Platform/spi/ios/PhotosUISPI.h  2021-10-06 00:42:35 UTC (rev 283592)
</span><span class="lines">@@ -0,0 +1,49 @@
</span><ins>+/*
+ * Copyright (C) 2021 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#if USE(APPLE_INTERNAL_SDK)
+
+#import <PhotosUI/PUActivityProgressController.h>
+
+#else
+
+#import "UIKitSPI.h"
+
+@interface PUActivityProgressController : NSObject
+
+@property (nonatomic, copy) NSString *title;
+
+@property (nonatomic, copy) void (^cancellationHandler)(void);
+
+@property (nonatomic, readonly) BOOL isCancelled;
+
+- (void)setFractionCompleted:(double)fractionCompleted;
+
+- (void)showAnimated:(BOOL)animated allowDelay:(BOOL)allowDelay;
+- (void)hideAnimated:(BOOL)animated allowDelay:(BOOL)allowDelay;
+
+@end
+
+#endif // USE(APPLE_INTERNAL_SDK)
</ins></span></pre></div>
<a id="trunkSourceWebKitUIProcessiosformsWKFileUploadPanelmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/UIProcess/ios/forms/WKFileUploadPanel.mm (283591 => 283592)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/UIProcess/ios/forms/WKFileUploadPanel.mm     2021-10-06 00:20:55 UTC (rev 283591)
+++ trunk/Source/WebKit/UIProcess/ios/forms/WKFileUploadPanel.mm        2021-10-06 00:42:35 UTC (rev 283592)
</span><span class="lines">@@ -32,6 +32,7 @@
</span><span class="cx"> #import "APIData.h"
</span><span class="cx"> #import "APIOpenPanelParameters.h"
</span><span class="cx"> #import "APIString.h"
</span><ins>+#import "PhotosUISPI.h"
</ins><span class="cx"> #import "UIKitSPI.h"
</span><span class="cx"> #import "UserInterfaceIdiom.h"
</span><span class="cx"> #import "WKContentViewInteraction.h"
</span><span class="lines">@@ -45,11 +46,17 @@
</span><span class="cx"> #import <UniformTypeIdentifiers/UniformTypeIdentifiers.h>
</span><span class="cx"> #import <WebCore/LocalizedStrings.h>
</span><span class="cx"> #import <WebCore/MIMETypeRegistry.h>
</span><ins>+#import <wtf/MainThread.h>
</ins><span class="cx"> #import <wtf/OptionSet.h>
</span><span class="cx"> #import <wtf/RetainPtr.h>
</span><span class="cx"> #import <wtf/WeakObjCPtr.h>
</span><span class="cx"> #import <wtf/text/StringView.h>
</span><span class="cx"> 
</span><ins>+#import <pal/cocoa/AVFoundationSoftLink.h>
+
+SOFT_LINK_FRAMEWORK(PhotosUI)
+SOFT_LINK_CLASS(PhotosUI, PUActivityProgressController)
+
</ins><span class="cx"> using namespace WebKit;
</span><span class="cx"> 
</span><span class="cx"> enum class WKFileUploadPanelImagePickerType : uint8_t {
</span><span class="lines">@@ -79,7 +86,6 @@
</span><span class="cx"> @interface _WKFileUploadItem : NSObject
</span><span class="cx"> - (instancetype)initWithFileURL:(NSURL *)fileURL;
</span><span class="cx"> @property (nonatomic, readonly, getter=isVideo) BOOL video;
</span><del>-@property (nonatomic, readonly) NSURL *fileURL;
</del><span class="cx"> @property (nonatomic, readonly) RetainPtr<UIImage> displayImage;
</span><span class="cx"> @end
</span><span class="cx"> 
</span><span class="lines">@@ -109,6 +115,11 @@
</span><span class="cx">     return _fileURL.get();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+- (void)setFileURL:(NSURL *)fileURL
+{
+    _fileURL = fileURL;
+}
+
</ins><span class="cx"> - (RetainPtr<UIImage>)displayImage
</span><span class="cx"> {
</span><span class="cx">     ASSERT_NOT_REACHED();
</span><span class="lines">@@ -153,10 +164,165 @@
</span><span class="cx"> 
</span><span class="cx"> @end
</span><span class="cx"> 
</span><ins>+#pragma mark - WKFileUploadMediaTranscoder
</ins><span class="cx"> 
</span><ins>+@interface WKFileUploadMediaTranscoder : NSObject
+
+- (instancetype)initWithItems:(NSArray *)items videoCount:(NSUInteger)videoCount completionHandler:(WTF::Function<void(NSArray<_WKFileUploadItem *> *)>&&)completionHandler;
+
+- (void)start;
+
+@end
+
+@implementation WKFileUploadMediaTranscoder {
+    RetainPtr<NSTimer> _progressTimer;
+    RetainPtr<PUActivityProgressController> _progressController;
+    RetainPtr<AVAssetExportSession> _exportSession;
+    RetainPtr<NSArray<_WKFileUploadItem *>> _items;
+    RetainPtr<NSString> _temporaryDirectoryPath;
+
+    // Only called if the transcoding is not cancelled.
+    WTF::Function<void(NSArray<_WKFileUploadItem *> *)> _completionHandler;
+
+    NSUInteger _videoCount;
+    NSUInteger _processedVideoCount;
+}
+
+- (instancetype)initWithItems:(NSArray<_WKFileUploadItem *> *)items videoCount:(NSUInteger)videoCount completionHandler:(WTF::Function<void(NSArray<_WKFileUploadItem *> *)>&&)completionHandler
+{
+    if (!(self = [super init]))
+        return nil;
+
+    _items = items;
+    _processedVideoCount = 0;
+    _videoCount = videoCount;
+
+    _completionHandler = WTFMove(completionHandler);
+
+    return self;
+}
+
+- (void)start
+{
+    _progressController = adoptNS([allocPUActivityProgressControllerInstance() init]);
+    [_progressController setTitle:WEB_UI_STRING_KEY("Preparing…", "Preparing (file upload)", "Title for file upload progress view")];
+    [_progressController showAnimated:YES allowDelay:YES];
+
+    [_progressController setCancellationHandler:makeBlockPtr([weakSelf = WeakObjCPtr<WKFileUploadMediaTranscoder>(self)] {
+        auto strongSelf = weakSelf.get();
+        if (!strongSelf)
+            return;
+
+        [strongSelf->_exportSession cancelExport];
+        [strongSelf _dismissProgress];
+    }).get()];
+
+    _progressTimer = [NSTimer scheduledTimerWithTimeInterval:0.1f target:self selector:@selector(_updateProgress:) userInfo:nil repeats:YES];
+
+    [self _processItemAtIndex:0];
+}
+
+- (void)_processItemAtIndex:(NSUInteger)index
+{
+    if ([_progressController isCancelled])
+        return;
+
+    if (index >= [_items count]) {
+        [self _finishedProcessing];
+        return;
+    }
+
+    _WKFileUploadItem *item = [_items objectAtIndex:index];
+
+    while (!item.isVideo) {
+        index++;
+
+        if (index == [_items count]) {
+            [self _finishedProcessing];
+            return;
+        }
+
+        item = [_items objectAtIndex:index];
+    }
+
+    NSString *temporaryDirectory = [self _temporaryDirectoryCreateIfNecessary];
+    if (!temporaryDirectory) {
+        LOG_ERROR("WKFileUploadMediaTranscoder: Failed to make temporary directory");
+        [self _finishedProcessing];
+        return;
+    }
+
+    NSString *fileName = [item.fileURL.lastPathComponent.stringByDeletingPathExtension stringByAppendingPathExtension:UTTypeQuickTimeMovie.preferredFilenameExtension.uppercaseString];
+    NSString *filePath = [temporaryDirectory stringByAppendingPathComponent:fileName];
+    NSURL *outputURL = [NSURL fileURLWithPath:filePath isDirectory:NO];
+
+    RetainPtr<AVURLAsset> asset = adoptNS([PAL::allocAVURLAssetInstance() initWithURL:item.fileURL options:nil]);
+    _exportSession = adoptNS([PAL::allocAVAssetExportSessionInstance() initWithAsset:asset.get() presetName:AVAssetExportPresetHighestQuality]);
+    [_exportSession setOutputURL:outputURL];
+    [_exportSession setOutputFileType:AVFileTypeQuickTimeMovie];
+
+    [_exportSession exportAsynchronouslyWithCompletionHandler:makeBlockPtr([weakSelf = WeakObjCPtr<WKFileUploadMediaTranscoder>(self), index] () mutable {
+        ensureOnMainRunLoop([weakSelf = WTFMove(weakSelf), index] {
+            auto strongSelf = weakSelf.get();
+            if (!strongSelf)
+                return;
+
+            AVAssetExportSessionStatus status = [strongSelf->_exportSession status];
+
+            if (status == AVAssetExportSessionStatusCancelled)
+                return;
+
+            if (status == AVAssetExportSessionStatusCompleted) {
+                _WKFileUploadItem *item = [strongSelf->_items objectAtIndex:index];
+                [item setFileURL:[strongSelf->_exportSession outputURL]];
+            }
+
+            strongSelf->_exportSession = nil;
+
+            strongSelf->_processedVideoCount++;
+            [strongSelf _processItemAtIndex:index + 1];
+        });
+    }).get()];
+}
+
+- (void)_finishedProcessing
+{
+    [self _dismissProgress];
+
+    if (auto completionHandler = std::exchange(_completionHandler, nullptr))
+        completionHandler(_items.get());
+}
+
+- (void)_dismissProgress
+{
+    [_progressTimer invalidate];
+    [_progressController hideAnimated:NO allowDelay:NO];
+}
+
+- (void)_updateProgress:(NSTimer *)timer
+{
+    auto currentSessionProgress = [_exportSession progress];
+    [_progressController setFractionCompleted:(currentSessionProgress + _processedVideoCount) / _videoCount];
+}
+
+- (NSString *)_temporaryDirectoryCreateIfNecessary
+{
+    if (_temporaryDirectoryPath) {
+        BOOL isDirectory = NO;
+        BOOL exists = [[NSFileManager defaultManager] fileExistsAtPath:_temporaryDirectoryPath.get() isDirectory:&isDirectory];
+
+        if (exists && isDirectory)
+            return _temporaryDirectoryPath.get();
+    }
+
+    _temporaryDirectoryPath = FileSystem::createTemporaryDirectory(@"WKVideoUpload");
+    return _temporaryDirectoryPath.get();
+}
+
+@end
+
</ins><span class="cx"> #pragma mark - WKFileUploadPanel
</span><span class="cx"> 
</span><del>-
</del><span class="cx"> @interface WKFileUploadPanel () <UIPopoverControllerDelegate, UINavigationControllerDelegate, UIImagePickerControllerDelegate, UIDocumentPickerDelegate, UIAdaptivePresentationControllerDelegate
</span><span class="cx"> #if USE(UICONTEXTMENU)
</span><span class="cx"> , UIContextMenuInteractionDelegate
</span><span class="lines">@@ -172,6 +338,7 @@
</span><span class="cx">     CGPoint _interactionPoint;
</span><span class="cx">     BOOL _allowMultipleFiles;
</span><span class="cx">     BOOL _usingCamera;
</span><ins>+    RetainPtr<WKFileUploadMediaTranscoder> _mediaTranscoder;
</ins><span class="cx">     RetainPtr<UIImagePickerController> _imagePicker;
</span><span class="cx">     RetainPtr<UIViewController> _presentationViewController; // iPhone always. iPad for Fullscreen Camera.
</span><span class="cx">     ALLOW_DEPRECATED_DECLARATIONS_BEGIN
</span><span class="lines">@@ -220,6 +387,30 @@
</span><span class="cx">     [self _dispatchDidDismiss];
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+- (void)_chooseMediaItems:(NSArray<_WKFileUploadItem *> *)mediaItems
+{
+    RetainPtr<UIImage> iconImage = nil;
+    NSMutableArray *fileURLs = [NSMutableArray array];
+    NSUInteger videoCount = 0;
+
+    for (_WKFileUploadItem *item in mediaItems) {
+        [fileURLs addObject:item.fileURL];
+
+        if (!iconImage)
+            iconImage = item.displayImage;
+
+        if (item.isVideo)
+            videoCount++;
+    }
+
+    NSUInteger imageCount = mediaItems.count - videoCount;
+
+    NSString *displayString = (imageCount || videoCount) ? [NSString localizedStringWithFormat:WEB_UI_NSSTRING(@"%lu photo(s) and %lu video(s)", "label next to file upload control; parameters are the number of photos and the number of videos"), (unsigned long)imageCount, (unsigned long)videoCount] : nil;
+
+    [self _dismissDisplayAnimated:YES];
+    [self _chooseFiles:fileURLs displayString:displayString iconImage:iconImage.get()];
+}
+
</ins><span class="cx"> - (void)_chooseFiles:(NSArray *)fileURLs displayString:(NSString *)displayString iconImage:(UIImage *)iconImage
</span><span class="cx"> {
</span><span class="cx">     NSUInteger count = [fileURLs count];
</span><span class="lines">@@ -729,18 +920,16 @@
</span><span class="cx">     if ([self _willMultipleSelectionDelegateBeCalled])
</span><span class="cx">         return;
</span><span class="cx"> 
</span><del>-    [self _dismissDisplayAnimated:YES];
-
</del><span class="cx">     [self _processMediaInfoDictionaries:@[info]
</span><del>-        successBlock:^(NSArray *processedResults, NSString *displayString) {
-            ASSERT([processedResults count] == 1);
-            _WKFileUploadItem *result = [processedResults objectAtIndex:0];
-            RunLoop::main().dispatch([self, strongSelf = retainPtr(self), result = retainPtr(result), displayString = retainPtr(displayString)] {
-                [self _chooseFiles:@[result.get().fileURL] displayString:displayString.get() iconImage:result.get().displayImage.get()];
</del><ins>+        successBlock:^(NSArray<_WKFileUploadItem *> *items) {
+            ASSERT([items count] == 1);
+            ensureOnMainRunLoop([self, strongSelf = retainPtr(self), items = retainPtr(items)] {
+                [self _chooseMediaItems:items.get()];
</ins><span class="cx">             });
</span><span class="cx">         }
</span><span class="cx">         failureBlock:^{
</span><del>-            RunLoop::main().dispatch([self, strongSelf = retainPtr(self)] {
</del><ins>+            ensureOnMainRunLoop([self, strongSelf = retainPtr(self)] {
+                [self _dismissDisplayAnimated:YES];
</ins><span class="cx">                 [self _cancel];
</span><span class="cx">             });
</span><span class="cx">         }
</span><span class="lines">@@ -749,27 +938,13 @@
</span><span class="cx"> 
</span><span class="cx"> - (void)imagePickerController:(UIImagePickerController *)imagePicker didFinishPickingMultipleMediaWithInfo:(NSArray *)infos
</span><span class="cx"> {
</span><del>-    [self _dismissDisplayAnimated:YES];
-
</del><span class="cx">     [self _processMediaInfoDictionaries:infos
</span><del>-        successBlock:^(NSArray *processedResults, NSString *displayString) {
-            RetainPtr<UIImage> iconImage = nil;
-            NSMutableArray *fileURLs = [NSMutableArray array];
-            for (_WKFileUploadItem *result in processedResults) {
-                NSURL *fileURL = result.fileURL;
-                if (!fileURL)
-                    continue;
-                [fileURLs addObject:result.fileURL];
-                if (!iconImage)
-                    iconImage = result.displayImage;
-            }
-
-            RunLoop::main().dispatch([self, strongSelf = retainPtr(self), fileURLs = retainPtr(fileURLs), displayString = retainPtr(displayString), iconImage] {
-                [self _chooseFiles:fileURLs.get() displayString:displayString.get() iconImage:iconImage.get()];
-            });
</del><ins>+        successBlock:^(NSArray<_WKFileUploadItem *> *items) {
+            [self _uploadMediaItemsTranscodingVideo:items];
</ins><span class="cx">         }
</span><span class="cx">         failureBlock:^{
</span><del>-            RunLoop::main().dispatch([self, strongSelf = retainPtr(self)] {
</del><ins>+            ensureOnMainRunLoop([self, strongSelf = retainPtr(self)] {
+                [self _dismissDisplayAnimated:YES];
</ins><span class="cx">                 [self _cancel];
</span><span class="cx">             });
</span><span class="cx">         }
</span><span class="lines">@@ -784,17 +959,16 @@
</span><span class="cx"> 
</span><span class="cx"> #pragma mark - Process UIImagePicker results
</span><span class="cx"> 
</span><del>-- (void)_processMediaInfoDictionaries:(NSArray *)infos successBlock:(void (^)(NSArray *processedResults, NSString *displayString))successBlock failureBlock:(void (^)(void))failureBlock
</del><ins>+- (void)_processMediaInfoDictionaries:(NSArray *)infos successBlock:(void (^)(NSArray<_WKFileUploadItem *> *processedResults))successBlock failureBlock:(void (^)(void))failureBlock
</ins><span class="cx"> {
</span><del>-    [self _processMediaInfoDictionaries:infos atIndex:0 processedResults:[NSMutableArray array] processedImageCount:0 processedVideoCount:0 successBlock:successBlock failureBlock:failureBlock];
</del><ins>+    [self _processMediaInfoDictionaries:infos atIndex:0 processedResults:[NSMutableArray array] successBlock:successBlock failureBlock:failureBlock];
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-- (void)_processMediaInfoDictionaries:(NSArray *)infos atIndex:(NSUInteger)index processedResults:(NSMutableArray *)processedResults processedImageCount:(NSUInteger)processedImageCount processedVideoCount:(NSUInteger)processedVideoCount successBlock:(void (^)(NSArray *processedResults, NSString *displayString))successBlock failureBlock:(void (^)(void))failureBlock
</del><ins>+- (void)_processMediaInfoDictionaries:(NSArray *)infos atIndex:(NSUInteger)index processedResults:(NSMutableArray<_WKFileUploadItem *> *)processedResults successBlock:(void (^)(NSArray<_WKFileUploadItem *> *processedResults))successBlock failureBlock:(void (^)(void))failureBlock
</ins><span class="cx"> {
</span><span class="cx">     NSUInteger count = [infos count];
</span><span class="cx">     if (index == count) {
</span><del>-        NSString *displayString = (processedImageCount || processedVideoCount) ? [NSString localizedStringWithFormat:WEB_UI_NSSTRING(@"%lu photo(s) and %lu video(s)", "label next to file upload control; parameters are the number of photos and the number of videos"), (unsigned long)processedImageCount, (unsigned long)processedVideoCount] : nil;
-        successBlock(processedResults, displayString);
</del><ins>+        successBlock(processedResults);
</ins><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -803,10 +977,8 @@
</span><span class="cx">     index++;
</span><span class="cx"> 
</span><span class="cx">     auto uploadItemSuccessBlock = ^(_WKFileUploadItem *uploadItem) {
</span><del>-        NSUInteger newProcessedVideoCount = processedVideoCount + (uploadItem.isVideo ? 1 : 0);
-        NSUInteger newProcessedImageCount = processedImageCount + (uploadItem.isVideo ? 0 : 1);
</del><span class="cx">         [processedResults addObject:uploadItem];
</span><del>-        [self _processMediaInfoDictionaries:infos atIndex:index processedResults:processedResults processedImageCount:newProcessedImageCount processedVideoCount:newProcessedVideoCount successBlock:successBlock failureBlock:failureBlock];
</del><ins>+        [self _processMediaInfoDictionaries:infos atIndex:index processedResults:processedResults successBlock:successBlock failureBlock:failureBlock];
</ins><span class="cx">     };
</span><span class="cx"> 
</span><span class="cx">     [self _uploadItemFromMediaInfo:info successBlock:uploadItemSuccessBlock failureBlock:failureBlock];
</span><span class="lines">@@ -890,7 +1062,6 @@
</span><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-#if PLATFORM(IOS_FAMILY)
</del><span class="cx">     if (NSURL *imageURL = info[UIImagePickerControllerImageURL]) {
</span><span class="cx">         if (!imageURL.isFileURL) {
</span><span class="cx">             LOG_ERROR("WKFileUploadPanel: Expected image URL to be a file path, it was not");
</span><span class="lines">@@ -902,7 +1073,6 @@
</span><span class="cx">         successBlock(adoptNS([[_WKImageFileUploadItem alloc] initWithFileURL:imageURL]).get());
</span><span class="cx">         return;
</span><span class="cx">     }
</span><del>-#endif
</del><span class="cx"> 
</span><span class="cx">     UIImage *originalImage = [info objectForKey:UIImagePickerControllerOriginalImage];
</span><span class="cx">     if (!originalImage) {
</span><span class="lines">@@ -916,6 +1086,30 @@
</span><span class="cx">     [self _uploadItemForJPEGRepresentationOfImage:originalImage successBlock:successBlock failureBlock:failureBlock];
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+- (void)_uploadMediaItemsTranscodingVideo:(NSArray<_WKFileUploadItem *> *)items
+{
+    auto videoCount = [[items indexesOfObjectsPassingTest:^(_WKFileUploadItem *item, NSUInteger, BOOL*) {
+        return item.isVideo;
+    }] count];
+
+    ensureOnMainRunLoop([self, strongSelf = retainPtr(self), items = retainPtr(items), videoCount] {
+        if (!videoCount) {
+            [self _chooseMediaItems:items.get()];
+            return;
+        }
+
+        _mediaTranscoder = adoptNS([[WKFileUploadMediaTranscoder alloc] initWithItems:items.get() videoCount:videoCount completionHandler:[weakSelf = WeakObjCPtr<WKFileUploadPanel>(self)] (NSArray<_WKFileUploadItem *> *items) {
+            auto strongSelf = weakSelf.get();
+            if (!strongSelf)
+                return;
+
+            [strongSelf _chooseMediaItems:items];
+        }]);
+
+        [_mediaTranscoder start];
+    });
+}
+
</ins><span class="cx"> - (BOOL)platformSupportsPickerViewController
</span><span class="cx"> {
</span><span class="cx"> #if PLATFORM(WATCHOS)
</span></span></pre></div>
<a id="trunkSourceWebKitWebKitxcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj (283591 => 283592)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj     2021-10-06 00:20:55 UTC (rev 283591)
+++ trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj        2021-10-06 00:42:35 UTC (rev 283592)
</span><span class="lines">@@ -2033,6 +2033,7 @@
</span><span class="cx">          E596DD6A251E71D400C275A7 /* WKContactPicker.h in Headers */ = {isa = PBXBuildFile; fileRef = E596DD68251E71D300C275A7 /* WKContactPicker.h */; };
</span><span class="cx">          E5BEF6822130C48000F31111 /* WebDataListSuggestionsDropdownIOS.h in Headers */ = {isa = PBXBuildFile; fileRef = E5BEF6802130C47F00F31111 /* WebDataListSuggestionsDropdownIOS.h */; };
</span><span class="cx">          E5CB07DC20E1678F0022C183 /* WKFormColorControl.h in Headers */ = {isa = PBXBuildFile; fileRef = E5CB07DA20E1678F0022C183 /* WKFormColorControl.h */; };
</span><ins>+               E5DEFA6826F8F42600AB68DB /* PhotosUISPI.h in Headers */ = {isa = PBXBuildFile; fileRef = E5DEFA6726F8F42600AB68DB /* PhotosUISPI.h */; };
</ins><span class="cx">           ED82A7F2128C6FAF004477B3 /* WKBundlePageOverlay.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A22F0FF1289FCD90085E74F /* WKBundlePageOverlay.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">          F4094CBD2553053D003D73E3 /* DisplayListReaderHandle.h in Headers */ = {isa = PBXBuildFile; fileRef = F4094CBB255304AF003D73E3 /* DisplayListReaderHandle.h */; };
</span><span class="cx">          F4094CBE25530540003D73E3 /* DisplayListWriterHandle.h in Headers */ = {isa = PBXBuildFile; fileRef = F4094CB92553047E003D73E3 /* DisplayListWriterHandle.h */; };
</span><span class="lines">@@ -6092,6 +6093,7 @@
</span><span class="cx">          E5BEF6812130C47F00F31111 /* WebDataListSuggestionsDropdownIOS.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = WebDataListSuggestionsDropdownIOS.mm; path = ios/WebDataListSuggestionsDropdownIOS.mm; sourceTree = "<group>"; };
</span><span class="cx">          E5CB07DA20E1678F0022C183 /* WKFormColorControl.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = WKFormColorControl.h; path = ios/forms/WKFormColorControl.h; sourceTree = "<group>"; };
</span><span class="cx">          E5CB07DB20E1678F0022C183 /* WKFormColorControl.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = WKFormColorControl.mm; path = ios/forms/WKFormColorControl.mm; sourceTree = "<group>"; };
</span><ins>+               E5DEFA6726F8F42600AB68DB /* PhotosUISPI.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PhotosUISPI.h; sourceTree = "<group>"; };
</ins><span class="cx">           ECA680D31E6904B500731D20 /* ExtraPrivateSymbolsForTAPI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExtraPrivateSymbolsForTAPI.h; sourceTree = "<group>"; };
</span><span class="cx">          ECBFC1DB1E6A4D66000300C7 /* ExtraPublicSymbolsForTAPI.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ExtraPublicSymbolsForTAPI.h; sourceTree = "<group>"; };
</span><span class="cx">          F036978715F4BF0500C3A80E /* WebColorPicker.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebColorPicker.cpp; sourceTree = "<group>"; };
</span><span class="lines">@@ -11805,6 +11807,7 @@
</span><span class="cx">                          2D4AF0882044C3C4006C8817 /* FrontBoardServicesSPI.h */,
</span><span class="cx">                          A13B3DA1207F39DE0090C58D /* MobileWiFiSPI.h */,
</span><span class="cx">                          3178AF9720E2A7F80074DE94 /* PDFKitSPI.h */,
</span><ins>+                               E5DEFA6726F8F42600AB68DB /* PhotosUISPI.h */,
</ins><span class="cx">                           2D279E1826955768004B3EEB /* PrototypeToolsSPI.h */,
</span><span class="cx">                          46F38E8B2416E66D0059375A /* RunningBoardServicesSPI.h */,
</span><span class="cx">                          079D1D9926960CD300883577 /* SystemStatusSPI.h */,
</span><span class="lines">@@ -12481,6 +12484,7 @@
</span><span class="cx">                          5C298DA01C3DF02100470AFE /* PendingDownload.h in Headers */,
</span><span class="cx">                          832ED18C1E2FE157006BA64A /* PerActivityStateCPUUsageSampler.h in Headers */,
</span><span class="cx">                          7AFBD36F21E546F8005DBACB /* PersistencyUtils.h in Headers */,
</span><ins>+                            E5DEFA6826F8F42600AB68DB /* PhotosUISPI.h in Headers */,
</ins><span class="cx">                           5CE85B201C88E64B0070BFCE /* PingLoad.h in Headers */,
</span><span class="cx">                          0F5E200418E77051003EC3E5 /* PlatformCAAnimationRemote.h in Headers */,
</span><span class="cx">                          2DA049B4180CCCD300AAFA9E /* PlatformCALayerRemote.h in Headers */,
</span></span></pre>
</div>
</div>

</body>
</html>