190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// found in the LICENSE file.
490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/ui/app_list/search/app_result.h"
690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/extensions/extension_service.h"
890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/extensions/extension_system_factory.h"
93d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch#include "chrome/browser/extensions/install_tracker.h"
103d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch#include "chrome/browser/extensions/install_tracker_factory.h"
1190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/profiles/profile.h"
1290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/ui/app_list/app_context_menu.h"
1390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/ui/app_list/app_list_controller_delegate.h"
1490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/ui/app_list/search/tokenized_string.h"
1590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/ui/app_list/search/tokenized_string_match.h"
16a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "chrome/browser/ui/webui/ntp/core_app_launcher_handler.h"
1790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/common/extensions/extension.h"
1890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/common/extensions/extension_icon_set.h"
1990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/common/extensions/manifest_handlers/icons_handler.h"
2090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "content/public/browser/user_metrics.h"
2190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
2290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)namespace app_list {
2390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
2490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)AppResult::AppResult(Profile* profile,
2590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                     const std::string& app_id,
2690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                     AppListControllerDelegate* controller)
2790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    : profile_(profile),
2890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      app_id_(app_id),
293d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch      controller_(controller),
303d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch      install_tracker_(NULL) {
3190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  set_id(extensions::Extension::GetBaseURLFromExtensionId(app_id_).spec());
3290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
3390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  const extensions::Extension* extension =
3490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      extensions::ExtensionSystem::Get(profile_)->extension_service()
3590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          ->GetInstalledExtension(app_id_);
3690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DCHECK(extension);
3790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
3890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  is_platform_app_ = extension->is_platform_app();
3990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
4090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  icon_.reset(new extensions::IconImage(
4190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      profile_,
4290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      extension,
4390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      extensions::IconsInfo::GetIcons(extension),
4490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      extension_misc::EXTENSION_ICON_SMALL,
4590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      extensions::IconsInfo::GetDefaultAppIcon(),
4690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      this));
4790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  SetIcon(icon_->image_skia());
483d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch  StartObservingInstall();
493d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch}
503d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch
513d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben MurdochAppResult::~AppResult() {
523d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch  StopObservingInstall();
5390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
5490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
5590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void AppResult::UpdateFromMatch(const TokenizedString& title,
5690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                const TokenizedStringMatch& match) {
5790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  const TokenizedStringMatch::Hits& hits = match.hits();
5890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
5990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  Tags tags;
6090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  tags.reserve(hits.size());
6190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  for (size_t i = 0; i < hits.size(); ++i)
6290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    tags.push_back(Tag(Tag::MATCH, hits[i].start(), hits[i].end()));
6390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
6490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  set_title(title.text());
6590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  set_title_tags(tags);
6690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  set_relevance(match.relevance());
6790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
6890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
6990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void AppResult::Open(int event_flags) {
7090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  const extensions::Extension* extension =
7190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      extensions::ExtensionSystem::Get(profile_)->extension_service()
7290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          ->GetInstalledExtension(app_id_);
7390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (!extension)
7490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return;
7590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
76a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  CoreAppLauncherHandler::RecordAppListSearchLaunch(extension);
7790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  content::RecordAction(
7890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      content::UserMetricsAction("AppList_ClickOnAppFromSearch"));
7990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
8090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  controller_->ActivateApp(profile_, extension, event_flags);
8190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
8290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
8390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void AppResult::InvokeAction(int action_index, int event_flags) {}
8490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
8590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)scoped_ptr<ChromeSearchResult> AppResult::Duplicate() {
8690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<ChromeSearchResult> copy(
8790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      new AppResult(profile_, app_id_, controller_));
8890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  copy->set_title(title());
8990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  copy->set_title_tags(title_tags());
9090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
9190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  return copy.Pass();
9290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
9390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
94eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochChromeSearchResultType AppResult::GetType() {
95eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return APP_SEARCH_RESULT;
96eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
97eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
9890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)ui::MenuModel* AppResult::GetContextMenuModel() {
9990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (!context_menu_) {
10090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    context_menu_.reset(new AppContextMenu(
10190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        this, profile_, app_id_, controller_, is_platform_app_));
10290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
10390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
10490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  return context_menu_->GetMenuModel();
10590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
10690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
1073d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdochvoid AppResult::StartObservingInstall() {
1083d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch  DCHECK(!install_tracker_);
1093d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch
1103d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch  install_tracker_ = extensions::InstallTrackerFactory::GetForProfile(profile_);
1113d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch  install_tracker_->AddObserver(this);
1123d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch}
1133d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch
1143d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdochvoid AppResult::StopObservingInstall() {
1153d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch  if (install_tracker_)
1163d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch    install_tracker_->RemoveObserver(this);
1173d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch
1183d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch  install_tracker_ = NULL;
1193d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch}
1203d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch
1213d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdochvoid AppResult::OnExtensionIconImageChanged(extensions::IconImage* image) {
12290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DCHECK_EQ(icon_.get(), image);
12390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  SetIcon(icon_->image_skia());
12490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
12590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
12690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void AppResult::ExecuteLaunchCommand(int event_flags) {
12790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  Open(event_flags);
12890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
12990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
1303d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdochvoid AppResult::OnBeginExtensionInstall(const std::string& extension_id,
1313d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch                                        const std::string& extension_name,
1323d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch                                        const gfx::ImageSkia& installing_icon,
1333d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch                                        bool is_app,
1343d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch                                        bool is_platform_app) {}
1353d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch
1363d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdochvoid AppResult::OnDownloadProgress(const std::string& extension_id,
1373d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch                                   int percent_downloaded) {}
1383d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch
1393d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdochvoid AppResult::OnInstallFailure(const std::string& extension_id) {}
1403d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch
1413d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdochvoid AppResult::OnExtensionInstalled(const extensions::Extension* extension) {}
1423d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch
1433d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdochvoid AppResult::OnExtensionLoaded(const extensions::Extension* extension) {}
1443d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch
1453d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdochvoid AppResult::OnExtensionUnloaded(const extensions::Extension* extension) {}
1463d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch
1473d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdochvoid AppResult::OnExtensionUninstalled(const extensions::Extension* extension) {
1483d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch  if (extension->id() != app_id_)
1493d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch    return;
1503d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch
1513d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch  NotifyItemUninstalled();
1523d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch}
1533d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch
1543d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdochvoid AppResult::OnAppsReordered() {}
1553d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch
1563d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdochvoid AppResult::OnAppInstalledToAppList(const std::string& extension_id) {}
1573d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch
1583d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdochvoid AppResult::OnShutdown() { StopObservingInstall(); }
1593d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch
16090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}  // namespace app_list
161