Upstream version 6.35.121.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / app_list / search / people / people_result.cc
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/ui/app_list/search/people/people_result.h"
6
7 #include <vector>
8
9 #include "base/bind.h"
10 #include "base/memory/ref_counted.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "chrome/browser/profiles/profile.h"
13 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
14 #include "chrome/browser/signin/signin_manager.h"
15 #include "chrome/browser/signin/signin_manager_factory.h"
16 #include "chrome/browser/ui/app_list/search/common/url_icon_source.h"
17 #include "chrome/browser/ui/app_list/search/people/person.h"
18 #include "chrome/browser/ui/browser_navigator.h"
19 #include "chrome/common/extensions/api/hangouts_private.h"
20 #include "components/signin/core/browser/profile_oauth2_token_service.h"
21 #include "content/public/browser/user_metrics.h"
22 #include "extensions/browser/event_router.h"
23 #include "extensions/browser/extension_system.h"
24 #include "grit/generated_resources.h"
25 #include "grit/theme_resources.h"
26 #include "ui/base/l10n/l10n_util.h"
27 #include "ui/base/resource/resource_bundle.h"
28
29 namespace OnHangoutRequested =
30     extensions::api::hangouts_private::OnHangoutRequested;
31
32 using extensions::api::hangouts_private::User;
33 using extensions::api::hangouts_private::HangoutRequest;
34
35 namespace {
36
37 const int kIconSize = 32;
38 const char kImageSizePath[] = "s32-p/";
39 const char kEmailUrlPrefix[] = "mailto:";
40
41 const char* const kHangoutsExtensionIds[] = {
42   "nckgahadagoaajjgafhacjanaoiihapd",
43   "ljclpkphhpbpinifbeabbhlfddcpfdde",
44   "ppleadejekpmccmnpjdimmlfljlkdfej",
45   "eggnbpckecmjlblplehfpjjdhhidfdoj"
46 };
47
48 // Add a query parameter to specify the size to fetch the image in. The
49 // original profile image can be of an arbitrary size, we ask the server to
50 // crop it to a square 32x32 using its smart cropping algorithm.
51 GURL GetImageUrl(const GURL& url) {
52   std::string image_filename = url.ExtractFileName();
53   if (image_filename.empty())
54     return url;
55
56   return url.Resolve(kImageSizePath + image_filename);
57 }
58
59 }  // namespace
60
61 namespace app_list {
62
63 PeopleResult::PeopleResult(Profile* profile, scoped_ptr<Person> person)
64     : profile_(profile), person_(person.Pass()), weak_factory_(this) {
65   set_id(person_->id);
66   set_title(base::UTF8ToUTF16(person_->display_name));
67   set_relevance(person_->interaction_rank);
68   set_details(base::UTF8ToUTF16(person_->email));
69
70   RefreshHangoutsExtensionId();
71   SetDefaultActions();
72
73   image_ = gfx::ImageSkia(
74       new UrlIconSource(base::Bind(&PeopleResult::OnIconLoaded,
75                                    weak_factory_.GetWeakPtr()),
76                         profile_->GetRequestContext(),
77                         GetImageUrl(person_->image_url),
78                         kIconSize,
79                         IDR_PROFILE_PICTURE_LOADING),
80       gfx::Size(kIconSize, kIconSize));
81   SetIcon(image_);
82 }
83
84 PeopleResult::~PeopleResult() {
85 }
86
87 void PeopleResult::Open(int event_flags) {
88   // Action 0 will always be our default action.
89   InvokeAction(0, event_flags);
90 }
91
92 void PeopleResult::InvokeAction(int action_index, int event_flags) {
93   if (hangouts_extension_id_.empty()) {
94     // If the hangouts app is not available, the only option we are showing
95     // to the user is 'Send Email'.
96     SendEmail();
97   } else {
98     switch (action_index) {
99       case 0:
100         OpenChat();
101         break;
102       case 1:
103         SendEmail();
104         break;
105       default:
106         LOG(ERROR) << "Invalid people search action: " << action_index;
107     }
108   }
109 }
110
111 scoped_ptr<ChromeSearchResult> PeopleResult::Duplicate() {
112   return scoped_ptr<ChromeSearchResult>(
113       new PeopleResult(profile_, person_->Duplicate().Pass())).Pass();
114 }
115
116 void PeopleResult::OnIconLoaded() {
117   // Remove the existing image reps since the icon data is loaded and they
118   // need to be re-created.
119   const std::vector<gfx::ImageSkiaRep>& image_reps = image_.image_reps();
120   for (size_t i = 0; i < image_reps.size(); ++i)
121     image_.RemoveRepresentation(image_reps[i].scale());
122
123   SetIcon(image_);
124 }
125
126 void PeopleResult::SetDefaultActions() {
127   Actions actions;
128
129   ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance();
130   if (!hangouts_extension_id_.empty()) {
131     actions.push_back(Action(
132         *bundle.GetImageSkiaNamed(IDR_PEOPLE_SEARCH_ACTION_CHAT),
133         *bundle.GetImageSkiaNamed(IDR_PEOPLE_SEARCH_ACTION_CHAT_HOVER),
134         *bundle.GetImageSkiaNamed(IDR_PEOPLE_SEARCH_ACTION_CHAT_PRESSED),
135         l10n_util::GetStringUTF16(IDS_PEOPLE_SEARCH_ACTION_CHAT_TOOLTIP)));
136   }
137   actions.push_back(Action(
138       *bundle.GetImageSkiaNamed(IDR_PEOPLE_SEARCH_ACTION_EMAIL),
139       *bundle.GetImageSkiaNamed(IDR_PEOPLE_SEARCH_ACTION_EMAIL_HOVER),
140       *bundle.GetImageSkiaNamed(IDR_PEOPLE_SEARCH_ACTION_EMAIL_PRESSED),
141       l10n_util::GetStringUTF16(IDS_PEOPLE_SEARCH_ACTION_EMAIL_TOOLTIP)));
142   SetActions(actions);
143 }
144
145 void PeopleResult::OpenChat() {
146   HangoutRequest request;
147
148   request.type = extensions::api::hangouts_private::HANGOUT_TYPE_CHAT;
149
150   // from: the user this chat request is originating from.
151   SigninManagerBase* signin_manager =
152       SigninManagerFactory::GetInstance()->GetForProfile(profile_);
153   DCHECK(signin_manager);
154   request.from = signin_manager->GetAuthenticatedAccountId();
155
156   // to: list of users with whom to start this hangout is with.
157   linked_ptr<User> target(new User());
158   target->id = person_->owner_id;
159   request.to.push_back(target);
160
161   scoped_ptr<extensions::Event> event(
162       new extensions::Event(OnHangoutRequested::kEventName,
163                             OnHangoutRequested::Create(request)));
164
165   // TODO(rkc): Change this once we remove the hangoutsPrivate API.
166   // See crbug.com/306672
167   extensions::ExtensionSystem::Get(
168       profile_)->event_router()->DispatchEventToExtension(
169           hangouts_extension_id_, event.Pass());
170
171   content::RecordAction(base::UserMetricsAction("PeopleSearch_OpenChat"));
172 }
173
174 void PeopleResult::SendEmail() {
175   chrome::NavigateParams params(profile_,
176                                 GURL(kEmailUrlPrefix + person_->email),
177                                 content::PAGE_TRANSITION_LINK);
178   // If no window exists, this will open a new window this one tab.
179   params.disposition = NEW_FOREGROUND_TAB;
180   chrome::Navigate(&params);
181   content::RecordAction(base::UserMetricsAction("PeopleSearch_SendEmail"));
182 }
183
184 void PeopleResult::RefreshHangoutsExtensionId() {
185   // TODO(rkc): Change this once we remove the hangoutsPrivate API.
186   // See crbug.com/306672
187   for (size_t i = 0; i < arraysize(kHangoutsExtensionIds); ++i) {
188     if (extensions::ExtensionSystem::Get(
189         profile_)->event_router()->ExtensionHasEventListener(
190             kHangoutsExtensionIds[i], OnHangoutRequested::kEventName)) {
191       hangouts_extension_id_ = kHangoutsExtensionIds[i];
192       return;
193     }
194   }
195   hangouts_extension_id_.clear();
196 }
197
198 ChromeSearchResultType PeopleResult::GetType() {
199   return SEARCH_PEOPLE_SEARCH_RESULT;
200 }
201
202 }  // namespace app_list