Merge pull request #5401 from electron/ns-js-object
Fully support the userInfo object in app.setUserActivity and continue-activity event
This commit is contained in:
commit
636570306a
17 changed files with 167 additions and 147 deletions
|
@ -20,7 +20,6 @@
|
|||
#include "atom/common/native_mate_converters/image_converter.h"
|
||||
#include "atom/common/native_mate_converters/net_converter.h"
|
||||
#include "atom/common/native_mate_converters/value_converter.h"
|
||||
#include "atom/common/native_mate_converters/string_map_converter.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "atom/common/options_switches.h"
|
||||
#include "base/command_line.h"
|
||||
|
@ -250,11 +249,14 @@ void App::OnFinishLaunching() {
|
|||
Emit("ready");
|
||||
}
|
||||
|
||||
void App::OnContinueUserActivity(bool* prevent_default,
|
||||
const std::string& type,
|
||||
const std::map<std::string, std::string>& user_info) {
|
||||
#if defined(OS_MACOSX)
|
||||
void App::OnContinueUserActivity(
|
||||
bool* prevent_default,
|
||||
const std::string& type,
|
||||
const base::DictionaryValue& user_info) {
|
||||
*prevent_default = Emit("continue-activity", type, user_info);
|
||||
}
|
||||
#endif
|
||||
|
||||
void App::OnLogin(LoginHandler* login_handler) {
|
||||
v8::Locker locker(isolate());
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
#define ATOM_BROWSER_API_ATOM_API_APP_H_
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
#include "atom/browser/api/event_emitter.h"
|
||||
#include "atom/browser/atom_browser_client.h"
|
||||
|
@ -72,9 +71,12 @@ class App : public AtomBrowserClient::Delegate,
|
|||
void OnWillFinishLaunching() override;
|
||||
void OnFinishLaunching() override;
|
||||
void OnLogin(LoginHandler* login_handler) override;
|
||||
void OnContinueUserActivity(bool* prevent_default,
|
||||
const std::string& type,
|
||||
const std::map<std::string, std::string>& user_info) override;
|
||||
#if defined(OS_MACOSX)
|
||||
void OnContinueUserActivity(
|
||||
bool* prevent_default,
|
||||
const std::string& type,
|
||||
const base::DictionaryValue& user_info) override;
|
||||
#endif
|
||||
|
||||
// content::ContentBrowserClient:
|
||||
void AllowCertificateError(
|
||||
|
|
|
@ -137,19 +137,6 @@ void Browser::Activate(bool has_visible_windows) {
|
|||
OnActivate(has_visible_windows));
|
||||
}
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
bool Browser::ContinueUserActivity(const std::string& type,
|
||||
const std::map<std::string,
|
||||
std::string>& user_info) {
|
||||
bool prevent_default = false;
|
||||
FOR_EACH_OBSERVER(BrowserObserver,
|
||||
observers_,
|
||||
OnContinueUserActivity(&prevent_default, type, user_info));
|
||||
|
||||
return prevent_default;
|
||||
}
|
||||
#endif
|
||||
|
||||
void Browser::WillFinishLaunching() {
|
||||
FOR_EACH_OBSERVER(BrowserObserver, observers_, OnWillFinishLaunching());
|
||||
}
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
#include "base/macros.h"
|
||||
#include "base/compiler_specific.h"
|
||||
|
@ -95,14 +94,14 @@ class Browser : public WindowListObserver {
|
|||
|
||||
// Creates an activity and sets it as the one currently in use.
|
||||
void SetUserActivity(const std::string& type,
|
||||
const std::map<std::string, std::string>& user_info);
|
||||
const base::DictionaryValue& user_info);
|
||||
|
||||
// Returns the type name of the current user activity.
|
||||
std::string GetCurrentActivityType();
|
||||
|
||||
// Resumes an activity via hand-off.
|
||||
bool ContinueUserActivity(const std::string& type,
|
||||
const std::map<std::string, std::string>& user_info);
|
||||
const base::DictionaryValue& user_info);
|
||||
|
||||
// Bounce the dock icon.
|
||||
enum BounceType {
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
#include "atom/browser/mac/atom_application.h"
|
||||
#include "atom/browser/mac/atom_application_delegate.h"
|
||||
#include "atom/browser/mac/dict_util.h"
|
||||
#include "atom/browser/native_window.h"
|
||||
#include "atom/browser/window_list.h"
|
||||
#include "base/mac/bundle_locations.h"
|
||||
|
@ -87,28 +88,28 @@ bool Browser::IsDefaultProtocolClient(const std::string& protocol) {
|
|||
void Browser::SetAppUserModelID(const base::string16& name) {
|
||||
}
|
||||
|
||||
void Browser::SetUserActivity(const std::string& type, const std::map<std::string, std::string>& user_info) {
|
||||
NSString* type_ns = [NSString stringWithUTF8String:type.c_str()];
|
||||
NSUserActivity* user_activity = [[NSUserActivity alloc] initWithActivityType:type_ns];
|
||||
|
||||
base::scoped_nsobject<NSMutableDictionary> user_info_args([[NSMutableDictionary alloc] init]);
|
||||
for (auto const &pair : user_info) {
|
||||
NSString* value_ns = [NSString stringWithUTF8String:pair.second.c_str()];
|
||||
NSString* key_ns = [NSString stringWithUTF8String:pair.first.c_str()];
|
||||
|
||||
[user_info_args.get() setObject:value_ns
|
||||
forKey:key_ns];
|
||||
}
|
||||
|
||||
user_activity.userInfo = user_info_args.get();
|
||||
[user_activity becomeCurrent];
|
||||
|
||||
[[AtomApplication sharedApplication] setCurrentActivity:user_activity];
|
||||
void Browser::SetUserActivity(
|
||||
const std::string& type,
|
||||
const base::DictionaryValue& user_info) {
|
||||
[[AtomApplication sharedApplication]
|
||||
setCurrentActivity:base::SysUTF8ToNSString(type)
|
||||
withUserInfo:DictionaryValueToNSDictionary(user_info)];
|
||||
}
|
||||
|
||||
std::string Browser::GetCurrentActivityType() {
|
||||
NSUserActivity* user_activity = [[AtomApplication sharedApplication] getCurrentActivity];
|
||||
return base::SysNSStringToUTF8(user_activity.activityType);
|
||||
NSUserActivity* userActivity =
|
||||
[[AtomApplication sharedApplication] getCurrentActivity];
|
||||
return base::SysNSStringToUTF8(userActivity.activityType);
|
||||
}
|
||||
|
||||
bool Browser::ContinueUserActivity(
|
||||
const std::string& type,
|
||||
const base::DictionaryValue& user_info) {
|
||||
bool prevent_default = false;
|
||||
FOR_EACH_OBSERVER(BrowserObserver,
|
||||
observers_,
|
||||
OnContinueUserActivity(&prevent_default, type, user_info));
|
||||
return prevent_default;
|
||||
}
|
||||
|
||||
std::string Browser::GetExecutableFileVersion() const {
|
||||
|
|
|
@ -6,7 +6,12 @@
|
|||
#define ATOM_BROWSER_BROWSER_OBSERVER_H_
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
#include "build/build_config.h"
|
||||
|
||||
namespace base {
|
||||
class DictionaryValue;
|
||||
}
|
||||
|
||||
namespace atom {
|
||||
|
||||
|
@ -46,10 +51,13 @@ class BrowserObserver {
|
|||
// The browser requests HTTP login.
|
||||
virtual void OnLogin(LoginHandler* login_handler) {}
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
// The browser wants to resume a user activity via handoff. (OS X only)
|
||||
virtual void OnContinueUserActivity(bool* prevent_default,
|
||||
const std::string& type,
|
||||
const std::map<std::string, std::string>& user_info) {}
|
||||
virtual void OnContinueUserActivity(
|
||||
bool* prevent_default,
|
||||
const std::string& type,
|
||||
const base::DictionaryValue& user_info) {}
|
||||
#endif
|
||||
|
||||
protected:
|
||||
virtual ~BrowserObserver() {}
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
- (void)setHandlingSendEvent:(BOOL)handlingSendEvent;
|
||||
|
||||
- (NSUserActivity*)getCurrentActivity;
|
||||
|
||||
- (void)setCurrentActivity:(NSUserActivity*)userActivity;
|
||||
- (void)setCurrentActivity:(NSString*)type withUserInfo:(NSDictionary*)userInfo;
|
||||
|
||||
@end
|
||||
|
|
|
@ -28,8 +28,12 @@
|
|||
handlingSendEvent_ = handlingSendEvent;
|
||||
}
|
||||
|
||||
- (void)setCurrentActivity:(NSUserActivity*)userActivity {
|
||||
currentActivity_ = base::scoped_nsobject<NSUserActivity>(userActivity);
|
||||
- (void)setCurrentActivity:(NSString*)type
|
||||
withUserInfo:(NSDictionary*)userInfo {
|
||||
currentActivity_ = base::scoped_nsobject<NSUserActivity>(
|
||||
[[NSUserActivity alloc] initWithActivityType:type]);
|
||||
[currentActivity_ setUserInfo:userInfo];
|
||||
[currentActivity_ becomeCurrent];
|
||||
}
|
||||
|
||||
- (NSUserActivity*)getCurrentActivity {
|
||||
|
|
|
@ -6,7 +6,9 @@
|
|||
|
||||
#import "atom/browser/mac/atom_application.h"
|
||||
#include "atom/browser/browser.h"
|
||||
#include "atom/browser/mac/dict_util.h"
|
||||
#include "base/strings/sys_string_conversions.h"
|
||||
#include "base/values.h"
|
||||
|
||||
@implementation AtomApplicationDelegate
|
||||
|
||||
|
@ -59,23 +61,17 @@
|
|||
return flag;
|
||||
}
|
||||
|
||||
- (BOOL)application:(NSApplication *)sender
|
||||
continueUserActivity:(NSUserActivity *)userActivity
|
||||
restorationHandler:(void (^)(NSArray *restorableObjects))restorationHandler {
|
||||
- (BOOL)application:(NSApplication*)sender
|
||||
continueUserActivity:(NSUserActivity*)userActivity
|
||||
restorationHandler:(void (^)(NSArray*restorableObjects))restorationHandler {
|
||||
std::string activity_type(base::SysNSStringToUTF8(userActivity.activityType));
|
||||
|
||||
std::map<std::string, std::string> user_info;
|
||||
base::scoped_nsobject<NSArray> keys([userActivity.userInfo allKeys]);
|
||||
|
||||
for (NSString* key in keys.get()) {
|
||||
NSString* value = [userActivity.userInfo objectForKey:key];
|
||||
std::string key_str(base::SysNSStringToUTF8(key));
|
||||
std::string value_str(base::SysNSStringToUTF8(value));
|
||||
user_info[key_str] = value_str;
|
||||
}
|
||||
scoped_ptr<base::DictionaryValue> user_info =
|
||||
atom::NSDictionaryToDictionaryValue(userActivity.userInfo);
|
||||
if (!user_info)
|
||||
return NO;
|
||||
|
||||
atom::Browser* browser = atom::Browser::Get();
|
||||
return browser->ContinueUserActivity(activity_type, user_info) ? YES : NO;
|
||||
return browser->ContinueUserActivity(activity_type, *user_info) ? YES : NO;
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
26
atom/browser/mac/dict_util.h
Normal file
26
atom/browser/mac/dict_util.h
Normal file
|
@ -0,0 +1,26 @@
|
|||
// Copyright (c) 2016 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ATOM_BROWSER_MAC_DICT_UTIL_H_
|
||||
#define ATOM_BROWSER_MAC_DICT_UTIL_H_
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#include "base/memory/scoped_ptr.h"
|
||||
|
||||
namespace base {
|
||||
class Value;
|
||||
class DictionaryValue;
|
||||
}
|
||||
|
||||
namespace atom {
|
||||
|
||||
NSDictionary* DictionaryValueToNSDictionary(const base::DictionaryValue& value);
|
||||
|
||||
scoped_ptr<base::DictionaryValue> NSDictionaryToDictionaryValue(
|
||||
NSDictionary* dict);
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_MAC_DICT_UTIL_H_
|
42
atom/browser/mac/dict_util.mm
Normal file
42
atom/browser/mac/dict_util.mm
Normal file
|
@ -0,0 +1,42 @@
|
|||
// Copyright (c) 2016 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/browser/mac/dict_util.h"
|
||||
|
||||
#include "base/mac/scoped_nsobject.h"
|
||||
#include "base/json/json_reader.h"
|
||||
#include "base/json/json_writer.h"
|
||||
#include "base/values.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
NSDictionary* DictionaryValueToNSDictionary(const base::DictionaryValue& value) {
|
||||
std::string json;
|
||||
if (!base::JSONWriter::Write(value, &json))
|
||||
return nil;
|
||||
NSData* jsonData = [NSData dataWithBytes:json.c_str() length:json.length()];
|
||||
id obj = [NSJSONSerialization JSONObjectWithData:jsonData
|
||||
options:0
|
||||
error:nil];
|
||||
if (![obj isKindOfClass:[NSDictionary class]])
|
||||
return nil;
|
||||
return obj;
|
||||
}
|
||||
|
||||
scoped_ptr<base::DictionaryValue> NSDictionaryToDictionaryValue(
|
||||
NSDictionary* dict) {
|
||||
NSData* data = [NSJSONSerialization dataWithJSONObject:dict
|
||||
options:0
|
||||
error:nil];
|
||||
if (!data)
|
||||
return nullptr;
|
||||
|
||||
base::scoped_nsobject<NSString> json =
|
||||
[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
|
||||
scoped_ptr<base::Value> value =
|
||||
base::JSONReader::Read([json UTF8String]);
|
||||
return base::DictionaryValue::From(std::move(value));
|
||||
}
|
||||
|
||||
} // namespace atom
|
|
@ -6,7 +6,6 @@
|
|||
#include <string>
|
||||
|
||||
#include "atom/common/crash_reporter/crash_reporter.h"
|
||||
#include "atom/common/native_mate_converters/string_map_converter.h"
|
||||
#include "base/bind.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
|
||||
|
@ -16,6 +15,24 @@ using crash_reporter::CrashReporter;
|
|||
|
||||
namespace mate {
|
||||
|
||||
template<>
|
||||
struct Converter<std::map<std::string, std::string> > {
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
std::map<std::string, std::string>* out) {
|
||||
if (!val->IsObject())
|
||||
return false;
|
||||
|
||||
v8::Local<v8::Object> dict = val->ToObject();
|
||||
v8::Local<v8::Array> keys = dict->GetOwnPropertyNames();
|
||||
for (uint32_t i = 0; i < keys->Length(); ++i) {
|
||||
v8::Local<v8::Value> key = keys->Get(i);
|
||||
(*out)[V8ToString(key)] = V8ToString(dict->Get(key));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct Converter<CrashReporter::UploadReportResult> {
|
||||
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
||||
|
|
|
@ -1,36 +0,0 @@
|
|||
// Copyright (c) 2014 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/common/native_mate_converters/string_map_converter.h"
|
||||
|
||||
namespace mate {
|
||||
|
||||
bool Converter<std::map<std::string, std::string>>::FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
std::map<std::string, std::string>* out) {
|
||||
if (!val->IsObject())
|
||||
return false;
|
||||
|
||||
v8::Local<v8::Object> dict = val->ToObject();
|
||||
v8::Local<v8::Array> keys = dict->GetOwnPropertyNames();
|
||||
for (uint32_t i = 0; i < keys->Length(); ++i) {
|
||||
v8::Local<v8::Value> key = keys->Get(i);
|
||||
(*out)[V8ToString(key)] = V8ToString(dict->Get(key));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> Converter<std::map<std::string, std::string>>::ToV8(
|
||||
v8::Isolate* isolate,
|
||||
const std::map<std::string, std::string>& in) {
|
||||
mate::Dictionary dict(isolate, v8::Object::New(isolate));
|
||||
|
||||
for (auto const &pair : in) {
|
||||
dict.Set(pair.first, pair.second);
|
||||
}
|
||||
|
||||
return dict.GetHandle();
|
||||
}
|
||||
|
||||
} // namespace mate
|
|
@ -1,28 +0,0 @@
|
|||
// Copyright (c) 2014 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ATOM_COMMON_NATIVE_MATE_CONVERTERS_STRING_MAP_CONVERTER_H_
|
||||
#define ATOM_COMMON_NATIVE_MATE_CONVERTERS_STRING_MAP_CONVERTER_H_
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
#include "native_mate/converter.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
|
||||
namespace mate {
|
||||
|
||||
template<>
|
||||
struct Converter<std::map<std::string, std::string>> {
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
std::map<std::string, std::string>* out);
|
||||
|
||||
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
||||
const std::map<std::string, std::string>& in);
|
||||
};
|
||||
|
||||
} // namespace mate
|
||||
|
||||
#endif // ATOM_COMMON_NATIVE_MATE_CONVERTERS_STRING_MAP_CONVERTER_H_
|
|
@ -116,17 +116,18 @@ the application's dock icon.
|
|||
Returns:
|
||||
|
||||
* `event` Event
|
||||
* `type` String - A string identifying the event. Maps to [`NSUserActivity.activityType`](https://developer.apple.com/library/ios/documentation/Foundation/Reference/NSUserActivity_Class/index.html#//apple_ref/occ/instp/NSUserActivity/activityType).
|
||||
* `type` String - A string identifying the activity. Maps to
|
||||
[`NSUserActivity.activityType`][activity-type].
|
||||
* `userInfo` Object - Contains app-specific state stored by the activity on
|
||||
another device. Currently only string data is supported.
|
||||
another device.
|
||||
|
||||
Emitted during [handoff](https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/Handoff/HandoffFundamentals/HandoffFundamentals.html) when an activity from a different device wants to be
|
||||
resumed. You should call `event.preventDefault()` if you want to handle this
|
||||
event.
|
||||
Emitted during [Handoff][handoff] when an activity from a different device wants
|
||||
to be resumed. You should call `event.preventDefault()` if you want to handle
|
||||
this event.
|
||||
|
||||
A user activity can be continued only in an app that has the same developer
|
||||
Team ID as the activity's source app and that supports the activity's type.
|
||||
Supported activity types are specified in the app's Info.plist under the
|
||||
A user activity can be continued only in an app that has the same developer Team
|
||||
ID as the activity's source app and that supports the activity's type.
|
||||
Supported activity types are specified in the app's `Info.plist` under the
|
||||
`NSUserActivityTypes` key.
|
||||
|
||||
### Event: 'browser-window-blur'
|
||||
|
@ -502,13 +503,12 @@ app.on('ready', function() {
|
|||
|
||||
### `app.setUserActivity(type, userInfo)` _OS X_
|
||||
|
||||
* `type` String - Uniquely identifies the activity. It's recommended to use a
|
||||
reverse-DNS string.
|
||||
* `type` String - Uniquely identifies the activity. Maps to
|
||||
[`NSUserActivity.activityType`][activity-type].
|
||||
* `userInfo` Object - App-specific state to store for use by another device.
|
||||
Currently only string data is supported.
|
||||
|
||||
Creates an `NSUserActivity` and sets it as the current activity. The activity
|
||||
is eligible for [handoff](https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/Handoff/HandoffFundamentals/HandoffFundamentals.html) to another device afterward.
|
||||
is eligible for [Handoff][handoff] to another device afterward.
|
||||
|
||||
### `app.getCurrentActivityType()` _OS X_
|
||||
|
||||
|
@ -600,5 +600,6 @@ Sets the `image` associated with this dock icon.
|
|||
[tasks]:http://msdn.microsoft.com/en-us/library/windows/desktop/dd378460(v=vs.85).aspx#tasks
|
||||
[app-user-model-id]: https://msdn.microsoft.com/en-us/library/windows/desktop/dd378459(v=vs.85).aspx
|
||||
[CFBundleURLTypes]: https://developer.apple.com/library/ios/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html#//apple_ref/doc/uid/TP40009249-102207-TPXREF115
|
||||
[LSCopyDefaultHandlerForURLScheme]:
|
||||
https://developer.apple.com/library/mac/documentation/Carbon/Reference/LaunchServicesReference/#//apple_ref/c/func/LSCopyDefaultHandlerForURLScheme
|
||||
[LSCopyDefaultHandlerForURLScheme]: https://developer.apple.com/library/mac/documentation/Carbon/Reference/LaunchServicesReference/#//apple_ref/c/func/LSCopyDefaultHandlerForURLScheme
|
||||
[handoff]: https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/Handoff/HandoffFundamentals/HandoffFundamentals.html
|
||||
[activity-type]: https://developer.apple.com/library/ios/documentation/Foundation/Reference/NSUserActivity_Class/index.html#//apple_ref/occ/instp/NSUserActivity/activityType
|
||||
|
|
|
@ -183,6 +183,8 @@
|
|||
'atom/browser/mac/atom_application.mm',
|
||||
'atom/browser/mac/atom_application_delegate.h',
|
||||
'atom/browser/mac/atom_application_delegate.mm',
|
||||
'atom/browser/mac/dict_util.h',
|
||||
'atom/browser/mac/dict_util.mm',
|
||||
'atom/browser/native_window.cc',
|
||||
'atom/browser/native_window.h',
|
||||
'atom/browser/native_window_views_win.cc',
|
||||
|
@ -361,8 +363,6 @@
|
|||
'atom/common/native_mate_converters/image_converter.h',
|
||||
'atom/common/native_mate_converters/net_converter.cc',
|
||||
'atom/common/native_mate_converters/net_converter.h',
|
||||
'atom/common/native_mate_converters/string_map_converter.cc',
|
||||
'atom/common/native_mate_converters/string_map_converter.h',
|
||||
'atom/common/native_mate_converters/string16_converter.h',
|
||||
'atom/common/native_mate_converters/ui_base_types_converter.h',
|
||||
'atom/common/native_mate_converters/v8_value_converter.cc',
|
||||
|
|
|
@ -91,7 +91,7 @@ describe('app module', function () {
|
|||
})
|
||||
|
||||
describe('app.setUserActivity(type, userInfo)', function () {
|
||||
if (isCI && process.platform !== 'darwin') {
|
||||
if (process.platform !== 'darwin') {
|
||||
return
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue