[Libreoffice-commits] online.git: ios/Mobile wsd/DocumentBroker.cpp
Tor Lillqvist (via logerrit)
logerrit at kemper.freedesktop.org
Tue Apr 7 22:01:51 UTC 2020
ios/Mobile/CODocument.h | 1
ios/Mobile/CODocument.mm | 20 +++++++++----------
ios/Mobile/DocumentViewController.mm | 36 +++++++++++++++++++----------------
wsd/DocumentBroker.cpp | 8 +++----
4 files changed, 35 insertions(+), 30 deletions(-)
New commits:
commit 0930286e2d8fd2ba1e4820758246ee3766040254
Author: Tor Lillqvist <tml at collabora.com>
AuthorDate: Tue Apr 7 21:21:55 2020 +0300
Commit: Tor Lillqvist <tml at collabora.com>
CommitDate: Wed Apr 8 00:01:30 2020 +0200
Fix problems after my 293f4913d2cdfe5385e2cdc0e3bebde281da1578
It is enough to call the -[UIDocument
saveToURL:forSaveOperation:completionHandler:] only in
DocumentBroker::sendUnoSave(). And on the other hand, in
-[DocumentViewController bye] we can't want for the
LOOLWSD::lokit_main_mutex as the main queue is needed for parts of
what the saveToURL does.
Also, use a separate copy of the document as the file that is actually
edited by LO core. This matches what the Android app does. I think it
is useful to do this in order to avoid some hangs that I noticed. They
probably were caused by both LO core and the system frameworks
occasionally accessing the same document file at the same time.
Change-Id: Idb65be23a7cb6ad1288fbbd23c7471e0fb8d52f4
Reviewed-on: https://gerrit.libreoffice.org/c/online/+/91851
Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice at gmail.com>
Reviewed-by: Tor Lillqvist <tml at collabora.com>
diff --git a/ios/Mobile/CODocument.h b/ios/Mobile/CODocument.h
index 82e2e80e3..79f772a1b 100644
--- a/ios/Mobile/CODocument.h
+++ b/ios/Mobile/CODocument.h
@@ -18,6 +18,7 @@
@interface CODocument : UIDocument {
@public
int fakeClientFd;
+ NSURL *copyFileURL;
}
@property (weak) DocumentViewController *viewController;
diff --git a/ios/Mobile/CODocument.mm b/ios/Mobile/CODocument.mm
index 095d449ea..5dcd9b136 100644
--- a/ios/Mobile/CODocument.mm
+++ b/ios/Mobile/CODocument.mm
@@ -37,14 +37,7 @@
@implementation CODocument
- (id)contentsForType:(NSString*)typeName error:(NSError **)errorPtr {
- // Somehow this doesn't feel right, creating an NSFileWrapper around the file that was given to
- // us for loadFromContents. I get the vague feeling that the file is perhaps just a temporary
- // data container created by the system for us to be used while loading the document data, and
- // not the actual permanent document, especially in the case of things like NextCloud. Or is it?
- // Is saving back to the file (which we have already saved to in the core code by the time we
- // get here) correct? This does seem to work, though. Sadly the Apple documentation is a bit
- // lacking about how these things *really* work.
- return [[NSFileWrapper alloc] initWithURL:[self fileURL] options:0 error:errorPtr];
+ return [NSData dataWithContentsOfFile:[copyFileURL path] options:0 error:errorPtr];
}
- (BOOL)loadFromContents:(id)contents ofType:(NSString *)typeName error:(NSError **)errorPtr {
@@ -55,11 +48,18 @@
return YES;
fakeClientFd = fakeSocketSocket();
- NSString *uri = [[self fileURL] absoluteString];
+
+ copyFileURL = [[[NSFileManager defaultManager] temporaryDirectory] URLByAppendingPathComponent:[[[self fileURL] path] lastPathComponent]];
+
+ NSError *error;
+ [[NSFileManager defaultManager] removeItemAtURL:copyFileURL error:nil];
+ [[NSFileManager defaultManager] copyItemAtURL:[self fileURL] toURL:copyFileURL error:&error];
+ if (error != nil)
+ return NO;
NSURL *url = [[NSBundle mainBundle] URLForResource:@"loleaflet" withExtension:@"html"];
NSURLComponents *components = [NSURLComponents componentsWithURL:url resolvingAgainstBaseURL:NO];
- components.queryItems = @[ [NSURLQueryItem queryItemWithName:@"file_path" value:uri],
+ components.queryItems = @[ [NSURLQueryItem queryItemWithName:@"file_path" value:[copyFileURL absoluteString]],
[NSURLQueryItem queryItemWithName:@"closebutton" value:@"1"],
[NSURLQueryItem queryItemWithName:@"permission" value:@"edit"],
[NSURLQueryItem queryItemWithName:@"lang" value:app_locale]
diff --git a/ios/Mobile/DocumentViewController.mm b/ios/Mobile/DocumentViewController.mm
index 94dbd839c..97ac7ab96 100644
--- a/ios/Mobile/DocumentViewController.mm
+++ b/ios/Mobile/DocumentViewController.mm
@@ -348,7 +348,7 @@ static IMP standardImpOfInputAccessoryView = nil;
// First we simply send it the URL. This corresponds to the GET request with Upgrade to
// WebSocket.
- std::string url([[[self.document fileURL] absoluteString] UTF8String]);
+ std::string url([[self.document->copyFileURL absoluteString] UTF8String]);
p.fd = self.document->fakeClientFd;
p.events = POLLOUT;
fakeSocketPoll(&p, 1, -1);
@@ -469,21 +469,25 @@ static IMP standardImpOfInputAccessoryView = nil;
// Close one end of the socket pair, that will wake up the forwarding thread above
fakeSocketClose(closeNotificationPipeForForwardingThread[0]);
- // I suspect that what this will do (in -[CODocument contentsForType:error:]) is to read the
- // contents of the file that LO core already saved, and overwrite it with the same contents.
- [self.document saveToURL:[self.document fileURL]
- forSaveOperation:UIDocumentSaveForOverwriting
- completionHandler:^(BOOL success) {
- LOG_TRC("save completion handler gets " << (success?"YES":"NO"));
- }];
-
- // Wait for lokit_main thread to exit
- std::lock_guard<std::mutex> lock(LOOLWSD::lokit_main_mutex);
-
- theSingleton = nil;
-
- // And only then let the document browsing view show up again
- [self dismissDocumentViewController];
+ // We can't wait for the LOOLWSD::lokit_main_mutex directly here because this is called on the
+ // main queue and the main queue must be ready to execute code dispatched by the system APIs
+ // used to do document saving.
+ dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),
+ ^{
+ // Wait for lokit_main thread to exit
+ std::lock_guard<std::mutex> lock(LOOLWSD::lokit_main_mutex);
+
+ theSingleton = nil;
+
+ [[NSFileManager defaultManager] removeItemAtURL:self.document->copyFileURL error:nil];
+
+ // And only then let the document browsing view show up again. The
+ // dismissViewControllerAnimated must be done on the main queue.
+ dispatch_async(dispatch_get_main_queue(),
+ ^{
+ [self dismissDocumentViewController];
+ });
+ });
}
+ (DocumentViewController*)singleton {
diff --git a/wsd/DocumentBroker.cpp b/wsd/DocumentBroker.cpp
index 0d5ce909d..4287624e9 100644
--- a/wsd/DocumentBroker.cpp
+++ b/wsd/DocumentBroker.cpp
@@ -1289,14 +1289,14 @@ bool DocumentBroker::sendUnoSave(const std::string& sessionId, bool dontTerminat
forwardToChild(sessionId, command);
_lastSaveRequestTime = std::chrono::steady_clock::now();
#ifdef IOS
- // We need to do this so that file provider extensions notice. Just like in
- // -[DocumentViewController bye] I suspect that will read the file and then overwrite it
- // with the same contents, but oh well.
+ // We need to do this here, also for auto-save, so that file provider extensions notice.
+
CODocument *document = [[DocumentViewController singleton] document];
+
[document saveToURL:[[[DocumentViewController singleton] document] fileURL]
forSaveOperation:UIDocumentSaveForOverwriting
completionHandler:^(BOOL success) {
- LOG_TRC("save completion handler gets " << (success?"YES":"NO"));
+ LOG_TRC("DocumentBroker::sendUnoSave() save completion handler gets " << (success?"YES":"NO"));
}];
#endif
return true;
More information about the Libreoffice-commits
mailing list