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