Index: chrome/browser/ui/google_now/google_now_service.cc |
diff --git a/chrome/browser/ui/google_now/google_now_service.cc b/chrome/browser/ui/google_now/google_now_service.cc |
index e6e91771ae5177156b356ae6738d4a55906b1f94..0d334509d7ea6156735dc211fcc4c000ceca1781 100644 |
--- a/chrome/browser/ui/google_now/google_now_service.cc |
+++ b/chrome/browser/ui/google_now/google_now_service.cc |
@@ -5,8 +5,17 @@ |
#include "chrome/browser/ui/google_now/google_now_service.h" |
#include "base/command_line.h" |
+#include "base/json/json_reader.h" |
+#include "base/memory/scoped_vector.h" |
+#include "base/utf_string_conversions.h" |
+#include "base/values.h" |
+#include "chrome/browser/browser_process.h" |
+#include "chrome/browser/notifications/notification.h" |
+#include "chrome/browser/notifications/notification_ui_manager.h" |
#include "chrome/browser/profiles/profile.h" |
+#include "chrome/browser/ui/google_now/google_now_notification_delegate.h" |
#include "chrome/common/chrome_switches.h" |
+#include "chrome/common/extensions/api/experimental_notification.h" |
#include "content/public/browser/geolocation.h" |
#include "content/public/common/geoposition.h" |
#include "net/http/http_status_code.h" |
@@ -14,8 +23,11 @@ |
#include "net/url_request/url_request_context.h" |
using base::Bind; |
+using base::JSONReader; |
using base::TimeDelta; |
+using base::Value; |
using content::Geoposition; |
+using extensions::api::experimental_notification::ShowOptions; |
using net::HTTP_OK; |
using net::URLFetcher; |
using net::URLRequestStatus; |
@@ -31,10 +43,17 @@ namespace { |
const int kDefaultPollingPeriodMs = 300000; // 5 minutes |
// Time allocated to a geolocation request. |
const int kGeolocationRequestTimeoutMs = 60000; // 1 minute |
+// JSON key for expiration timestamp. |
+const char kExpirationTimestampKey[] = "expiration_timestamp_seconds"; |
+// JSON key for cards. |
+const char kCardsKey[] = "cards"; |
} // namespace |
+// Google Now cards in the server response. |
+typedef ScopedVector<ShowOptions> ParsedCards; |
+ |
struct GoogleNowService::ServerResponse { |
- // TODO(vadimt): Populate this structure with real fields. |
+ ParsedCards cards; |
TimeDelta next_request_delay; |
}; |
@@ -158,15 +177,121 @@ void GoogleNowService::StartServerRequest( |
bool GoogleNowService::ParseServerResponse(const std::string& response_string, |
ServerResponse* server_response) { |
- // TODO(vadimt): Do real parsing. |
+ // Server response is in JSON format. |
+ scoped_ptr<Value> value(JSONReader::Read(response_string)); |
+ |
+ if (value == NULL) |
+ return false; |
+ |
+ const DictionaryValue* root; |
+ if (!value->GetAsDictionary(&root)) |
+ return false; |
+ |
+ int expiration_timestamp_seconds; |
+ if (!root->GetInteger(kExpirationTimestampKey, |
+ &expiration_timestamp_seconds)) { |
+ return false; |
+ } |
+ |
server_response->next_request_delay = |
- TimeDelta::FromMilliseconds(kDefaultPollingPeriodMs); |
+ TimeDelta::FromSeconds(expiration_timestamp_seconds); |
+ |
+ const ListValue* cards; |
+ if (!root->GetList(kCardsKey, &cards)) |
+ return false; |
+ |
+ for (size_t index = 0; index < cards->GetSize(); ++index) { |
+ const base::DictionaryValue* card; |
+ if (!cards->GetDictionary(index, &card)) |
+ return false; |
+ |
+ scoped_ptr<ShowOptions> show_options(new ShowOptions()); |
+ |
+ if (!ShowOptions::Populate(*card, show_options.get())) |
+ return false; |
+ |
+ server_response->cards.push_back(show_options.release()); |
+ } |
+ |
return true; |
} |
void GoogleNowService::ShowNotifications( |
const ServerResponse& server_response) { |
- // TODO(vadimt): Implement using Chrome Notifications. |
+ // TODO(vadimt): Most of the code below duplicates the code in |
+ // NotificationShowFunction::RunImpl. Once we finally decide the format of the |
+ // server response, remove the duplication. Before this, keep this code in |
+ // sync with its origin. |
+ for (ParsedCards::const_iterator it = server_response.cards.begin(); |
+ it != server_response.cards.end(); |
+ ++it) { |
+ ShowOptions* show_options = *it; |
+ |
+ ui::notifications::NotificationType type = |
+ ui::notifications::StringToNotificationType(show_options->type); |
+ GURL icon_url(UTF8ToUTF16(show_options->icon_url)); |
+ string16 title(UTF8ToUTF16(show_options->title)); |
+ string16 message(UTF8ToUTF16(show_options->message)); |
+ |
+ scoped_ptr<DictionaryValue> optional_fields(new DictionaryValue()); |
+ |
+ // For all notification types. |
+ if (show_options->priority.get()) |
+ optional_fields->SetInteger(ui::notifications::kPriorityKey, |
+ *show_options->priority); |
+ if (show_options->timestamp.get()) |
+ optional_fields->SetString(ui::notifications::kTimestampKey, |
+ *show_options->timestamp); |
+ if (show_options->second_icon_url.get()) |
+ optional_fields->SetString(ui::notifications::kSecondIconUrlKey, |
+ UTF8ToUTF16(*show_options->second_icon_url)); |
+ if (show_options->unread_count.get()) |
+ optional_fields->SetInteger(ui::notifications::kUnreadCountKey, |
+ *show_options->unread_count); |
+ if (show_options->button_one_title.get()) |
+ optional_fields->SetString(ui::notifications::kButtonOneTitleKey, |
+ UTF8ToUTF16(*show_options->button_one_title)); |
+ if (show_options->button_two_title.get()) |
+ optional_fields->SetString(ui::notifications::kButtonTwoTitleKey, |
+ UTF8ToUTF16(*show_options->button_two_title)); |
+ if (show_options->expanded_message.get()) |
+ optional_fields->SetString(ui::notifications::kExpandedMessageKey, |
+ UTF8ToUTF16(*show_options->expanded_message)); |
+ |
+ // For image notifications (type == 'image'). |
+ if (show_options->image_url.get()) |
+ optional_fields->SetString(ui::notifications::kImageUrlKey, |
+ UTF8ToUTF16(*show_options->image_url)); |
+ |
+ // For multiple-item notifications (type == 'multiple'). |
+ if (show_options->items.get()) { |
+ base::ListValue* items = new base::ListValue(); |
+ std::vector< |
+ linked_ptr< |
+ extensions::api::experimental_notification::NotificationItem> >:: |
+ iterator i; |
+ for (i = show_options->items->begin(); |
+ i != show_options->items->end(); |
+ ++i) { |
+ base::DictionaryValue* item = new base::DictionaryValue(); |
+ item->SetString(ui::notifications::kItemTitleKey, |
+ UTF8ToUTF16(i->get()->title)); |
+ item->SetString(ui::notifications::kItemMessageKey, |
+ UTF8ToUTF16(i->get()->message)); |
+ items->Append(item); |
+ } |
+ optional_fields->Set(ui::notifications::kItemsKey, items); |
+ } |
+ |
+ string16 replace_id(UTF8ToUTF16(show_options->replace_id)); |
+ |
+ Notification notification(type, icon_url, title, message, |
+ WebKit::WebTextDirectionDefault, |
+ string16(), replace_id, |
+ optional_fields.get(), |
+ new GoogleNowNotificationDelegate()); |
+ g_browser_process->notification_ui_manager()->Add(notification, profile_); |
+ } |
} |
void GoogleNowService::OnURLFetchComplete(const net::URLFetcher* source) { |