fix(share_plus): correct Windows share sheet data package setup - #3975
MobileWeblink wants to merge 2 commits into
Conversation
The Windows share sheet failed with "We couldn't show you all the ways you could share" because the DataPackage handed to Windows was invalid. Several issues contributed to this: - IStorageFile was reinterpret_cast to IStorageItem. The two interfaces are unrelated at the ABI level, so the share target received a pointer with the wrong vtable. The interface is now obtained via QueryInterface. - The IStorageItem collection was stack allocated, while the DataPackage keeps a reference to it after the DataRequested handler returns. It is now heap allocated and owned by the plugin. - SetStorageItemsReadOnly was called unconditionally, so a text-only share advertised an empty file collection. It is now only called when there is at least one file. - An empty Title was set when sharing files without a title, subject or text. Windows rejects such a package, so the title now falls back to the subject, the text, the URI and finally the window title. - Files were resolved with a synchronous wait inside the DataRequested handler, which runs on the UI thread with a short deadline. They are now resolved before the share UI is shown. - add_DataRequested was called on every share without ever removing the previous handler, leaving stale handlers writing to later packages. Additionally, the plugin state is reset on every call so values are no longer inherited from the previous share, HRESULTs are propagated to Dart instead of always reporting success, the IStorageFile reference is no longer leaked, and Utf16FromUtf8 no longer embeds a NUL terminator in the converted string.
|
Update on testing: I have now verified this on a real machine.
The other scenarios from the description (text only, text and files together, two consecutive shares, large files and network paths) have not been verified yet. |
|
The formatting check was failing on I pushed a separate commit applying |
The file was not formatted according to the dart format version used by CI, which made the formatting check report it. It is unrelated to the Windows fix in this PR.
da57a7d to
106bbec
Compare
|
A note on the red checks, since most of them are not caused by this PR. The same five checks are currently failing on every open pull request (#3970, #3971, #3972), so they look like pre-existing breakage on
The one item that does belong to this PR is |
Description
On Windows the share sheet fails with "Try that again — We couldn't show you all the ways you could share", both when sharing files and when sharing text only. The
DataPackagebuilt by the plugin is rejected by Windows.Several distinct problems in the Windows implementation contribute to this, each of which is enough to produce that error:
IStorageFilewasreinterpret_casttoIStorageItem. The two interfaces are unrelated at the ABI level, so the collection handed to theDataPackagecontained pointers with the wrong vtable. The interface is now obtained viaQueryInterface.IStorageItemcollection was a stack allocatedVector<>, while theDataPackagekeeps a reference to it after theDataRequestedhandler has returned. It is now heap allocated withWRL::Make<>and owned by the plugin.SetStorageItemsReadOnlywas called unconditionally, so a text-only share advertised an empty file collection. It is now only called when there is at least one file.Titlewas set when sharing files without a title, subject or text. Windows rejects a package with an empty title, so the title now falls back to the subject, the text, the URI and finally the window title.GetFileFromPathAsyncplus aSleepExspin) inside theDataRequestedhandler, which runs on the UI thread with a short deadline. They are now resolved beforeShowShareUIForWindowis called.add_DataRequestedwas called on every share without ever removing the previous handler, and the registration token was overwritten. Handlers accumulated and all wrote to theDataPackageof every later request.Additionally:
paths,title,subjectandtextare no longer inherited from the previous share when the new call omits them.findinstead ofstd::map::operator[], which was inserting null values for missing keys.HRESULTs are checked and propagated to Dart as a method channel error, instead of always reporting success.IStorageFilereference returned byGetStorageFileFromPathis no longer leaked.Utf16FromUtf8no longer includes the terminating NUL in the convertedstd::wstring, which was embedding a NUL in the resultingHSTRINGs.No Dart code is affected, so the existing tests are unchanged.
Testing
Verified on Windows 11 when sharing a single PDF file: before this change the share sheet showed "Try that again — We couldn't show you all the ways you could share", after it the sheet opens and lists the share targets.
Still to be verified:
Related Issues
Checklist
CHANGELOG.mdnor the plugin version inpubspec.yamlfiles.flutter analyze) does not report any problems on my PR.Breaking Change