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

This commit is contained in:
Rafael Nobre 2017-08-09 12:09:47 -03:00 committed by Cheng Zhao
parent c23b4a48ec
commit 9483f0fc14
7 changed files with 33 additions and 5 deletions

View file

@ -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");

View file

@ -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;

View file

@ -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.

View file

@ -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(

View file

@ -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)

View file

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

View file

@ -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