Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(288)

Side by Side Diff: chrome/browser/ui/google_now/google_now_service.cc

Issue 11633013: Parsing server response and showing notifications for Google Now (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/ui/google_now/google_now_service.h" 5 #include "chrome/browser/ui/google_now/google_now_service.h"
6 6
7 #include "base/command_line.h" 7 #include "base/command_line.h"
8 #include "base/json/json_reader.h"
9 #include "base/memory/scoped_vector.h"
10 #include "base/utf_string_conversions.h"
11 #include "base/values.h"
12 #include "chrome/browser/browser_process.h"
13 #include "chrome/browser/notifications/notification.h"
14 #include "chrome/browser/notifications/notification_ui_manager.h"
8 #include "chrome/browser/profiles/profile.h" 15 #include "chrome/browser/profiles/profile.h"
16 #include "chrome/browser/ui/google_now/google_now_notification_delegate.h"
9 #include "chrome/common/chrome_switches.h" 17 #include "chrome/common/chrome_switches.h"
18 #include "chrome/common/extensions/api/experimental_notification.h"
10 #include "content/public/browser/geolocation.h" 19 #include "content/public/browser/geolocation.h"
11 #include "content/public/common/geoposition.h" 20 #include "content/public/common/geoposition.h"
12 #include "net/http/http_status_code.h" 21 #include "net/http/http_status_code.h"
13 #include "net/url_request/url_fetcher.h" 22 #include "net/url_request/url_fetcher.h"
14 #include "net/url_request/url_request_context.h" 23 #include "net/url_request/url_request_context.h"
15 24
16 using base::Bind; 25 using base::Bind;
26 using base::JSONReader;
17 using base::TimeDelta; 27 using base::TimeDelta;
28 using base::Value;
18 using content::Geoposition; 29 using content::Geoposition;
30 using extensions::api::experimental_notification::ShowOptions;
19 using net::HTTP_OK; 31 using net::HTTP_OK;
20 using net::URLFetcher; 32 using net::URLFetcher;
21 using net::URLRequestStatus; 33 using net::URLRequestStatus;
22 34
23 namespace { 35 namespace {
24 // TODO(vadimt): Figure out the values of the constants. 36 // TODO(vadimt): Figure out the values of the constants.
25 37
26 // Period for polling for Google Now cards to use when the period from the 38 // Period for polling for Google Now cards to use when the period from the
27 // server is not available. 39 // server is not available.
28 // TODO(vadimt): Figure out the consequences for LBS and battery. 40 // TODO(vadimt): Figure out the consequences for LBS and battery.
29 // TODO(vadimt): Consider triggers other than the timer for refreshing the 41 // TODO(vadimt): Consider triggers other than the timer for refreshing the
30 // position, such as waking from sleep. 42 // position, such as waking from sleep.
31 const int kDefaultPollingPeriodMs = 300000; // 5 minutes 43 const int kDefaultPollingPeriodMs = 300000; // 5 minutes
32 // Time allocated to a geolocation request. 44 // Time allocated to a geolocation request.
33 const int kGeolocationRequestTimeoutMs = 60000; // 1 minute 45 const int kGeolocationRequestTimeoutMs = 60000; // 1 minute
46 // JSON key for expiration timestamp.
47 const char kExpirationTimestampKey[] = "expiration_timestamp_seconds";
48 // JSON key for cards.
49 const char kCardsKey[] = "cards";
34 } // namespace 50 } // namespace
35 51
52 // Google Now cards in the server response.
53 typedef ScopedVector<ShowOptions> ParsedCards;
54
36 struct GoogleNowService::ServerResponse { 55 struct GoogleNowService::ServerResponse {
37 // TODO(vadimt): Populate this structure with real fields. 56 ParsedCards cards;
38 TimeDelta next_request_delay; 57 TimeDelta next_request_delay;
39 }; 58 };
40 59
41 GoogleNowService::GoogleNowService(Profile* profile) 60 GoogleNowService::GoogleNowService(Profile* profile)
42 : profile_(profile), 61 : profile_(profile),
43 ALLOW_THIS_IN_INITIALIZER_LIST(geolocation_request_weak_factory_(this)) { 62 ALLOW_THIS_IN_INITIALIZER_LIST(geolocation_request_weak_factory_(this)) {
44 DCHECK(profile_); 63 DCHECK(profile_);
45 } 64 }
46 65
47 GoogleNowService::~GoogleNowService() { 66 GoogleNowService::~GoogleNowService() {
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
151 fetcher_->SetRequestContext(profile_->GetRequestContext()); 170 fetcher_->SetRequestContext(profile_->GetRequestContext());
152 fetcher_->SetLoadFlags( 171 fetcher_->SetLoadFlags(
153 net::LOAD_BYPASS_CACHE | net::LOAD_DISABLE_CACHE | 172 net::LOAD_BYPASS_CACHE | net::LOAD_DISABLE_CACHE |
154 net::LOAD_DO_NOT_SAVE_COOKIES); 173 net::LOAD_DO_NOT_SAVE_COOKIES);
155 174
156 fetcher_->Start(); 175 fetcher_->Start();
157 } 176 }
158 177
159 bool GoogleNowService::ParseServerResponse(const std::string& response_string, 178 bool GoogleNowService::ParseServerResponse(const std::string& response_string,
160 ServerResponse* server_response) { 179 ServerResponse* server_response) {
161 // TODO(vadimt): Do real parsing. 180 // Server response is in JSON format.
181 scoped_ptr<Value> value(JSONReader::Read(response_string));
182
183 if (value == NULL)
184 return false;
185
186 const DictionaryValue* root;
187 if (!value->GetAsDictionary(&root))
188 return false;
189
190 int expiration_timestamp_seconds;
191 if (!root->GetInteger(kExpirationTimestampKey,
192 &expiration_timestamp_seconds)) {
193 return false;
194 }
195
162 server_response->next_request_delay = 196 server_response->next_request_delay =
163 TimeDelta::FromMilliseconds(kDefaultPollingPeriodMs); 197 TimeDelta::FromSeconds(expiration_timestamp_seconds);
198
199 const ListValue* cards;
200 if (!root->GetList(kCardsKey, &cards))
201 return false;
202
203 for (size_t index = 0; index < cards->GetSize(); ++index) {
204 const base::DictionaryValue* card;
205 if (!cards->GetDictionary(index, &card))
206 return false;
207
208 scoped_ptr<ShowOptions> show_options(new ShowOptions());
209
210 if (!ShowOptions::Populate(*card, show_options.get()))
211 return false;
212
213 server_response->cards.push_back(show_options.release());
214 }
215
164 return true; 216 return true;
165 } 217 }
166 218
167 void GoogleNowService::ShowNotifications( 219 void GoogleNowService::ShowNotifications(
168 const ServerResponse& server_response) { 220 const ServerResponse& server_response) {
169 // TODO(vadimt): Implement using Chrome Notifications. 221 // TODO(vadimt): Most of the code below duplicates the code in
222 // NotificationShowFunction::RunImpl. Once we finally decide the format of the
223 // server response, remove the duplication. Before this, keep this code in
224 // sync with its origin.
225 for (ParsedCards::const_iterator it = server_response.cards.begin();
226 it != server_response.cards.end();
227 ++it) {
228 ShowOptions* show_options = *it;
229
230 ui::notifications::NotificationType type =
231 ui::notifications::StringToNotificationType(show_options->type);
232 GURL icon_url(UTF8ToUTF16(show_options->icon_url));
233 string16 title(UTF8ToUTF16(show_options->title));
234 string16 message(UTF8ToUTF16(show_options->message));
235
236 scoped_ptr<DictionaryValue> optional_fields(new DictionaryValue());
237
238 // For all notification types.
239 if (show_options->priority.get())
240 optional_fields->SetInteger(ui::notifications::kPriorityKey,
241 *show_options->priority);
242 if (show_options->timestamp.get())
243 optional_fields->SetString(ui::notifications::kTimestampKey,
244 *show_options->timestamp);
245 if (show_options->second_icon_url.get())
246 optional_fields->SetString(ui::notifications::kSecondIconUrlKey,
247 UTF8ToUTF16(*show_options->second_icon_url));
248 if (show_options->unread_count.get())
249 optional_fields->SetInteger(ui::notifications::kUnreadCountKey,
250 *show_options->unread_count);
251 if (show_options->button_one_title.get())
252 optional_fields->SetString(ui::notifications::kButtonOneTitleKey,
253 UTF8ToUTF16(*show_options->button_one_title));
254 if (show_options->button_two_title.get())
255 optional_fields->SetString(ui::notifications::kButtonTwoTitleKey,
256 UTF8ToUTF16(*show_options->button_two_title));
257 if (show_options->expanded_message.get())
258 optional_fields->SetString(ui::notifications::kExpandedMessageKey,
259 UTF8ToUTF16(*show_options->expanded_message));
260
261 // For image notifications (type == 'image').
262 if (show_options->image_url.get())
263 optional_fields->SetString(ui::notifications::kImageUrlKey,
264 UTF8ToUTF16(*show_options->image_url));
265
266 // For multiple-item notifications (type == 'multiple').
267 if (show_options->items.get()) {
268 base::ListValue* items = new base::ListValue();
269 std::vector<
270 linked_ptr<
271 extensions::api::experimental_notification::NotificationItem> >::
272 iterator i;
273 for (i = show_options->items->begin();
274 i != show_options->items->end();
275 ++i) {
276 base::DictionaryValue* item = new base::DictionaryValue();
277 item->SetString(ui::notifications::kItemTitleKey,
278 UTF8ToUTF16(i->get()->title));
279 item->SetString(ui::notifications::kItemMessageKey,
280 UTF8ToUTF16(i->get()->message));
281 items->Append(item);
282 }
283 optional_fields->Set(ui::notifications::kItemsKey, items);
284 }
285
286 string16 replace_id(UTF8ToUTF16(show_options->replace_id));
287
288 Notification notification(type, icon_url, title, message,
289 WebKit::WebTextDirectionDefault,
290 string16(), replace_id,
291 optional_fields.get(),
292 new GoogleNowNotificationDelegate());
293 g_browser_process->notification_ui_manager()->Add(notification, profile_);
294 }
170 } 295 }
171 296
172 void GoogleNowService::OnURLFetchComplete(const net::URLFetcher* source) { 297 void GoogleNowService::OnURLFetchComplete(const net::URLFetcher* source) {
173 DCHECK(source != NULL); 298 DCHECK(source != NULL);
174 DCHECK(IsGoogleNowEnabled()); 299 DCHECK(IsGoogleNowEnabled());
175 DCHECK(!next_update_timer_.IsRunning()); 300 DCHECK(!next_update_timer_.IsRunning());
176 DCHECK(!geolocation_request_timer_.IsRunning()); 301 DCHECK(!geolocation_request_timer_.IsRunning());
177 DCHECK(!geolocation_request_weak_factory_.HasWeakPtrs()); 302 DCHECK(!geolocation_request_weak_factory_.HasWeakPtrs());
178 DCHECK(fetcher_.get() == source); 303 DCHECK(fetcher_.get() == source);
179 304
(...skipping 11 matching lines...) Expand all
191 if (ParseServerResponse(response_string, &server_response)) { 316 if (ParseServerResponse(response_string, &server_response)) {
192 ShowNotifications(server_response); 317 ShowNotifications(server_response);
193 next_request_delay = server_response.next_request_delay; 318 next_request_delay = server_response.next_request_delay;
194 } 319 }
195 } 320 }
196 } 321 }
197 322
198 fetcher_.reset(NULL); 323 fetcher_.reset(NULL);
199 StartWaitingForNextUpdate(next_request_delay); 324 StartWaitingForNextUpdate(next_request_delay);
200 } 325 }
OLDNEW
« no previous file with comments | « chrome/browser/ui/google_now/google_now_notification_delegate.cc ('k') | chrome/chrome_browser_ui.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698