Browse Source

Adds synchronization logic to allow NSUserActivityDelegate to wait Javascript updating the NSUserActiity UserInfo if requested.

Rafael Nobre 7 years ago
parent
commit
9483f0fc14

+ 2 - 1
atom/browser/api/atom_api_app.cc

@@ -606,9 +606,10 @@ void App::OnUserActivityWasContinued(
   Emit("activity-was-continued", type, user_info);
 }
 void App::OnUpdateUserActivityState(
+    bool* prevent_default,
     const std::string& type,
     const base::DictionaryValue& user_info) {
-  Emit("update-activity-state", type, user_info);
+  *prevent_default = Emit("update-activity-state", type, user_info);
 }
 void App::OnNewWindowForTab() {
   Emit("new-window-for-tab");

+ 1 - 0
atom/browser/api/atom_api_app.h

@@ -127,6 +127,7 @@ class App : public AtomBrowserClient::Delegate,
       const std::string& type,
       const base::DictionaryValue& user_info) override;
   void OnUpdateUserActivityState(
+      bool* prevent_default,
       const std::string& type,
       const base::DictionaryValue& user_info) override;
   void OnNewWindowForTab() override;

+ 1 - 1
atom/browser/browser.h

@@ -142,7 +142,7 @@ class Browser : public WindowListObserver {
                                 const base::DictionaryValue& user_info);
 
   // Gives an oportunity to update the Handoff payload.
-  void UpdateUserActivityState(const std::string& type,
+  bool UpdateUserActivityState(const std::string& type,
                                const base::DictionaryValue& user_info);
 
   // Bounce the dock icon.

+ 4 - 2
atom/browser/browser_mac.mm

@@ -182,10 +182,12 @@ void Browser::UserActivityWasContinued(const std::string& type,
     observer.OnUserActivityWasContinued(type, user_info);
 }
 
-void Browser::UpdateUserActivityState(const std::string& type,
+bool Browser::UpdateUserActivityState(const std::string& type,
                                       const base::DictionaryValue& user_info) {
+  bool prevent_default = false;
   for (BrowserObserver& observer : observers_)
-    observer.OnUpdateUserActivityState(type, user_info);
+    observer.OnUpdateUserActivityState(&prevent_default, type, user_info);
+  return prevent_default;
 }
 
 Browser::LoginItemSettings Browser::GetLoginItemSettings(

+ 1 - 0
atom/browser/browser_observer.h

@@ -75,6 +75,7 @@ class BrowserObserver {
       const base::DictionaryValue& user_info) {}
   // The browser wants to update an user activity payload. (macOS only)
   virtual void OnUpdateUserActivityState(
+      bool* prevent_default,
       const std::string& type,
       const base::DictionaryValue& user_info) {}
   // User clicked the native macOS new tab button. (macOS only)

+ 2 - 0
atom/browser/mac/atom_application.h

@@ -11,6 +11,8 @@
  @private
   BOOL handlingSendEvent_;
   base::scoped_nsobject<NSUserActivity> currentActivity_;
+  NSCondition *handoffLock_;
+  BOOL updateReceived_;
 }
 
 + (AtomApplication*)sharedApplication;

+ 22 - 1
atom/browser/mac/atom_application.mm

@@ -57,17 +57,36 @@
   if (currentActivity_.get() != NULL) {
     [currentActivity_.get() addUserInfoEntriesFromDictionary:userInfo];
   }
+
+  [handoffLock_ lock];
+  updateReceived_ = YES;
+  [handoffLock_ signal];
+  [handoffLock_ unlock];
 }
 
 - (void)userActivityWillSave:(NSUserActivity *)userActivity {
+
+  __block BOOL shouldWait = NO;
+
   dispatch_sync(dispatch_get_main_queue(), ^{
     std::string activity_type(base::SysNSStringToUTF8(userActivity.activityType));
     std::unique_ptr<base::DictionaryValue> user_info =
       atom::NSDictionaryToDictionaryValue(userActivity.userInfo);
 
     atom::Browser* browser = atom::Browser::Get();
-    browser->UpdateUserActivityState(activity_type, *user_info);    
+    shouldWait = browser->UpdateUserActivityState(activity_type, *user_info) ? YES : NO;    
   });
+
+  if (shouldWait) {
+    [handoffLock_ lock];
+    updateReceived_ = NO;
+    while (!updateReceived_) {
+      BOOL isSignaled = [handoffLock_ waitUntilDate:[NSDate dateWithTimeIntervalSinceNow:1]];
+      if (!isSignaled) { break; }
+    }
+    [handoffLock_ unlock];
+  }
+
   [userActivity setNeedsSave:YES];
 }
 
@@ -90,6 +109,8 @@
           andSelector:@selector(handleURLEvent:withReplyEvent:)
         forEventClass:kInternetEventClass
            andEventID:kAEGetURL];
+
+  handoffLock_ = [NSCondition new];
 }
 
 - (void)handleURLEvent:(NSAppleEventDescriptor*)event