From 60bd60e1ed765c7e4c3d6872857ed6f4cc74176d Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 5 May 2016 16:26:44 +0900 Subject: [PATCH] Fully support converting NSDictionary to JS userInfo object --- atom/browser/api/atom_api_app.cc | 2 +- atom/browser/api/atom_api_app.h | 3 +- atom/browser/browser.cc | 13 ------ atom/browser/browser.h | 8 ++-- atom/browser/browser_mac.mm | 35 ++++++++-------- atom/browser/browser_observer.h | 7 +++- atom/browser/mac/atom_application_delegate.mm | 18 ++++---- atom/browser/mac/dict_util.h | 26 ++++++++++++ atom/browser/mac/dict_util.mm | 42 +++++++++++++++++++ filenames.gypi | 2 + 10 files changed, 105 insertions(+), 51 deletions(-) create mode 100644 atom/browser/mac/dict_util.h create mode 100644 atom/browser/mac/dict_util.mm diff --git a/atom/browser/api/atom_api_app.cc b/atom/browser/api/atom_api_app.cc index d573ac72793..3652f142a74 100644 --- a/atom/browser/api/atom_api_app.cc +++ b/atom/browser/api/atom_api_app.cc @@ -254,7 +254,7 @@ void App::OnFinishLaunching() { void App::OnContinueUserActivity( bool* prevent_default, const std::string& type, - const std::map& user_info) { + const base::DictionaryValue& user_info) { *prevent_default = Emit("continue-activity", type, user_info); } #endif diff --git a/atom/browser/api/atom_api_app.h b/atom/browser/api/atom_api_app.h index acc3071aec7..edfd09c4d28 100644 --- a/atom/browser/api/atom_api_app.h +++ b/atom/browser/api/atom_api_app.h @@ -6,7 +6,6 @@ #define ATOM_BROWSER_API_ATOM_API_APP_H_ #include -#include #include "atom/browser/api/event_emitter.h" #include "atom/browser/atom_browser_client.h" @@ -76,7 +75,7 @@ class App : public AtomBrowserClient::Delegate, void OnContinueUserActivity( bool* prevent_default, const std::string& type, - const std::map& user_info) override; + const base::DictionaryValue& user_info) override; #endif // content::ContentBrowserClient: diff --git a/atom/browser/browser.cc b/atom/browser/browser.cc index 9fb0fc6beca..093209ef7c4 100644 --- a/atom/browser/browser.cc +++ b/atom/browser/browser.cc @@ -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& 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()); } diff --git a/atom/browser/browser.h b/atom/browser/browser.h index 1c9e5775fd7..eb8d2865ad8 100644 --- a/atom/browser/browser.h +++ b/atom/browser/browser.h @@ -7,7 +7,6 @@ #include #include -#include #include "base/macros.h" #include "base/compiler_specific.h" @@ -95,15 +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& 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& user_info); + bool ContinueUserActivity(const std::string& type, + const base::DictionaryValue& user_info); // Bounce the dock icon. enum BounceType { diff --git a/atom/browser/browser_mac.mm b/atom/browser/browser_mac.mm index 74002db4cc8..bb4cd2dda80 100644 --- a/atom/browser/browser_mac.mm +++ b/atom/browser/browser_mac.mm @@ -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" @@ -89,24 +90,14 @@ void Browser::SetAppUserModelID(const base::string16& name) { void Browser::SetUserActivity( const std::string& type, - const std::map& user_info) { - NSString* type_ns = [NSString stringWithUTF8String:type.c_str()]; - NSUserActivity* user_activity = - [[NSUserActivity alloc] initWithActivityType:type_ns]; + const base::DictionaryValue& user_info) { + NSString* nstype = [NSString stringWithUTF8String:type.c_str()]; + NSUserActivity* userActivity = + [[NSUserActivity alloc] initWithActivityType:nstype]; + userActivity.userInfo = DictionaryValueToNSDictionary(user_info); + [userActivity becomeCurrent]; - base::scoped_nsobject 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]; + [[AtomApplication sharedApplication] setCurrentActivity:userActivity]; } std::string Browser::GetCurrentActivityType() { @@ -115,6 +106,16 @@ std::string Browser::GetCurrentActivityType() { return base::SysNSStringToUTF8(user_activity.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 { return brightray::GetApplicationVersion(); } diff --git a/atom/browser/browser_observer.h b/atom/browser/browser_observer.h index 03257c48d0c..c8b0082beb7 100644 --- a/atom/browser/browser_observer.h +++ b/atom/browser/browser_observer.h @@ -6,10 +6,13 @@ #define ATOM_BROWSER_BROWSER_OBSERVER_H_ #include -#include #include "build/build_config.h" +namespace base { +class DictionaryValue; +} + namespace atom { class LoginHandler; @@ -53,7 +56,7 @@ class BrowserObserver { virtual void OnContinueUserActivity( bool* prevent_default, const std::string& type, - const std::map& user_info) {} + const base::DictionaryValue& user_info) {} #endif protected: diff --git a/atom/browser/mac/atom_application_delegate.mm b/atom/browser/mac/atom_application_delegate.mm index 8b7853e0d84..7fa3b3027f6 100644 --- a/atom/browser/mac/atom_application_delegate.mm +++ b/atom/browser/mac/atom_application_delegate.mm @@ -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 @@ -63,19 +65,13 @@ continueUserActivity:(NSUserActivity*)userActivity restorationHandler:(void (^)(NSArray*restorableObjects))restorationHandler { std::string activity_type(base::SysNSStringToUTF8(userActivity.activityType)); - - std::map user_info; - base::scoped_nsobject 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 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 diff --git a/atom/browser/mac/dict_util.h b/atom/browser/mac/dict_util.h new file mode 100644 index 00000000000..e5b293652d8 --- /dev/null +++ b/atom/browser/mac/dict_util.h @@ -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 + +#include "base/memory/scoped_ptr.h" + +namespace base { +class Value; +class DictionaryValue; +} + +namespace atom { + +NSDictionary* DictionaryValueToNSDictionary(const base::DictionaryValue& value); + +scoped_ptr NSDictionaryToDictionaryValue( + NSDictionary* dict); + +} // namespace atom + +#endif // ATOM_BROWSER_MAC_DICT_UTIL_H_ diff --git a/atom/browser/mac/dict_util.mm b/atom/browser/mac/dict_util.mm new file mode 100644 index 00000000000..6a98e4cfdaa --- /dev/null +++ b/atom/browser/mac/dict_util.mm @@ -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 NSDictionaryToDictionaryValue( + NSDictionary* dict) { + NSData* data = [NSJSONSerialization dataWithJSONObject:dict + options:0 + error:nil]; + if (!data) + return nullptr; + + base::scoped_nsobject json = + [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; + scoped_ptr value = + base::JSONReader::Read([json UTF8String]); + return base::DictionaryValue::From(std::move(value)); +} + +} // namespace atom diff --git a/filenames.gypi b/filenames.gypi index f0e3942a5e2..a6d3314135a 100644 --- a/filenames.gypi +++ b/filenames.gypi @@ -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',