app_list_service_impl.cc revision f2477e01787aa58f445919b809d89e252beef54f
1a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
2a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)// found in the LICENSE file.
4a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
5a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include "chrome/browser/ui/app_list/app_list_service_impl.h"
6a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
74e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include <string>
84e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
9ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "apps/pref_names.h"
10ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "base/command_line.h"
11a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include "base/metrics/histogram.h"
12a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include "base/prefs/pref_service.h"
134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/strings/string16.h"
14eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h"
150f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "chrome/browser/apps/shortcut_manager.h"
160f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "chrome/browser/apps/shortcut_manager_factory.h"
17a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include "chrome/browser/browser_process.h"
18a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include "chrome/browser/profiles/profile_manager.h"
194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/browser/ui/app_list/keep_alive_service.h"
204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/browser/ui/app_list/keep_alive_service_impl.h"
214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/browser/ui/app_list/profile_loader.h"
224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/browser/ui/app_list/profile_store.h"
23a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include "chrome/common/chrome_constants.h"
24ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "chrome/common/chrome_switches.h"
25a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include "chrome/common/pref_names.h"
26a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include "content/public/browser/browser_thread.h"
27a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
28a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)namespace {
29a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
30a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void SendAppListAppLaunch(int count) {
31a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  UMA_HISTOGRAM_CUSTOM_COUNTS(
32a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      "Apps.AppListDailyAppLaunches", count, 1, 1000, 50);
33a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  if (count > 0)
34a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    UMA_HISTOGRAM_ENUMERATION("Apps.AppListHasLaunchedAppToday", 1, 2);
35a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
36a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
37a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void SendAppListLaunch(int count) {
38a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  UMA_HISTOGRAM_CUSTOM_COUNTS(
39a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      "Apps.AppListDailyLaunches", count, 1, 1000, 50);
40a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  if (count > 0)
41a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    UMA_HISTOGRAM_ENUMERATION("Apps.AppListHasLaunchedAppListToday", 1, 2);
42a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
43a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
44a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)bool SendDailyEventFrequency(
45a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    const char* last_ping_pref,
46a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    const char* count_pref,
47a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    void (*send_callback)(int count)) {
48a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  PrefService* local_state = g_browser_process->local_state();
49a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
50a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  base::Time now = base::Time::Now();
51a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  base::Time last = base::Time::FromInternalValue(local_state->GetInt64(
52a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      last_ping_pref));
53a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  int days = (now - last).InDays();
54a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  if (days > 0) {
55a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    send_callback(local_state->GetInteger(count_pref));
56a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    local_state->SetInt64(
57a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        last_ping_pref,
58a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        (last + base::TimeDelta::FromDays(days)).ToInternalValue());
59a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    local_state->SetInteger(count_pref, 0);
60a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    return true;
61a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  }
62a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  return false;
63a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
64a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
65a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void RecordDailyEventFrequency(
66a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    const char* last_ping_pref,
67a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    const char* count_pref,
68a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    void (*send_callback)(int count)) {
69a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  PrefService* local_state = g_browser_process->local_state();
70a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
71a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  int count = local_state->GetInteger(count_pref);
72a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  local_state->SetInteger(count_pref, count + 1);
73a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  if (SendDailyEventFrequency(last_ping_pref, count_pref, send_callback)) {
74a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    local_state->SetInteger(count_pref, 1);
75a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  }
76a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
77a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)class ProfileStoreImpl : public ProfileStore {
794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) public:
804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  explicit ProfileStoreImpl(ProfileManager* profile_manager)
814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      : profile_manager_(profile_manager),
824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        weak_factory_(this) {
834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
84ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual void AddProfileObserver(ProfileInfoCacheObserver* observer) OVERRIDE {
864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    profile_manager_->GetProfileInfoCache().AddObserver(observer);
874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual void LoadProfileAsync(
904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      const base::FilePath& path,
914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      base::Callback<void(Profile*)> callback) OVERRIDE {
924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    profile_manager_->CreateProfileAsync(
934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        path,
944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        base::Bind(&ProfileStoreImpl::OnProfileCreated,
954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                   weak_factory_.GetWeakPtr(),
964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                   callback),
974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        base::string16(),
984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        base::string16(),
994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        std::string());
1004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
1014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  void OnProfileCreated(base::Callback<void(Profile*)> callback,
1034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                        Profile* profile,
1044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                        Profile::CreateStatus status) {
1054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    switch (status) {
1064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      case Profile::CREATE_STATUS_CREATED:
1074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        break;
1084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      case Profile::CREATE_STATUS_INITIALIZED:
1094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        callback.Run(profile);
1104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        break;
1114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      case Profile::CREATE_STATUS_LOCAL_FAIL:
1124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      case Profile::CREATE_STATUS_REMOTE_FAIL:
1134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      case Profile::CREATE_STATUS_CANCELED:
1144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        break;
1154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      case Profile::MAX_CREATE_STATUS:
1164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        NOTREACHED();
1174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        break;
1184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    }
1194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
1204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual Profile* GetProfileByPath(const base::FilePath& path) OVERRIDE {
1224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return profile_manager_->GetProfileByPath(path);
1234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
1244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual base::FilePath GetUserDataDir() OVERRIDE {
1264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return profile_manager_->user_data_dir();
1274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
1284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual bool IsProfileManaged(const base::FilePath& profile_path) OVERRIDE {
1304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    ProfileInfoCache& profile_info =
1314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        g_browser_process->profile_manager()->GetProfileInfoCache();
1324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    size_t profile_index = profile_info.GetIndexOfProfileWithPath(profile_path);
1334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return profile_info.ProfileIsManagedAtIndex(profile_index);
1344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
1354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) private:
1374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ProfileManager* profile_manager_;
1384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  base::WeakPtrFactory<ProfileStoreImpl> weak_factory_;
1394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)};
140ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
141a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}  // namespace
142a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
143a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)// static
144a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void AppListServiceImpl::RecordAppListLaunch() {
145a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  RecordDailyEventFrequency(prefs::kLastAppListLaunchPing,
146a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                            prefs::kAppListLaunchCount,
147a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                            &SendAppListLaunch);
148a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
149a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
150a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)// static
151a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void AppListServiceImpl::RecordAppListAppLaunch() {
152a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  RecordDailyEventFrequency(prefs::kLastAppListAppLaunchPing,
153a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                            prefs::kAppListAppLaunchCount,
154a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                            &SendAppListAppLaunch);
155a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
156a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
157a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)// static
158a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void AppListServiceImpl::SendAppListStats() {
159a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  if (!g_browser_process || g_browser_process->IsShuttingDown())
160a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    return;
161a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
162a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  SendDailyEventFrequency(prefs::kLastAppListLaunchPing,
163a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                          prefs::kAppListLaunchCount,
164a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                          &SendAppListLaunch);
165a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  SendDailyEventFrequency(prefs::kLastAppListAppLaunchPing,
166a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                          prefs::kAppListAppLaunchCount,
167a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                          &SendAppListAppLaunch);
168a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
169a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
170a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)AppListServiceImpl::AppListServiceImpl()
1711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    : profile_store_(new ProfileStoreImpl(
1724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          g_browser_process->profile_manager())),
17390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      weak_factory_(this),
1744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      command_line_(*CommandLine::ForCurrentProcess()),
1754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      local_state_(g_browser_process->local_state()),
1764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      profile_loader_(new ProfileLoader(
1774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          profile_store_.get(),
1784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          scoped_ptr<KeepAliveService>(new KeepAliveServiceImpl))) {
1794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  profile_store_->AddProfileObserver(this);
1804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
1814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)AppListServiceImpl::AppListServiceImpl(
1834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    const CommandLine& command_line,
1844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    PrefService* local_state,
1854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    scoped_ptr<ProfileStore> profile_store,
1864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    scoped_ptr<KeepAliveService> keep_alive_service)
1871e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    : profile_store_(profile_store.Pass()),
1884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      weak_factory_(this),
1894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      command_line_(command_line),
1904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      local_state_(local_state),
1914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      profile_loader_(new ProfileLoader(
1924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          profile_store_.get(), keep_alive_service.Pass())) {
1934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  profile_store_->AddProfileObserver(this);
194a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
195a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
196a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)AppListServiceImpl::~AppListServiceImpl() {}
197a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
198f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void AppListServiceImpl::SetAppListNextPaintCallback(void (*callback)()) {}
1993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
200ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid AppListServiceImpl::HandleFirstRun() {}
201ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
202a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void AppListServiceImpl::Init(Profile* initial_profile) {}
203a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
20490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)base::FilePath AppListServiceImpl::GetProfilePath(
205a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    const base::FilePath& user_data_dir) {
206a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  std::string app_list_profile;
2074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (local_state_->HasPrefPath(prefs::kAppListProfile))
2084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    app_list_profile = local_state_->GetString(prefs::kAppListProfile);
209a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
210a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  // If the user has no profile preference for the app launcher, default to the
211a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  // last browser profile used.
212a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  if (app_list_profile.empty() &&
2134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      local_state_->HasPrefPath(prefs::kProfileLastUsed)) {
2144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    app_list_profile = local_state_->GetString(prefs::kProfileLastUsed);
215ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  }
216ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
217ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // If there is no last used profile recorded, use the initial profile.
218ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (app_list_profile.empty())
219ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    app_list_profile = chrome::kInitialProfile;
220a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
221ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  return user_data_dir.AppendASCII(app_list_profile);
222ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch}
223a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
224ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid AppListServiceImpl::SetProfilePath(const base::FilePath& profile_path) {
22568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // Ensure we don't set the pref to a managed user's profile path.
2264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // TODO(calamity): Filter out managed profiles from the settings app so this
2274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // can't get hit, so we can remove it.
2284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (profile_store_->IsProfileManaged(profile_path))
22968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    return;
23068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
2314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  local_state_->SetString(
232ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      prefs::kAppListProfile,
233ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      profile_path.BaseName().MaybeAsASCII());
234a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
235a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
236ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid AppListServiceImpl::CreateShortcut() {}
237a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
238a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)// We need to watch for profile removal to keep kAppListProfile updated.
239a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void AppListServiceImpl::OnProfileWillBeRemoved(
240a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    const base::FilePath& profile_path) {
241a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  // If the profile the app list uses just got deleted, reset it to the last
242a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  // used profile.
2434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::string app_list_last_profile = local_state_->GetString(
244a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      prefs::kAppListProfile);
245a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  if (profile_path.BaseName().MaybeAsASCII() == app_list_last_profile) {
2464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    local_state_->SetString(prefs::kAppListProfile,
2474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        local_state_->GetString(prefs::kProfileLastUsed));
248a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  }
249a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
250a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
251ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid AppListServiceImpl::Show() {
2524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  profile_loader_->LoadProfileInvalidatingOtherLoads(
2534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      GetProfilePath(profile_store_->GetUserDataDir()),
254ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      base::Bind(&AppListServiceImpl::ShowForProfile,
255ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                 weak_factory_.GetWeakPtr()));
256a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
257a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
258ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid AppListServiceImpl::EnableAppList(Profile* initial_profile) {
259ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  SetProfilePath(initial_profile->GetPath());
2604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (local_state_->GetBoolean(prefs::kAppLauncherHasBeenEnabled))
261ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    return;
262ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
2634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  local_state_->SetBoolean(prefs::kAppLauncherHasBeenEnabled, true);
264ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  CreateShortcut();
265f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  AppShortcutManager* shortcut_manager =
266f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      AppShortcutManagerFactory::GetForProfile(initial_profile);
267f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (shortcut_manager)
268f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    shortcut_manager->OnceOffCreateShortcuts();
269a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
270a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
271a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void AppListServiceImpl::InvalidatePendingProfileLoads() {
2724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  profile_loader_->InvalidatePendingProfileLoads();
273a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
274a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
275ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid AppListServiceImpl::HandleCommandLineFlags(Profile* initial_profile) {
2764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (command_line_.HasSwitch(switches::kEnableAppList))
277ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    EnableAppList(initial_profile);
278ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
2798bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (command_line_.HasSwitch(switches::kResetAppListInstallState))
2804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    local_state_->SetBoolean(prefs::kAppLauncherHasBeenEnabled, false);
2814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
28268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
2834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void AppListServiceImpl::SendUsageStats() {
28468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // Send app list usage stats after a delay.
28568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  const int kSendUsageStatsDelay = 5;
28668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  base::MessageLoop::current()->PostDelayedTask(
28768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      FROM_HERE,
28868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      base::Bind(&AppListServiceImpl::SendAppListStats),
28968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      base::TimeDelta::FromSeconds(kSendUsageStatsDelay));
290a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
291