people_result.cc revision 8bcbed890bc3ce4d7a057a8f32cab53fa534672e
158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// found in the LICENSE file.
458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "chrome/browser/ui/app_list/search/people/people_result.h"
658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include <vector>
858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "base/bind.h"
1058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "base/memory/ref_counted.h"
1158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "base/strings/utf_string_conversions.h"
124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/browser/extensions/event_router.h"
134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/browser/extensions/extension_system.h"
1458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "chrome/browser/profiles/profile.h"
154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/browser/signin/profile_oauth2_token_service.h"
164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
1758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "chrome/browser/ui/app_list/search/common/url_icon_source.h"
184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/browser/ui/app_list/search/people/person.h"
1968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "chrome/browser/ui/browser_navigator.h"
204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/common/extensions/api/hangouts_private.h"
2168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "grit/generated_resources.h"
2258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "grit/theme_resources.h"
2358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "ui/base/l10n/l10n_util.h"
2468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "ui/base/resource/resource_bundle.h"
2558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)namespace OnHangoutRequested =
274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    extensions::api::hangouts_private::OnHangoutRequested;
284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)using extensions::api::hangouts_private::User;
304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)using extensions::api::hangouts_private::HangoutRequest;
314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)namespace {
3358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
3458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)const int kIconSize = 32;
3558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)const char kImageSizePath[] = "s32-p/";
3668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)const char kEmailUrlPrefix[] = "mailto:";
3758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
388bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)const char* const kHangoutsExtensionIds[] = {
398bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  "nckgahadagoaajjgafhacjanaoiihapd",
408bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  "ljclpkphhpbpinifbeabbhlfddcpfdde",
418bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  "ppleadejekpmccmnpjdimmlfljlkdfej",
428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  "eggnbpckecmjlblplehfpjjdhhidfdoj"
438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)};
444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// Add a query parameter to specify the size to fetch the image in. The
4658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// original profile image can be of an arbitrary size, we ask the server to
4758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// crop it to a square 32x32 using its smart cropping algorithm.
4858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)GURL GetImageUrl(const GURL& url) {
4958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  std::string image_filename = url.ExtractFileName();
5058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (image_filename.empty())
5158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return url;
5258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
5358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return url.Resolve(kImageSizePath + image_filename);
5458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
5558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
5658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}  // namespace
5758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
5858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)namespace app_list {
5958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)PeopleResult::PeopleResult(Profile* profile, scoped_ptr<Person> person)
614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    : profile_(profile), person_(person.Pass()), weak_factory_(this) {
624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  set_id(person_->id);
634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  set_title(UTF8ToUTF16(person_->display_name));
644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  set_relevance(person_->interaction_rank);
654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  set_details(UTF8ToUTF16(person_->email));
6668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  RefreshHangoutsExtensionId();
6868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  SetDefaultActions();
6958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
7058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  image_ = gfx::ImageSkia(
7158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      new UrlIconSource(base::Bind(&PeopleResult::OnIconLoaded,
7258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                   weak_factory_.GetWeakPtr()),
7358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                        profile_->GetRequestContext(),
744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                        GetImageUrl(person_->image_url),
7558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                        kIconSize,
7658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                        IDR_PROFILE_PICTURE_LOADING),
7758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      gfx::Size(kIconSize, kIconSize));
7858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  SetIcon(image_);
7958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
8058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
8158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)PeopleResult::~PeopleResult() {
8258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
8358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
8458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void PeopleResult::Open(int event_flags) {
854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Action 0 will always be our default action.
8668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  InvokeAction(0, event_flags);
8758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
8858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
8958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void PeopleResult::InvokeAction(int action_index, int event_flags) {
908bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (hangouts_extension_id_.empty()) {
914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // If the hangouts app is not available, the only option we are showing
924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // to the user is 'Send Email'.
934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    SendEmail();
944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  } else {
954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    switch (action_index) {
964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      case 0:
974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        OpenChat();
984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        break;
994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      case 1:
1004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        SendEmail();
1014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        break;
1024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      default:
1034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        LOG(ERROR) << "Invalid people search action: " << action_index;
1044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    }
1054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
10658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
10758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
10858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)scoped_ptr<ChromeSearchResult> PeopleResult::Duplicate() {
1094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return scoped_ptr<ChromeSearchResult>(
1104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      new PeopleResult(profile_, person_->Duplicate().Pass())).Pass();
11158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
11258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
11358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void PeopleResult::OnIconLoaded() {
11458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Remove the existing image reps since the icon data is loaded and they
11558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // need to be re-created.
11658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  const std::vector<gfx::ImageSkiaRep>& image_reps = image_.image_reps();
11758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  for (size_t i = 0; i < image_reps.size(); ++i)
11868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    image_.RemoveRepresentation(image_reps[i].scale());
11958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
12058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  SetIcon(image_);
12158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
12258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
12368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void PeopleResult::SetDefaultActions() {
12468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  Actions actions;
12568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
12668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance();
1278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (!hangouts_extension_id_.empty()) {
1284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    actions.push_back(Action(
1294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        *bundle.GetImageSkiaNamed(IDR_PEOPLE_SEARCH_ACTION_CHAT),
1304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        *bundle.GetImageSkiaNamed(IDR_PEOPLE_SEARCH_ACTION_CHAT_HOVER),
1314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        *bundle.GetImageSkiaNamed(IDR_PEOPLE_SEARCH_ACTION_CHAT_PRESSED),
1324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        l10n_util::GetStringUTF16(IDS_PEOPLE_SEARCH_ACTION_CHAT_TOOLTIP)));
1334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
13468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  actions.push_back(Action(
13568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      *bundle.GetImageSkiaNamed(IDR_PEOPLE_SEARCH_ACTION_EMAIL),
13668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      *bundle.GetImageSkiaNamed(IDR_PEOPLE_SEARCH_ACTION_EMAIL_HOVER),
13768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      *bundle.GetImageSkiaNamed(IDR_PEOPLE_SEARCH_ACTION_EMAIL_PRESSED),
13868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      l10n_util::GetStringUTF16(IDS_PEOPLE_SEARCH_ACTION_EMAIL_TOOLTIP)));
13968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  SetActions(actions);
14068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
14168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
1424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void PeopleResult::OpenChat() {
1434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  HangoutRequest request;
1444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  request.type = extensions::api::hangouts_private::HANGOUT_TYPE_CHAT;
1464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // from: the user this chat request is originating from.
1484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ProfileOAuth2TokenService* token_service =
1494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ProfileOAuth2TokenServiceFactory::GetForProfile(profile_);
1504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(token_service);
1514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  request.from = token_service->GetPrimaryAccountId();
1524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // to: list of users with whom to start this hangout is with.
1544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  linked_ptr<User> target(new User());
1554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  target->id = person_->owner_id;
1564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  request.to.push_back(target);
1574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  scoped_ptr<extensions::Event> event(
1594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      new extensions::Event(OnHangoutRequested::kEventName,
1604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                            OnHangoutRequested::Create(request)));
1614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // TODO(rkc): Change this once we remove the hangoutsPrivate API.
1634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // See crbug.com/306672
1644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  extensions::ExtensionSystem::Get(
1654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      profile_)->event_router()->DispatchEventToExtension(
1668bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)          hangouts_extension_id_, event.Pass());
1674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
1684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
16968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void PeopleResult::SendEmail() {
17068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  chrome::NavigateParams params(profile_,
1714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                GURL(kEmailUrlPrefix + person_->email),
17268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                                content::PAGE_TRANSITION_LINK);
17368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // If no window exists, this will open a new window this one tab.
17468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  params.disposition = NEW_FOREGROUND_TAB;
17568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  chrome::Navigate(&params);
17668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
17768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
1788bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void PeopleResult::RefreshHangoutsExtensionId() {
1794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // TODO(rkc): Change this once we remove the hangoutsPrivate API.
1804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // See crbug.com/306672
1818bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  for (size_t i = 0; i < arraysize(kHangoutsExtensionIds); ++i) {
1828bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    if (extensions::ExtensionSystem::Get(
1838bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        profile_)->event_router()->ExtensionHasEventListener(
1848bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)            kHangoutsExtensionIds[i], OnHangoutRequested::kEventName)) {
1858bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      hangouts_extension_id_ = kHangoutsExtensionIds[i];
1868bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      return;
1878bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    }
1888bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
1898bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  hangouts_extension_id_.clear();
1904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
1914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
19258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)ChromeSearchResultType PeopleResult::GetType() {
19358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return SEARCH_PEOPLE_SEARCH_RESULT;
19458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
19558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
19658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}  // namespace app_list
197