Browse Source

Fully support converting NSDictionary to JS userInfo object

Cheng Zhao 9 years ago
parent
commit
60bd60e1ed

+ 1 - 1
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<std::string, std::string>& user_info) {
+    const base::DictionaryValue& user_info) {
   *prevent_default = Emit("continue-activity", type, user_info);
 }
 #endif

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

@@ -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"
@@ -76,7 +75,7 @@ class App : public AtomBrowserClient::Delegate,
   void OnContinueUserActivity(
       bool* prevent_default,
       const std::string& type,
-      const std::map<std::string, std::string>& user_info) override;
+      const base::DictionaryValue& user_info) override;
 #endif
 
   // content::ContentBrowserClient:

+ 0 - 13
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<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());
 }

+ 3 - 5
atom/browser/browser.h

@@ -7,7 +7,6 @@
 
 #include <string>
 #include <vector>
-#include <map>
 
 #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<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);
+  bool ContinueUserActivity(const std::string& type,
+                            const base::DictionaryValue& user_info);
 
   // Bounce the dock icon.
   enum BounceType {

+ 18 - 17
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<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];
-  }
+    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];
 
-  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();
 }

+ 5 - 2
atom/browser/browser_observer.h

@@ -6,10 +6,13 @@
 #define ATOM_BROWSER_BROWSER_OBSERVER_H_
 
 #include <string>
-#include <map>
 
 #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<std::string, std::string>& user_info) {}
+      const base::DictionaryValue& user_info) {}
 #endif
 
  protected:

+ 7 - 11
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<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 - 0
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 <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 - 0
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<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

+ 2 - 0
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',