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/webui/ntp/core_app_launcher_handler.h"
6
7#include "base/bind.h"
8#include "base/metrics/histogram.h"
9#include "chrome/browser/profiles/profile.h"
10#include "chrome/browser/ui/webui/ntp/app_launcher_handler.h"
11#include "chrome/common/pref_names.h"
12#include "components/pref_registry/pref_registry_syncable.h"
13#include "content/public/browser/web_ui.h"
14#include "extensions/browser/extension_registry.h"
15#include "extensions/common/extension.h"
16#include "extensions/common/extension_set.h"
17#include "net/base/escape.h"
18
19namespace {
20const net::UnescapeRule::Type kUnescapeRules =
21    net::UnescapeRule::NORMAL | net::UnescapeRule::URL_SPECIAL_CHARS;
22}
23
24CoreAppLauncherHandler::CoreAppLauncherHandler() {}
25
26CoreAppLauncherHandler::~CoreAppLauncherHandler() {}
27
28// static
29void CoreAppLauncherHandler::RecordAppLaunchType(
30    extension_misc::AppLaunchBucket bucket,
31    extensions::Manifest::Type app_type) {
32  DCHECK_LT(bucket, extension_misc::APP_LAUNCH_BUCKET_BOUNDARY);
33  if (app_type == extensions::Manifest::TYPE_PLATFORM_APP) {
34    UMA_HISTOGRAM_ENUMERATION(extension_misc::kPlatformAppLaunchHistogram,
35                              bucket,
36                              extension_misc::APP_LAUNCH_BUCKET_BOUNDARY);
37  } else {
38    UMA_HISTOGRAM_ENUMERATION(extension_misc::kAppLaunchHistogram,
39                              bucket,
40                              extension_misc::APP_LAUNCH_BUCKET_BOUNDARY);
41  }
42}
43
44// static
45void CoreAppLauncherHandler::RecordAppListSearchLaunch(
46    const extensions::Extension* extension) {
47  extension_misc::AppLaunchBucket bucket =
48      extension_misc::APP_LAUNCH_APP_LIST_SEARCH;
49  if (extension->id() == extension_misc::kWebStoreAppId)
50    bucket = extension_misc::APP_LAUNCH_APP_LIST_SEARCH_WEBSTORE;
51  else if (extension->id() == extension_misc::kChromeAppId)
52    bucket = extension_misc::APP_LAUNCH_APP_LIST_SEARCH_CHROME;
53  RecordAppLaunchType(bucket, extension->GetType());
54}
55
56// static
57void CoreAppLauncherHandler::RecordAppListMainLaunch(
58    const extensions::Extension* extension) {
59  extension_misc::AppLaunchBucket bucket =
60      extension_misc::APP_LAUNCH_APP_LIST_MAIN;
61  if (extension->id() == extension_misc::kWebStoreAppId)
62    bucket = extension_misc::APP_LAUNCH_APP_LIST_MAIN_WEBSTORE;
63  else if (extension->id() == extension_misc::kChromeAppId)
64    bucket = extension_misc::APP_LAUNCH_APP_LIST_MAIN_CHROME;
65  RecordAppLaunchType(bucket, extension->GetType());
66}
67
68// static
69void CoreAppLauncherHandler::RecordWebStoreLaunch() {
70  RecordAppLaunchType(extension_misc::APP_LAUNCH_NTP_WEBSTORE,
71                      extensions::Manifest::TYPE_HOSTED_APP);
72}
73
74// static
75void CoreAppLauncherHandler::RegisterProfilePrefs(
76    user_prefs::PrefRegistrySyncable* registry) {
77  registry->RegisterListPref(prefs::kNtpAppPageNames,
78                             user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
79}
80
81void CoreAppLauncherHandler::HandleRecordAppLaunchByUrl(
82    const base::ListValue* args) {
83  std::string url;
84  CHECK(args->GetString(0, &url));
85  double source;
86  CHECK(args->GetDouble(1, &source));
87
88  extension_misc::AppLaunchBucket bucket =
89      static_cast<extension_misc::AppLaunchBucket>(static_cast<int>(source));
90  CHECK(source < extension_misc::APP_LAUNCH_BUCKET_BOUNDARY);
91
92  RecordAppLaunchByUrl(Profile::FromWebUI(web_ui()), url, bucket);
93}
94
95void CoreAppLauncherHandler::RecordAppLaunchByUrl(
96    Profile* profile,
97    std::string escaped_url,
98    extension_misc::AppLaunchBucket bucket) {
99  CHECK(bucket != extension_misc::APP_LAUNCH_BUCKET_INVALID);
100
101  GURL url(net::UnescapeURLComponent(escaped_url, kUnescapeRules));
102  if (!extensions::ExtensionRegistry::Get(profile)
103          ->enabled_extensions().GetAppByURL(url)) {
104    return;
105  }
106
107  RecordAppLaunchType(bucket, extensions::Manifest::TYPE_HOSTED_APP);
108}
109
110void CoreAppLauncherHandler::RegisterMessages() {
111  web_ui()->RegisterMessageCallback("recordAppLaunchByURL",
112      base::Bind(&CoreAppLauncherHandler::HandleRecordAppLaunchByUrl,
113                 base::Unretained(this)));
114}
115